Compare commits
17 Commits
main
...
refactor-c
| Author | SHA1 | Date |
|---|---|---|
|
|
3e39a9ff79 | |
|
|
c304ebb54f | |
|
|
3a6cc6aa09 | |
|
|
616478be1f | |
|
|
e08c6da9b5 | |
|
|
d46762c1d6 | |
|
|
646fad2eda | |
|
|
6980c8e9f2 | |
|
|
4e8a16f2bb | |
|
|
314461848c | |
|
|
6982052e74 | |
|
|
63c5df9e73 | |
|
|
bb91ce7592 | |
|
|
ca17b5a928 | |
|
|
d027f286e3 | |
|
|
1c508d61fb | |
|
|
54cdc3ff40 |
|
|
@ -1,7 +1,7 @@
|
|||
import type { FunctionalComponent } from 'vue';
|
||||
import type { OptionGroupData } from '../vc-select/interface';
|
||||
import type { DefaultOptionType } from '../select';
|
||||
|
||||
export type OptGroupProps = Omit<OptionGroupData, 'options'>;
|
||||
export type OptGroupProps = Omit<DefaultOptionType, 'options'>;
|
||||
|
||||
export interface OptionGroupFC extends FunctionalComponent<OptGroupProps> {
|
||||
/** Legacy for check if is a Option Group */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { FunctionalComponent } from 'vue';
|
||||
import type { OptionCoreData } from '../vc-select/interface';
|
||||
import type { DefaultOptionType } from '../vc-select/Select';
|
||||
|
||||
export interface OptionProps extends Omit<OptionCoreData, 'label'> {
|
||||
export interface OptionProps extends Omit<DefaultOptionType, 'label'> {
|
||||
/** Save for customize data */
|
||||
[prop: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ function YearSelect<DateType>(props: SharedProps<DateType>) {
|
|||
options={options}
|
||||
value={year}
|
||||
class={`${prefixCls}-year-select`}
|
||||
onChange={numYear => {
|
||||
onChange={(numYear: number) => {
|
||||
let newDate = generateConfig.setYear(value, numYear);
|
||||
|
||||
if (validRange) {
|
||||
|
|
@ -108,7 +108,7 @@ function MonthSelect<DateType>(props: SharedProps<DateType>) {
|
|||
class={`${prefixCls}-month-select`}
|
||||
value={month}
|
||||
options={options}
|
||||
onChange={newMonth => {
|
||||
onChange={(newMonth: number) => {
|
||||
onChange(generateConfig.setMonth(value, newMonth));
|
||||
}}
|
||||
getPopupContainer={() => divRef!.value!}
|
||||
|
|
|
|||
|
|
@ -1,62 +1,159 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/cascader/demo/basic.vue correctly 1`] = `
|
||||
<span class="ant-cascader-picker" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/change-on-select.vue correctly 1`] = `
|
||||
<span class="ant-cascader-picker" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/custom-render.vue correctly 1`] = `<span class="ant-cascader-picker" style="width: 100%;" tabindex="0"><span class="ant-cascader-picker-label"><span><span>Zhejiang /</span></span><span><span>Hangzhou /</span></span><span><span>West Lake ( <a>752100</a> ) </span></span></span><input autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input"><span tabindex="-1" role="img" aria-label="close-circle" class="anticon anticon-close-circle ant-cascader-picker-clear"><svg focusable="false" class="" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg></span><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>`;
|
||||
exports[`renders ./components/cascader/demo/custom-render.vue correctly 1`] = `
|
||||
<div style="width: 100%;" class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span><span class="ant-select-selection-item"><span><span>Zhejiang /</span></span><span><span>Hangzhou /</span></span><span><span>West Lake ( <a>752100</a> ) </span></span></span>
|
||||
<!---->
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span><span class="ant-select-clear" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close-circle" class="anticon anticon-close-circle"><svg focusable="false" class="" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg></span></span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/custom-trigger.vue correctly 1`] = `<span>Unselect <!----><a href="#" tabindex="0">Change city</a></span>`;
|
||||
exports[`renders ./components/cascader/demo/custom-trigger.vue correctly 1`] = `<span>Unselect <!----><a href="#">Change city</a></span>`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/disabled-option.vue correctly 1`] = `
|
||||
<span class="ant-cascader-picker" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/fields-name.vue correctly 1`] = `
|
||||
<span class="ant-cascader-picker" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/hover.vue correctly 1`] = `
|
||||
<span class="ant-cascader-picker" tabindex="0"><span class="ant-cascader-picker-label"><!----></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/lazy.vue correctly 1`] = `
|
||||
<span class="ant-cascader-picker" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/multiple.vue correctly 1`] = `
|
||||
<div style="width: 233px;" class="ant-select ant-cascader ant-select-multiple ant-select-allow-clear">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
<div class="ant-select-selection-overflow">
|
||||
<!---->
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
</div>
|
||||
</div><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/search.vue correctly 1`] = `
|
||||
<span class="ant-cascader-picker ant-cascader-picker-show-search" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/size.vue correctly 1`] = `
|
||||
<span class="ant-cascader-picker ant-cascader-picker-large" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input ant-input-lg">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div size="large" class="ant-select ant-cascader ant-select-lg ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
<span class="ant-cascader-picker" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
<span class="ant-cascader-picker ant-cascader-picker-small" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input ant-input-sm">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div size="small" class="ant-select ant-cascader ant-select-sm ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/cascader/demo/suffix.vue correctly 1`] = `
|
||||
<span class="ant-cascader-picker" style="margin-top: 1rem;" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="smile" class="anticon anticon-smile ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"></path></svg></span></span>
|
||||
<span class="ant-cascader-picker" style="margin-top: 1rem;" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" readonly="" suffixicon="ab" class="ant-input ant-cascader-input">
|
||||
<!----><span class="ant-cascader-picker-arrow">ab</span></span>
|
||||
<div style="margin-top: 1rem;" class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="smile" class="anticon anticon-smile test"><svg focusable="false" class="" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
<div suffixicon="ab" style="margin-top: 1rem;" class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true">ab</span>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,116 +1,160 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Cascader can be selected 1`] = `
|
||||
<div>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" title="Zhejiang" role="menuitem">Zhejiang<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" title="Jiangsu" role="menuitem">Jiangsu<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" title="Hangzhou" role="menuitem">Hangzhou<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" role="menuitemcheckbox" title="Zhejiang" aria-checked="false" data-path-key="zhejiang">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Zhejiang</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" role="menuitemcheckbox" title="Jiangsu" aria-checked="false" data-path-key="jiangsu">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Jiangsu</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" role="menuitemcheckbox" title="Hangzhou" aria-checked="false" data-path-key="zhejiang__RC_CASCADER_SPLIT__hangzhou">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Hangzhou</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
|
||||
exports[`Cascader can be selected 2`] = `
|
||||
<div>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" title="Zhejiang" role="menuitem">Zhejiang<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" title="Jiangsu" role="menuitem">Jiangsu<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" title="Hangzhou" role="menuitem">Hangzhou<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item" title="West Lake" role="menuitem">West Lake
|
||||
<!---->
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" role="menuitemcheckbox" title="Zhejiang" aria-checked="false" data-path-key="zhejiang">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Zhejiang</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" role="menuitemcheckbox" title="Jiangsu" aria-checked="false" data-path-key="jiangsu">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Jiangsu</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" role="menuitemcheckbox" title="Hangzhou" aria-checked="false" data-path-key="zhejiang__RC_CASCADER_SPLIT__hangzhou">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Hangzhou</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item" role="menuitemcheckbox" title="West Lake" aria-checked="false" data-path-key="zhejiang__RC_CASCADER_SPLIT__hangzhou__RC_CASCADER_SPLIT__xihu">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">West Lake</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
|
||||
exports[`Cascader can be selected 3`] = `
|
||||
<div>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" title="Zhejiang" role="menuitem">Zhejiang<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" title="Jiangsu" role="menuitem">Jiangsu<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" title="Hangzhou" role="menuitem">Hangzhou<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-active" title="West Lake" role="menuitem">West Lake
|
||||
<!---->
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" role="menuitemcheckbox" title="Zhejiang" aria-checked="true" data-path-key="zhejiang">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Zhejiang</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" role="menuitemcheckbox" title="Jiangsu" aria-checked="false" data-path-key="jiangsu">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Jiangsu</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" role="menuitemcheckbox" title="Hangzhou" aria-checked="true" data-path-key="zhejiang__RC_CASCADER_SPLIT__hangzhou">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Hangzhou</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-active" role="menuitemcheckbox" title="West Lake" aria-checked="true" data-path-key="zhejiang__RC_CASCADER_SPLIT__hangzhou__RC_CASCADER_SPLIT__xihu">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">West Lake</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
`;
|
||||
|
||||
exports[`Cascader popup correctly when panel is open 1`] = `
|
||||
<div>
|
||||
<!---->
|
||||
<div class="ant-cascader-menus" style="pointer-events: none;">
|
||||
<div>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" title="Zhejiang" role="menuitem">Zhejiang<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" title="Jiangsu" role="menuitem">Jiangsu<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ant-cascader-menus">
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" role="menuitemcheckbox" title="Zhejiang" aria-checked="false" data-path-key="zhejiang">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Zhejiang</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" role="menuitemcheckbox" title="Jiangsu" aria-checked="false" data-path-key="jiangsu">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Jiangsu</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Cascader popup correctly with defaultValue 1`] = `
|
||||
<div>
|
||||
<!---->
|
||||
<div class="ant-cascader-menus ant-slide-up-enter-from ant-slide-up-enter-active" style="pointer-events: none; opacity: 0;">
|
||||
<div>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" title="Zhejiang" role="menuitem">Zhejiang<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" title="Jiangsu" role="menuitem">Jiangsu<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" title="Hangzhou" role="menuitem">Hangzhou<span class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu">
|
||||
<li class="ant-cascader-menu-item" title="West Lake" role="menuitem">West Lake
|
||||
<!---->
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ant-cascader-menus">
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" role="menuitemcheckbox" title="Zhejiang" aria-checked="true" data-path-key="zhejiang">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Zhejiang</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand" role="menuitemcheckbox" title="Jiangsu" aria-checked="false" data-path-key="jiangsu">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Jiangsu</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item ant-cascader-menu-item-expand ant-cascader-menu-item-active" role="menuitemcheckbox" title="Hangzhou" aria-checked="true" data-path-key="zhejiang__RC_CASCADER_SPLIT__hangzhou">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">Hangzhou</div>
|
||||
<div class="ant-cascader-menu-item-expand-icon"><span role="img" aria-label="right" class="anticon anticon-right"><svg focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"></path></svg></span></div>
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="ant-cascader-menu" role="menu">
|
||||
<li class="ant-cascader-menu-item" role="menuitemcheckbox" title="West Lake" aria-checked="true" data-path-key="zhejiang__RC_CASCADER_SPLIT__hangzhou__RC_CASCADER_SPLIT__xihu">
|
||||
<!---->
|
||||
<div class="ant-cascader-menu-item-content">West Lake</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Cascader support controlled mode 1`] = `<span class="ant-cascader-picker" tabindex="0"><span class="ant-cascader-picker-label">Zhejiang / Hangzhou / West Lake</span><input autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input"><span tabindex="-1" role="img" aria-label="close-circle" class="anticon anticon-close-circle ant-cascader-picker-clear"><svg focusable="false" class="" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg></span><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>`;
|
||||
exports[`Cascader support controlled mode 1`] = `
|
||||
<div class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span><span class="ant-select-selection-item" title="Zhejiang">Zhejiang</span>
|
||||
<!---->
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span><span class="ant-select-clear" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close-circle" class="anticon anticon-close-circle"><svg focusable="false" class="" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg></span></span>
|
||||
</div>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,14 @@ function filter(inputValue, path) {
|
|||
return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
|
||||
}
|
||||
|
||||
function toggleOpen(wrapper) {
|
||||
wrapper.find('.ant-select-selector').trigger('mousedown');
|
||||
}
|
||||
|
||||
function isOpen(wrapper) {
|
||||
return !!wrapper.findComponent({ name: 'Trigger' }).props().popupVisible;
|
||||
}
|
||||
|
||||
describe('Cascader', () => {
|
||||
focusTest(Cascader);
|
||||
beforeEach(() => {
|
||||
|
|
@ -65,7 +73,7 @@ describe('Cascader', () => {
|
|||
it('popup correctly when panel is open', async () => {
|
||||
const wrapper = mount(Cascader, { props: { options }, sync: false, attachTo: 'body' });
|
||||
await asyncExpect(() => {
|
||||
wrapper.find('input').trigger('click');
|
||||
toggleOpen(wrapper);
|
||||
});
|
||||
expect($$('.ant-cascader-menus').length).toBe(1);
|
||||
await asyncExpect(() => {
|
||||
|
|
@ -95,7 +103,7 @@ describe('Cascader', () => {
|
|||
});
|
||||
|
||||
await asyncExpect(() => {
|
||||
wrapper.find('input').trigger('click');
|
||||
toggleOpen(wrapper);
|
||||
});
|
||||
expect($$('.ant-cascader-menus').length).toBe(1);
|
||||
await asyncExpect(() => {
|
||||
|
|
@ -106,9 +114,8 @@ describe('Cascader', () => {
|
|||
it('can be selected', async () => {
|
||||
const wrapper = mount(Cascader, { props: { options }, sync: false });
|
||||
await asyncExpect(() => {
|
||||
wrapper.find('input').trigger('click');
|
||||
toggleOpen(wrapper);
|
||||
});
|
||||
|
||||
await asyncExpect(() => {
|
||||
$$('.ant-cascader-menu')[0].querySelectorAll('.ant-cascader-menu-item')[0].click();
|
||||
});
|
||||
|
|
@ -134,23 +141,36 @@ describe('Cascader', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('backspace should work with `Cascader[showSearch]`', async () => {
|
||||
fit('backspace should work with `Cascader[showSearch]`', async () => {
|
||||
const wrapper = mount(Cascader, { props: { options, showSearch: true }, sync: false });
|
||||
await asyncExpect(() => {
|
||||
wrapper.find('input').element.value = '123';
|
||||
wrapper.find('input').trigger('input');
|
||||
});
|
||||
await asyncExpect(() => {
|
||||
expect(wrapper.vm.inputValue).toBe('123');
|
||||
expect(isOpen(wrapper)).toBeTruthy();
|
||||
});
|
||||
await asyncExpect(() => {
|
||||
wrapper.find('input').element.keyCode = KeyCode.BACKSPACE;
|
||||
wrapper.find('input').trigger('keydown');
|
||||
});
|
||||
await asyncExpect(() => {
|
||||
// trigger onKeyDown will not trigger onChange by default, so the value is still '123'
|
||||
expect(wrapper.vm.inputValue).toBe('123');
|
||||
expect(isOpen(wrapper)).toBeTruthy();
|
||||
});
|
||||
await asyncExpect(() => {
|
||||
wrapper.find('input').element.value = '';
|
||||
wrapper.find('input').trigger('input');
|
||||
});
|
||||
await asyncExpect(() => {
|
||||
expect(isOpen(wrapper)).toBeTruthy();
|
||||
});
|
||||
// await asyncExpect(() => {
|
||||
// wrapper.find('input').element.keyCode = KeyCode.BACKSPACE;
|
||||
// wrapper.find('input').trigger('keydown');
|
||||
// });
|
||||
// await asyncExpect(() => {
|
||||
// expect(isOpen(wrapper)).toBeFalsy();
|
||||
// }, 0);
|
||||
});
|
||||
|
||||
describe('limit filtered item count', () => {
|
||||
|
|
@ -191,7 +211,6 @@ describe('Cascader', () => {
|
|||
});
|
||||
|
||||
it('negative limit', async () => {
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
const wrapper = mount(Cascader, {
|
||||
props: { options, showSearch: { filter, limit: -1 } },
|
||||
sync: false,
|
||||
|
|
@ -203,9 +222,6 @@ describe('Cascader', () => {
|
|||
await asyncExpect(() => {
|
||||
expect($$('.ant-cascader-menu-item').length).toBe(2);
|
||||
}, 0);
|
||||
expect(errorSpy).toBeCalledWith(
|
||||
"Warning: [antdv: Cascader] 'limit' of showSearch in Cascader should be positive number or false.",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,12 +20,8 @@ Cascade selection box for selecting province/city/district.
|
|||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
children?: Option[];
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
|
|||
|
|
@ -16,16 +16,17 @@ Allow only select parent options.
|
|||
|
||||
</docs>
|
||||
<template>
|
||||
<a-cascader v-model:value="value" :options="options" change-on-select />
|
||||
<a-cascader
|
||||
v-model:value="value"
|
||||
:options="options"
|
||||
placeholder="Please select"
|
||||
change-on-select
|
||||
/>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
children?: Option[];
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
|
|||
|
|
@ -16,7 +16,12 @@ For instance, add an external link after the selected value.
|
|||
|
||||
</docs>
|
||||
<template>
|
||||
<a-cascader v-model:value="value" :options="options" style="width: 100%">
|
||||
<a-cascader
|
||||
v-model:value="value"
|
||||
placeholder="Please select"
|
||||
:options="options"
|
||||
style="width: 100%"
|
||||
>
|
||||
<template #displayRender="{ labels, selectedOptions }">
|
||||
<span v-for="(label, index) in labels" :key="selectedOptions[index].value">
|
||||
<span v-if="index === labels.length - 1">
|
||||
|
|
@ -33,14 +38,8 @@ For instance, add an external link after the selected value.
|
|||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
children?: Option[];
|
||||
code?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
@ -78,7 +77,7 @@ const options: Option[] = [
|
|||
];
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const handleAreaClick = (e: Event, label: string, option: Option) => {
|
||||
const handleAreaClick = (e: Event, label: string, option: CascaderProps['options'][number]) => {
|
||||
e.stopPropagation();
|
||||
console.log('clicked', label, option);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,21 +18,20 @@ Separate trigger button and result.
|
|||
<template>
|
||||
<span>
|
||||
{{ text }}
|
||||
<a-cascader v-model:value="value" :options="options" @change="onChange">
|
||||
<a-cascader
|
||||
v-model:value="value"
|
||||
placeholder="Please select"
|
||||
:options="options"
|
||||
@change="onChange"
|
||||
>
|
||||
<a href="#">Change city</a>
|
||||
</a-cascader>
|
||||
</span>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
children?: Option[];
|
||||
code?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
@ -72,7 +71,7 @@ export default defineComponent({
|
|||
const value = ref<string[]>([]);
|
||||
const text = ref<string>('Unselect');
|
||||
|
||||
const onChange = (_value: string, selectedOptions: Option[]) => {
|
||||
const onChange: CascaderProps['onChange'] = (_value, selectedOptions) => {
|
||||
text.value = selectedOptions.map(o => o.label).join(', ');
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,19 +16,12 @@ Disable option by specifying the `disabled` property in `options`.
|
|||
|
||||
</docs>
|
||||
<template>
|
||||
<a-cascader v-model:value="value" :options="options" />
|
||||
<a-cascader v-model:value="value" placeholder="Please select" :options="options" />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
children?: Option[];
|
||||
code?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
|
|||
|
|
@ -25,14 +25,8 @@ Custom Field Names
|
|||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
code: string;
|
||||
name: string;
|
||||
disabled?: boolean;
|
||||
items?: Option[];
|
||||
[key: string]: any;
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
code: 'zhejiang',
|
||||
name: 'Zhejiang',
|
||||
|
|
|
|||
|
|
@ -19,19 +19,14 @@ Hover to expand sub menu, click to select option.
|
|||
<a-cascader
|
||||
v-model:value="value"
|
||||
:options="options"
|
||||
:display-render="displayRender"
|
||||
expand-trigger="hover"
|
||||
placeholder="Please select"
|
||||
/>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
children?: Option[];
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
@ -67,14 +62,9 @@ const options: Option[] = [
|
|||
];
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const displayRender = ({ labels }: { labels: string[] }) => {
|
||||
return labels[labels.length - 1];
|
||||
};
|
||||
|
||||
return {
|
||||
value: ref<string[]>([]),
|
||||
options,
|
||||
displayRender,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
<lazy />
|
||||
<fields-name />
|
||||
<suffix />
|
||||
<multipleVue />
|
||||
</demo-sort>
|
||||
</template>
|
||||
<script>
|
||||
|
|
@ -25,6 +26,7 @@ import Search from './search.vue';
|
|||
import Size from './size.vue';
|
||||
import FieldsName from './fields-name.vue';
|
||||
import Suffix from './suffix.vue';
|
||||
import multipleVue from './multiple.vue';
|
||||
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
|
|
@ -44,6 +46,7 @@ export default defineComponent({
|
|||
Size,
|
||||
FieldsName,
|
||||
Suffix,
|
||||
multipleVue,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -28,16 +28,11 @@ Load options lazily with `loadData`.
|
|||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
loading?: boolean;
|
||||
isLeaf?: boolean;
|
||||
children?: Option[];
|
||||
}
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const options = ref<Option[]>([
|
||||
const options = ref<CascaderProps['options']>([
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
@ -50,7 +45,7 @@ export default defineComponent({
|
|||
},
|
||||
]);
|
||||
|
||||
const loadData = (selectedOptions: Option[]) => {
|
||||
const loadData: CascaderProps['loadData'] = selectedOptions => {
|
||||
const targetOption = selectedOptions[selectedOptions.length - 1];
|
||||
targetOption.loading = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
<docs>
|
||||
---
|
||||
order: 5.1
|
||||
version: 3.0.0
|
||||
title:
|
||||
zh-CN: 多选
|
||||
en-US: Multiple
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
一次性选择多个选项。
|
||||
|
||||
## en-US
|
||||
|
||||
Select multiple options
|
||||
</docs>
|
||||
<template>
|
||||
<a-cascader
|
||||
v-model:value="value"
|
||||
style="width: 233px"
|
||||
multiple
|
||||
max-tag-count="responsive"
|
||||
:options="options"
|
||||
placeholder="Please select"
|
||||
></a-cascader>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
label: 'Light',
|
||||
value: 'light',
|
||||
children: new Array(20)
|
||||
.fill(null)
|
||||
.map((_, index) => ({ label: `Number ${index}`, value: index })),
|
||||
},
|
||||
{
|
||||
label: 'Bamboo',
|
||||
value: 'bamboo',
|
||||
children: [
|
||||
{
|
||||
label: 'Little',
|
||||
value: 'little',
|
||||
children: [
|
||||
{
|
||||
label: 'Toy Fish',
|
||||
value: 'fish',
|
||||
},
|
||||
{
|
||||
label: 'Toy Cards',
|
||||
value: 'cards',
|
||||
},
|
||||
{
|
||||
label: 'Toy Bird',
|
||||
value: 'bird',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
return {
|
||||
value: ref<string[]>([]),
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
@ -27,13 +27,9 @@ Search and select options directly.
|
|||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
children?: Option[];
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
import type { ShowSearchType } from 'ant-design-vue/es/cascader';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
@ -74,7 +70,7 @@ const options: Option[] = [
|
|||
];
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const filter = (inputValue: string, path: Option[]) => {
|
||||
const filter: ShowSearchType['filter'] = (inputValue, path) => {
|
||||
return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,24 +16,20 @@ Cascade selection box of different sizes.
|
|||
|
||||
</docs>
|
||||
<template>
|
||||
<a-cascader v-model:value="value" size="large" :options="options" />
|
||||
<a-cascader v-model:value="value" placeholder="Please select" size="large" :options="options" />
|
||||
<br />
|
||||
<br />
|
||||
<a-cascader v-model:value="value" :options="options" />
|
||||
<a-cascader v-model:value="value" placeholder="Please select" :options="options" />
|
||||
<br />
|
||||
<br />
|
||||
<a-cascader v-model:value="value" size="small" :options="options" />
|
||||
<a-cascader v-model:value="value" placeholder="Please select" size="small" :options="options" />
|
||||
<br />
|
||||
<br />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
children?: Option[];
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
|
|||
|
|
@ -35,12 +35,8 @@ Custom suffix icon
|
|||
<script lang="ts">
|
||||
import { SmileOutlined } from '@ant-design/icons-vue';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
children?: Option[];
|
||||
}
|
||||
const options: Option[] = [
|
||||
import type { CascaderProps } from 'ant-design-vue';
|
||||
const options: CascaderProps['options'] = [
|
||||
{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
|
|
|
|||
|
|
@ -19,29 +19,34 @@ Cascade selection box.
|
|||
<a-cascader :options="options" v-model:value="value" />
|
||||
```
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| allowClear | whether allow clear | boolean | true |
|
||||
| autofocus | get focus when component mounted | boolean | false |
|
||||
| changeOnSelect | change value on each selection if set to true, see above demo for details | boolean | false |
|
||||
| defaultValue | initial selected value | string\[] \| number\[] | \[] |
|
||||
| disabled | whether disabled select | boolean | false |
|
||||
| displayRender | render function of displaying selected options, you can use #displayRender="{labels, selectedOptions}" | `({labels, selectedOptions}) => VNode` | `labels => labels.join(' / ')` |
|
||||
| expandTrigger | expand current item when click or hover, one of 'click' 'hover' | string | 'click' |
|
||||
| fieldNames | custom field name for label and value and children | object | `{ label: 'label', value: 'value', children: 'children' }` |
|
||||
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. | Function(triggerNode) | () => document.body |
|
||||
| loadData | To load option lazily, and it cannot work with `showSearch` | `(selectedOptions) => void` | - |
|
||||
| notFoundContent | Specify content to show when no result matches. | string | 'Not Found' |
|
||||
| options | data options of cascade | [Option](#option)[] | - |
|
||||
| placeholder | input placeholder | string | 'Please select' |
|
||||
| popupClassName | additional className of popup overlay | string | - |
|
||||
| popupStyle | additional style of popup overlay | object | {} |
|
||||
| popupPlacement | use preset popup align config from builtinPlacements:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` |
|
||||
| popupVisible | set visible of cascader popup | boolean | - |
|
||||
| showSearch | Whether show search input in single mode. | boolean \| [object](#showsearch) | false |
|
||||
| size | input size, one of `large` `default` `small` | string | `default` |
|
||||
| suffixIcon | The custom suffix icon | string \| VNode \| slot | - |
|
||||
| value(v-model) | selected value | string\[] \| number\[] | - |
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| allowClear | whether allow clear | boolean | true | |
|
||||
| autofocus | get focus when component mounted | boolean | false | |
|
||||
| changeOnSelect | change value on each selection if set to true, see above demo for details | boolean | false | |
|
||||
| disabled | whether disabled select | boolean | false | |
|
||||
| displayRender | render function of displaying selected options, you can use #displayRender="{labels, selectedOptions}" | `({labels, selectedOptions}) => VNode` | `labels => labels.join(' / ')` | |
|
||||
| expandTrigger | expand current item when click or hover, one of 'click' 'hover' | string | 'click' | |
|
||||
| fieldNames | custom field name for label and value and children | object | `{ label: 'label', value: 'value', children: 'children' }` | |
|
||||
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. | Function(triggerNode) | () => document.body | |
|
||||
| loadData | To load option lazily, and it cannot work with `showSearch` | `(selectedOptions) => void` | - | |
|
||||
| notFoundContent | Specify content to show when no result matches. | string \| slot | 'Not Found' | |
|
||||
| options | data options of cascade | [Option](#option)[] | - | |
|
||||
| placeholder | input placeholder | string | 'Please select' | |
|
||||
| showSearch | Whether show search input in single mode. | boolean \| [object](#showsearch) | false | |
|
||||
| size | input size, one of `large` `default` `small` | string | `default` | |
|
||||
| suffixIcon | The custom suffix icon | string \| VNode \| slot | - | |
|
||||
| value(v-model) | selected value | string\[] \| number\[] | - | |
|
||||
| expandIcon | Customize the current item expand icon | slot | - | 3.0 |
|
||||
| maxTagCount | Max tag count to show. `responsive` will cost render performance | number \| `responsive` | - | 3.0 |
|
||||
| maxTagPlaceholder | Placeholder for not showing tags | v-slot \| function(omittedValues) | - | 3.0 |
|
||||
| dropdownClassName | additional className of popup overlay | string | - | 3.0 |
|
||||
| dropdownStyle | additional style of popup overlay | CSSProperties | {} | 3.0 |
|
||||
| open | set visible of cascader popup | boolean | - | 3.0 |
|
||||
| placement | use preset popup align config from builtinPlacements:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | 3.0 |
|
||||
| tagRender | Customize tag render when `multiple` | slot | - | 3.0 |
|
||||
| multiple | Support multiple or not | boolean | - | 3.0 |
|
||||
| searchValue | Set search value,Need work with `showSearch` | string | - | 3.0 |
|
||||
|
||||
### showSearch
|
||||
|
||||
|
|
@ -60,7 +65,7 @@ Fields in `showSearch`:
|
|||
| Events Name | Description | Arguments | version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| change | callback when finishing cascader select | `(value, selectedOptions) => void` | - | |
|
||||
| popupVisibleChange | callback when popup shown or hidden | `(value) => void` | - | |
|
||||
| dropdownVisibleChange | callback when popup shown or hidden | `(value) => void` | - | 3.0 |
|
||||
| search | callback when input value change | `(value) => void` | - | 1.5.4 |
|
||||
|
||||
### Option
|
||||
|
|
|
|||
|
|
@ -1,646 +1,277 @@
|
|||
import type { PropType, CSSProperties, ExtractPropTypes } from 'vue';
|
||||
import { inject, provide, defineComponent } from 'vue';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import VcCascader from '../vc-cascader';
|
||||
import arrayTreeFilter from 'array-tree-filter';
|
||||
import classNames from '../_util/classNames';
|
||||
import KeyCode from '../_util/KeyCode';
|
||||
import Input from '../input';
|
||||
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
|
||||
import DownOutlined from '@ant-design/icons-vue/DownOutlined';
|
||||
import type { ShowSearchType, FieldNames, BaseOptionType, DefaultOptionType } from '../vc-cascader';
|
||||
import VcCascader, { cascaderProps as vcCascaderProps } from '../vc-cascader';
|
||||
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
|
||||
import RedoOutlined from '@ant-design/icons-vue/RedoOutlined';
|
||||
import {
|
||||
hasProp,
|
||||
getOptionProps,
|
||||
isValidElement,
|
||||
getComponent,
|
||||
splitAttrs,
|
||||
findDOMNode,
|
||||
getSlot,
|
||||
} from '../_util/props-util';
|
||||
import BaseMixin from '../_util/BaseMixin';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import warning from '../_util/warning';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import LeftOutlined from '@ant-design/icons-vue/LeftOutlined';
|
||||
import getIcons from '../select/utils/iconUtil';
|
||||
import type { VueNode } from '../_util/type';
|
||||
import { tuple, withInstall } from '../_util/type';
|
||||
import type { RenderEmptyHandler } from '../config-provider/renderEmpty';
|
||||
import { useInjectFormItemContext } from '../form/FormItemContext';
|
||||
import { withInstall } from '../_util/type';
|
||||
import omit from '../_util/omit';
|
||||
import { computed, defineComponent, ref, watchEffect } from 'vue';
|
||||
import type { ExtractPropTypes, PropType } from 'vue';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { initDefaultProps } from '../_util/props-util';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
import classNames from '../_util/classNames';
|
||||
import type { SizeType } from '../config-provider';
|
||||
import devWarning from '../vc-util/devWarning';
|
||||
import { getTransitionName } from '../_util/transition';
|
||||
import { useInjectFormItemContext } from '../form';
|
||||
import type { ValueType } from '../vc-cascader/Cascader';
|
||||
|
||||
export interface CascaderOptionType {
|
||||
value?: string | number;
|
||||
label?: VueNode;
|
||||
disabled?: boolean;
|
||||
// Align the design since we use `rc-select` in root. This help:
|
||||
// - List search content will show all content
|
||||
// - Hover opacity style
|
||||
// - Search filter match case
|
||||
|
||||
export type { BaseOptionType, DefaultOptionType, ShowSearchType };
|
||||
|
||||
export type FieldNamesType = FieldNames;
|
||||
|
||||
export type FilledFieldNamesType = Required<FieldNamesType>;
|
||||
|
||||
function highlightKeyword(str: string, lowerKeyword: string, prefixCls: string | undefined) {
|
||||
const cells = str
|
||||
.toLowerCase()
|
||||
.split(lowerKeyword)
|
||||
.reduce((list, cur, index) => (index === 0 ? [cur] : [...list, lowerKeyword, cur]), []);
|
||||
const fillCells: VueNode[] = [];
|
||||
let start = 0;
|
||||
|
||||
cells.forEach((cell, index) => {
|
||||
const end = start + cell.length;
|
||||
let originWorld: VueNode = str.slice(start, end);
|
||||
start = end;
|
||||
|
||||
if (index % 2 === 1) {
|
||||
originWorld = (
|
||||
<span class={`${prefixCls}-menu-item-keyword`} key="seperator">
|
||||
{originWorld}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
fillCells.push(originWorld);
|
||||
});
|
||||
|
||||
return fillCells;
|
||||
}
|
||||
|
||||
const defaultSearchRender: ShowSearchType['render'] = ({
|
||||
inputValue,
|
||||
path,
|
||||
prefixCls,
|
||||
fieldNames,
|
||||
}) => {
|
||||
const optionList: VueNode[] = [];
|
||||
|
||||
// We do lower here to save perf
|
||||
const lower = inputValue.toLowerCase();
|
||||
|
||||
path.forEach((node, index) => {
|
||||
if (index !== 0) {
|
||||
optionList.push(' / ');
|
||||
}
|
||||
|
||||
let label = (node as any)[fieldNames.label!];
|
||||
const type = typeof label;
|
||||
if (type === 'string' || type === 'number') {
|
||||
label = highlightKeyword(String(label), lower, prefixCls);
|
||||
}
|
||||
|
||||
optionList.push(label);
|
||||
});
|
||||
return optionList;
|
||||
};
|
||||
|
||||
export interface CascaderOptionType extends DefaultOptionType {
|
||||
isLeaf?: boolean;
|
||||
loading?: boolean;
|
||||
children?: CascaderOptionType[];
|
||||
[key: string]: any;
|
||||
}
|
||||
export function cascaderProps<DataNodeType extends CascaderOptionType = CascaderOptionType>() {
|
||||
return {
|
||||
...omit(vcCascaderProps(), ['customSlots', 'checkable', 'options']),
|
||||
multiple: { type: Boolean, default: undefined },
|
||||
size: String as PropType<SizeType>,
|
||||
bordered: { type: Boolean, default: undefined },
|
||||
|
||||
export interface FieldNamesType {
|
||||
value?: string;
|
||||
label?: string;
|
||||
children?: string;
|
||||
}
|
||||
|
||||
export interface FilledFieldNamesType {
|
||||
value: string;
|
||||
label: string;
|
||||
children: string;
|
||||
}
|
||||
|
||||
// const CascaderOptionType = PropTypes.shape({
|
||||
// value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
// label: PropTypes.any,
|
||||
// disabled: PropTypes.looseBool,
|
||||
// children: PropTypes.array,
|
||||
// key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
// }).loose;
|
||||
|
||||
// const FieldNamesType = PropTypes.shape({
|
||||
// value: PropTypes.string.isRequired,
|
||||
// label: PropTypes.string.isRequired,
|
||||
// children: PropTypes.string,
|
||||
// }).loose;
|
||||
|
||||
export interface ShowSearchType {
|
||||
filter?: (inputValue: string, path: CascaderOptionType[], names: FilledFieldNamesType) => boolean;
|
||||
render?: (
|
||||
inputValue: string,
|
||||
path: CascaderOptionType[],
|
||||
prefixCls: string | undefined,
|
||||
names: FilledFieldNamesType,
|
||||
) => VueNode;
|
||||
sort?: (
|
||||
a: CascaderOptionType[],
|
||||
b: CascaderOptionType[],
|
||||
inputValue: string,
|
||||
names: FilledFieldNamesType,
|
||||
) => number;
|
||||
matchInputWidth?: boolean;
|
||||
limit?: number | false;
|
||||
}
|
||||
|
||||
export interface EmptyFilteredOptionsType {
|
||||
disabled: boolean;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface FilteredOptionsType extends EmptyFilteredOptionsType {
|
||||
__IS_FILTERED_OPTION: boolean;
|
||||
path: CascaderOptionType[];
|
||||
}
|
||||
|
||||
// const ShowSearchType = PropTypes.shape({
|
||||
// filter: PropTypes.func,
|
||||
// render: PropTypes.func,
|
||||
// sort: PropTypes.func,
|
||||
// matchInputWidth: PropTypes.looseBool,
|
||||
// limit: withUndefined(PropTypes.oneOfType([Boolean, Number])),
|
||||
// }).loose;
|
||||
function noop() {}
|
||||
|
||||
const cascaderProps = {
|
||||
/** 可选项数据源 */
|
||||
options: { type: Array as PropType<CascaderOptionType[]>, default: [] },
|
||||
/** 默认的选中项 */
|
||||
defaultValue: PropTypes.array,
|
||||
/** 指定选中项 */
|
||||
value: PropTypes.array,
|
||||
/** 选择完成后的回调 */
|
||||
// onChange?: (value: string[], selectedOptions?: CascaderOptionType[]) => void;
|
||||
/** 选择后展示的渲染函数 */
|
||||
displayRender: PropTypes.func,
|
||||
transitionName: PropTypes.string,
|
||||
popupStyle: PropTypes.object.def(() => ({})),
|
||||
/** 自定义浮层类名 */
|
||||
popupClassName: PropTypes.string,
|
||||
/** 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` */
|
||||
popupPlacement: PropTypes.oneOf(tuple('bottomLeft', 'bottomRight', 'topLeft', 'topRight')).def(
|
||||
'bottomLeft',
|
||||
),
|
||||
/** 输入框占位文本*/
|
||||
placeholder: PropTypes.string.def('Please select'),
|
||||
/** 输入框大小,可选 `large` `default` `small` */
|
||||
size: PropTypes.oneOf(tuple('large', 'default', 'small')),
|
||||
/** 禁用*/
|
||||
disabled: PropTypes.looseBool.def(false),
|
||||
/** 是否支持清除*/
|
||||
allowClear: PropTypes.looseBool.def(true),
|
||||
showSearch: {
|
||||
type: [Boolean, Object] as PropType<boolean | ShowSearchType | undefined>,
|
||||
default: undefined as PropType<boolean | ShowSearchType | undefined>,
|
||||
},
|
||||
notFoundContent: PropTypes.any,
|
||||
loadData: PropTypes.func,
|
||||
/** 次级菜单的展开方式,可选 'click' 和 'hover' */
|
||||
expandTrigger: PropTypes.oneOf(tuple('click', 'hover')),
|
||||
/** 当此项为 true 时,点选每级菜单选项值都会发生变化 */
|
||||
changeOnSelect: PropTypes.looseBool,
|
||||
/** 浮层可见变化时回调 */
|
||||
// onPopupVisibleChange?: (popupVisible: boolean) => void;
|
||||
prefixCls: PropTypes.string,
|
||||
inputPrefixCls: PropTypes.string,
|
||||
getPopupContainer: PropTypes.func,
|
||||
popupVisible: PropTypes.looseBool,
|
||||
fieldNames: { type: Object as PropType<FieldNamesType> },
|
||||
autofocus: PropTypes.looseBool,
|
||||
suffixIcon: PropTypes.any,
|
||||
showSearchRender: PropTypes.any,
|
||||
onChange: PropTypes.func,
|
||||
onPopupVisibleChange: PropTypes.func,
|
||||
onFocus: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
onSearch: PropTypes.func,
|
||||
'onUpdate:value': PropTypes.func,
|
||||
};
|
||||
|
||||
export type CascaderProps = Partial<ExtractPropTypes<typeof cascaderProps>>;
|
||||
|
||||
// We limit the filtered item count by default
|
||||
const defaultLimit = 50;
|
||||
|
||||
function defaultFilterOption(
|
||||
inputValue: string,
|
||||
path: CascaderOptionType[],
|
||||
names: FilledFieldNamesType,
|
||||
) {
|
||||
return path.some(option => option[names.label].indexOf(inputValue) > -1);
|
||||
}
|
||||
|
||||
function defaultSortFilteredOption(
|
||||
a: CascaderOptionType[],
|
||||
b: CascaderOptionType[],
|
||||
inputValue: string,
|
||||
names: FilledFieldNamesType,
|
||||
) {
|
||||
function callback(elem: CascaderOptionType) {
|
||||
return elem[names.label].indexOf(inputValue) > -1;
|
||||
}
|
||||
|
||||
return a.findIndex(callback) - b.findIndex(callback);
|
||||
}
|
||||
|
||||
function getFilledFieldNames(props: any) {
|
||||
const fieldNames = (props.fieldNames || {}) as FieldNamesType;
|
||||
const names: FilledFieldNamesType = {
|
||||
children: fieldNames.children || 'children',
|
||||
label: fieldNames.label || 'label',
|
||||
value: fieldNames.value || 'value',
|
||||
suffixIcon: PropTypes.any,
|
||||
options: Array as PropType<DataNodeType[]>,
|
||||
'onUpdate:value': Function as PropType<(value: ValueType) => void>,
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
function flattenTree(
|
||||
options: CascaderOptionType[],
|
||||
props: any,
|
||||
ancestor: CascaderOptionType[] = [],
|
||||
) {
|
||||
const names: FilledFieldNamesType = getFilledFieldNames(props);
|
||||
let flattenOptions = [];
|
||||
const childrenName = names.children;
|
||||
options.forEach(option => {
|
||||
const path = ancestor.concat(option);
|
||||
if (props.changeOnSelect || !option[childrenName] || !option[childrenName].length) {
|
||||
flattenOptions.push(path);
|
||||
}
|
||||
if (option[childrenName]) {
|
||||
flattenOptions = flattenOptions.concat(flattenTree(option[childrenName], props, path));
|
||||
}
|
||||
});
|
||||
return flattenOptions;
|
||||
}
|
||||
export type CascaderProps = Partial<ExtractPropTypes<ReturnType<typeof cascaderProps>>>;
|
||||
|
||||
const defaultDisplayRender = ({ labels }) => labels.join(' / ');
|
||||
export interface CascaderRef {
|
||||
focus: () => void;
|
||||
blur: () => void;
|
||||
}
|
||||
|
||||
const Cascader = defineComponent({
|
||||
name: 'ACascader',
|
||||
mixins: [BaseMixin],
|
||||
inheritAttrs: false,
|
||||
props: cascaderProps,
|
||||
setup() {
|
||||
props: initDefaultProps(cascaderProps(), {
|
||||
bordered: true,
|
||||
choiceTransitionName: '',
|
||||
allowClear: true,
|
||||
}),
|
||||
setup(props, { attrs, expose, slots, emit }) {
|
||||
const formItemContext = useInjectFormItemContext();
|
||||
return {
|
||||
configProvider: inject('configProvider', defaultConfigProvider),
|
||||
localeData: inject('localeData', {} as any),
|
||||
cachedOptions: [],
|
||||
popupRef: undefined,
|
||||
input: undefined,
|
||||
formItemContext,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
const { value, defaultValue, popupVisible, showSearch, options } = this.$props;
|
||||
return {
|
||||
sValue: (value || defaultValue || []) as any[],
|
||||
inputValue: '',
|
||||
inputFocused: false,
|
||||
sPopupVisible: popupVisible as boolean,
|
||||
flattenOptions: showSearch
|
||||
? flattenTree(options as CascaderOptionType[], this.$props)
|
||||
: undefined,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.setState({ sValue: val || [] });
|
||||
},
|
||||
popupVisible(val) {
|
||||
this.setState({ sPopupVisible: val });
|
||||
},
|
||||
options(val) {
|
||||
if (this.showSearch) {
|
||||
this.setState({ flattenOptions: flattenTree(val, this.$props as any) });
|
||||
}
|
||||
},
|
||||
},
|
||||
// model: {
|
||||
// prop: 'value',
|
||||
// event: 'change',
|
||||
// },
|
||||
created() {
|
||||
provide('savePopupRef', this.savePopupRef);
|
||||
},
|
||||
methods: {
|
||||
savePopupRef(ref: any) {
|
||||
this.popupRef = ref;
|
||||
},
|
||||
highlightKeyword(str: string, keyword: string, prefixCls: string | undefined) {
|
||||
return str
|
||||
.split(keyword)
|
||||
.map((node, index) =>
|
||||
index === 0
|
||||
? node
|
||||
: [<span class={`${prefixCls}-menu-item-keyword`}>{keyword}</span>, node],
|
||||
);
|
||||
},
|
||||
|
||||
defaultRenderFilteredOption(opt: {
|
||||
inputValue: string;
|
||||
path: CascaderOptionType[];
|
||||
prefixCls: string | undefined;
|
||||
names: FilledFieldNamesType;
|
||||
}) {
|
||||
const { inputValue, path, prefixCls, names } = opt;
|
||||
return path.map((option, index) => {
|
||||
const label = option[names.label];
|
||||
const node =
|
||||
label.indexOf(inputValue) > -1
|
||||
? this.highlightKeyword(label, inputValue, prefixCls)
|
||||
: label;
|
||||
return index === 0 ? node : [' / ', node];
|
||||
});
|
||||
},
|
||||
saveInput(node: any) {
|
||||
this.input = node;
|
||||
},
|
||||
handleChange(value: any, selectedOptions: CascaderOptionType[]) {
|
||||
this.setState({ inputValue: '' });
|
||||
if (selectedOptions[0].__IS_FILTERED_OPTION) {
|
||||
const unwrappedValue = value[0];
|
||||
const unwrappedSelectedOptions = selectedOptions[0].path;
|
||||
this.setValue(unwrappedValue, unwrappedSelectedOptions);
|
||||
return;
|
||||
}
|
||||
this.setValue(value, selectedOptions);
|
||||
},
|
||||
|
||||
handlePopupVisibleChange(popupVisible: boolean) {
|
||||
if (!hasProp(this, 'popupVisible')) {
|
||||
this.setState((state: any) => ({
|
||||
sPopupVisible: popupVisible,
|
||||
inputFocused: popupVisible,
|
||||
inputValue: popupVisible ? state.inputValue : '',
|
||||
}));
|
||||
}
|
||||
this.$emit('popupVisibleChange', popupVisible);
|
||||
},
|
||||
handleInputFocus(e: InputEvent) {
|
||||
this.$emit('focus', e);
|
||||
},
|
||||
|
||||
handleInputBlur(e: InputEvent) {
|
||||
this.setState({
|
||||
inputFocused: false,
|
||||
});
|
||||
this.$emit('blur', e);
|
||||
this.formItemContext.onFieldBlur();
|
||||
},
|
||||
|
||||
handleInputClick(e: MouseEvent & { nativeEvent?: any }) {
|
||||
const { inputFocused, sPopupVisible } = this;
|
||||
// Prevent `Trigger` behavior.
|
||||
if (inputFocused || sPopupVisible) {
|
||||
e.stopPropagation();
|
||||
if (e.nativeEvent && e.nativeEvent.stopImmediatePropagation) {
|
||||
e.nativeEvent.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleKeyDown(e: KeyboardEvent) {
|
||||
if (e.keyCode === KeyCode.BACKSPACE || e.keyCode === KeyCode.SPACE) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
handleInputChange(e: Event) {
|
||||
const inputValue = (e.target as HTMLInputElement).value;
|
||||
this.setState({ inputValue });
|
||||
this.$emit('search', inputValue);
|
||||
},
|
||||
|
||||
setValue(value: string[] | number[], selectedOptions: CascaderOptionType[] = []) {
|
||||
if (!hasProp(this, 'value')) {
|
||||
this.setState({ sValue: value });
|
||||
}
|
||||
this.$emit('update:value', value);
|
||||
this.$emit('change', value, selectedOptions);
|
||||
this.formItemContext.onFieldChange();
|
||||
},
|
||||
|
||||
getLabel() {
|
||||
const { options } = this;
|
||||
const names = getFilledFieldNames(this.$props);
|
||||
const displayRender = getComponent(this, 'displayRender', {}, false) || defaultDisplayRender;
|
||||
const value = this.sValue;
|
||||
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
|
||||
const selectedOptions = arrayTreeFilter<CascaderOptionType>(
|
||||
options as CascaderOptionType[],
|
||||
(o, level) => o[names.value] === unwrappedValue[level],
|
||||
{ childrenKeyName: names.children },
|
||||
);
|
||||
const labels = selectedOptions.map(o => o[names.label]);
|
||||
return displayRender({ labels, selectedOptions });
|
||||
},
|
||||
|
||||
clearSelection(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (!this.inputValue) {
|
||||
this.setValue([]);
|
||||
this.handlePopupVisibleChange(false);
|
||||
} else {
|
||||
this.setState({ inputValue: '' });
|
||||
}
|
||||
},
|
||||
|
||||
generateFilteredOptions(
|
||||
prefixCls: string | undefined,
|
||||
renderEmpty: RenderEmptyHandler,
|
||||
): EmptyFilteredOptionsType[] | FilteredOptionsType[] {
|
||||
const { showSearch, notFoundContent } = this;
|
||||
const names: FilledFieldNamesType = getFilledFieldNames(this.$props);
|
||||
const {
|
||||
filter = defaultFilterOption,
|
||||
// render = this.defaultRenderFilteredOption,
|
||||
sort = defaultSortFilteredOption,
|
||||
limit = defaultLimit,
|
||||
} = showSearch as ShowSearchType;
|
||||
const render =
|
||||
(showSearch as ShowSearchType).render ||
|
||||
getComponent(this, 'showSearchRender') ||
|
||||
this.defaultRenderFilteredOption;
|
||||
const { flattenOptions = [], inputValue } = this.$data;
|
||||
|
||||
// Limit the filter if needed
|
||||
let filtered: Array<CascaderOptionType[]>;
|
||||
if (limit > 0) {
|
||||
filtered = [];
|
||||
let matchCount = 0;
|
||||
|
||||
// Perf optimization to filter items only below the limit
|
||||
flattenOptions.some(path => {
|
||||
const match = filter(inputValue, path, names);
|
||||
if (match) {
|
||||
filtered.push(path);
|
||||
matchCount += 1;
|
||||
}
|
||||
return matchCount >= limit;
|
||||
});
|
||||
} else {
|
||||
warning(
|
||||
typeof limit !== 'number',
|
||||
'Cascader',
|
||||
"'limit' of showSearch in Cascader should be positive number or false.",
|
||||
);
|
||||
filtered = flattenOptions.filter(path => filter(inputValue, path, names));
|
||||
}
|
||||
|
||||
filtered.sort((a, b) => sort(a, b, inputValue, names));
|
||||
|
||||
if (filtered.length > 0) {
|
||||
return filtered.map(path => {
|
||||
return {
|
||||
__IS_FILTERED_OPTION: true,
|
||||
path,
|
||||
[names.label]: render({ inputValue, path, prefixCls, names }),
|
||||
[names.value]: path.map(o => o[names.value]),
|
||||
disabled: path.some(o => !!o.disabled),
|
||||
};
|
||||
});
|
||||
}
|
||||
return [
|
||||
{
|
||||
[names.label]: notFoundContent || renderEmpty('Cascader'),
|
||||
[names.value]: 'ANT_CASCADER_NOT_FOUND',
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
focus() {
|
||||
this.input && this.input.focus();
|
||||
},
|
||||
|
||||
blur() {
|
||||
this.input && this.input.blur();
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { sPopupVisible, inputValue, configProvider, localeData } = this;
|
||||
const { sValue: value, inputFocused } = this.$data;
|
||||
const props = getOptionProps(this);
|
||||
let suffixIcon = getComponent(this, 'suffixIcon');
|
||||
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
|
||||
const { getPopupContainer: getContextPopupContainer } = configProvider;
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
inputPrefixCls: customizeInputPrefixCls,
|
||||
placeholder = localeData.placeholder,
|
||||
size,
|
||||
disabled,
|
||||
allowClear,
|
||||
showSearch = false,
|
||||
notFoundContent,
|
||||
...otherProps
|
||||
} = props as any;
|
||||
const { onEvents, extraAttrs } = splitAttrs(this.$attrs);
|
||||
const {
|
||||
class: className,
|
||||
style,
|
||||
id = this.formItemContext.id.value,
|
||||
...restAttrs
|
||||
} = extraAttrs;
|
||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||
const renderEmpty = this.configProvider.renderEmpty;
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
const prefixCls = getPrefixCls('cascader', customizePrefixCls);
|
||||
const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls);
|
||||
|
||||
const sizeCls = classNames({
|
||||
[`${inputPrefixCls}-lg`]: size === 'large',
|
||||
[`${inputPrefixCls}-sm`]: size === 'small',
|
||||
});
|
||||
const clearIcon =
|
||||
(allowClear && !disabled && value.length > 0) || inputValue ? (
|
||||
<CloseCircleFilled
|
||||
class={`${prefixCls}-picker-clear`}
|
||||
onClick={this.clearSelection}
|
||||
key="clear-icon"
|
||||
/>
|
||||
) : null;
|
||||
const arrowCls = classNames({
|
||||
[`${prefixCls}-picker-arrow`]: true,
|
||||
[`${prefixCls}-picker-arrow-expand`]: sPopupVisible,
|
||||
});
|
||||
const pickerCls = classNames(className, `${prefixCls}-picker`, {
|
||||
[`${prefixCls}-picker-with-value`]: inputValue,
|
||||
[`${prefixCls}-picker-disabled`]: disabled,
|
||||
[`${prefixCls}-picker-${size}`]: !!size,
|
||||
[`${prefixCls}-picker-show-search`]: !!showSearch,
|
||||
[`${prefixCls}-picker-focused`]: inputFocused,
|
||||
});
|
||||
|
||||
// Fix bug of https://github.com/facebook/react/pull/5004
|
||||
// and https://fb.me/react-unknown-prop
|
||||
const tempInputProps = omit(otherProps, [
|
||||
'popupStyle',
|
||||
'options',
|
||||
'popupPlacement',
|
||||
'transitionName',
|
||||
'displayRender',
|
||||
'changeOnSelect',
|
||||
'expandTrigger',
|
||||
'popupVisible',
|
||||
'getPopupContainer',
|
||||
'loadData',
|
||||
'popupClassName',
|
||||
'filterOption',
|
||||
'renderFilteredOption',
|
||||
'sortFilteredOption',
|
||||
'notFoundContent',
|
||||
'defaultValue',
|
||||
'fieldNames',
|
||||
'onChange',
|
||||
'onPopupVisibleChange',
|
||||
'onFocus',
|
||||
'onBlur',
|
||||
'onSearch',
|
||||
'onUpdate:value',
|
||||
]);
|
||||
|
||||
let options = props.options;
|
||||
const names = getFilledFieldNames(this.$props);
|
||||
if (options && options.length > 0) {
|
||||
if (inputValue) {
|
||||
options = this.generateFilteredOptions(prefixCls, renderEmpty);
|
||||
}
|
||||
} else {
|
||||
options = [
|
||||
{
|
||||
[names.label]: notFoundContent || renderEmpty('Cascader'),
|
||||
[names.value]: 'ANT_CASCADER_NOT_FOUND',
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// Dropdown menu should keep previous status until it is fully closed.
|
||||
if (!sPopupVisible) {
|
||||
options = this.cachedOptions;
|
||||
} else {
|
||||
this.cachedOptions = options;
|
||||
}
|
||||
|
||||
const dropdownMenuColumnStyle: CSSProperties = {};
|
||||
const isNotFound =
|
||||
(options || []).length === 1 && options[0].value === 'ANT_CASCADER_NOT_FOUND';
|
||||
if (isNotFound) {
|
||||
dropdownMenuColumnStyle.height = 'auto'; // Height of one row.
|
||||
}
|
||||
// The default value of `matchInputWidth` is `true`
|
||||
const resultListMatchInputWidth = showSearch.matchInputWidth !== false;
|
||||
if (resultListMatchInputWidth && (inputValue || isNotFound) && this.input) {
|
||||
dropdownMenuColumnStyle.width = findDOMNode(this.input.input).offsetWidth + 'px';
|
||||
}
|
||||
// showSearch时,focus、blur在input上触发,反之在ref='picker'上触发
|
||||
const inputProps = {
|
||||
...restAttrs,
|
||||
...tempInputProps,
|
||||
id,
|
||||
prefixCls: inputPrefixCls,
|
||||
placeholder: value && value.length > 0 ? undefined : placeholder,
|
||||
value: inputValue,
|
||||
disabled,
|
||||
readonly: !showSearch,
|
||||
autocomplete: 'off',
|
||||
class: `${prefixCls}-input ${sizeCls}`,
|
||||
onFocus: this.handleInputFocus,
|
||||
onClick: showSearch ? this.handleInputClick : noop,
|
||||
onBlur: showSearch ? this.handleInputBlur : props.onBlur,
|
||||
onKeydown: this.handleKeyDown,
|
||||
onChange: showSearch ? this.handleInputChange : noop,
|
||||
};
|
||||
const children = getSlot(this);
|
||||
const inputIcon = (suffixIcon &&
|
||||
(isValidElement(suffixIcon) ? (
|
||||
cloneElement(suffixIcon, {
|
||||
class: `${prefixCls}-picker-arrow`,
|
||||
})
|
||||
) : (
|
||||
<span class={`${prefixCls}-picker-arrow`}>{suffixIcon}</span>
|
||||
))) || <DownOutlined class={arrowCls} />;
|
||||
|
||||
const input = children.length ? (
|
||||
children
|
||||
) : (
|
||||
<span class={pickerCls} style={style}>
|
||||
<span class={`${prefixCls}-picker-label`}>{this.getLabel()}</span>
|
||||
<Input {...inputProps} ref={this.saveInput} />
|
||||
{clearIcon}
|
||||
{inputIcon}
|
||||
</span>
|
||||
);
|
||||
|
||||
const expandIcon = <RightOutlined />;
|
||||
|
||||
const loadingIcon = (
|
||||
<span class={`${prefixCls}-menu-item-loading-icon`}>
|
||||
<RedoOutlined spin />
|
||||
</span>
|
||||
);
|
||||
const getPopupContainer = props.getPopupContainer || getContextPopupContainer;
|
||||
const cascaderProps = {
|
||||
...props,
|
||||
prefixCls: cascaderPrefixCls,
|
||||
rootPrefixCls,
|
||||
getPrefixCls,
|
||||
direction,
|
||||
getPopupContainer,
|
||||
options,
|
||||
prefixCls,
|
||||
value,
|
||||
popupVisible: sPopupVisible,
|
||||
dropdownMenuColumnStyle,
|
||||
expandIcon,
|
||||
loadingIcon,
|
||||
...onEvents,
|
||||
onPopupVisibleChange: this.handlePopupVisibleChange,
|
||||
onChange: this.handleChange,
|
||||
transitionName: getTransitionName(rootPrefixCls, 'slide-up', props.transitionName),
|
||||
renderEmpty,
|
||||
size,
|
||||
} = useConfigInject('cascader', props);
|
||||
const prefixCls = computed(() => getPrefixCls('select', props.prefixCls));
|
||||
const isRtl = computed(() => direction.value === 'rtl');
|
||||
// =================== Warning =====================
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
watchEffect(() => {
|
||||
devWarning(
|
||||
!props.multiple || !props.displayRender || !slots.displayRender,
|
||||
'Cascader',
|
||||
'`displayRender` not work on `multiple`. Please use `tagRender` instead.',
|
||||
);
|
||||
});
|
||||
}
|
||||
// ==================== Search =====================
|
||||
const mergedShowSearch = computed(() => {
|
||||
if (!props.showSearch) {
|
||||
return props.showSearch;
|
||||
}
|
||||
|
||||
let searchConfig: ShowSearchType = {
|
||||
render: defaultSearchRender,
|
||||
};
|
||||
|
||||
if (typeof props.showSearch === 'object') {
|
||||
searchConfig = {
|
||||
...searchConfig,
|
||||
...props.showSearch,
|
||||
};
|
||||
}
|
||||
|
||||
return searchConfig;
|
||||
});
|
||||
|
||||
// =================== Dropdown ====================
|
||||
const mergedDropdownClassName = computed(() =>
|
||||
classNames(
|
||||
props.dropdownClassName || props.popupClassName,
|
||||
`${cascaderPrefixCls.value}-dropdown`,
|
||||
{
|
||||
[`${cascaderPrefixCls.value}-dropdown-rtl`]: isRtl.value,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
const selectRef = ref<CascaderRef>();
|
||||
expose({
|
||||
focus() {
|
||||
selectRef.value?.focus();
|
||||
},
|
||||
blur() {
|
||||
selectRef.value?.blur();
|
||||
},
|
||||
} as CascaderRef);
|
||||
|
||||
const handleChange: CascaderProps['onChange'] = (...args) => {
|
||||
emit('update:value', args[0]);
|
||||
emit('change', ...args);
|
||||
formItemContext.onFieldChange();
|
||||
};
|
||||
const handleBlur: CascaderProps['onBlur'] = (...args) => {
|
||||
emit('blur', ...args);
|
||||
formItemContext.onFieldBlur();
|
||||
};
|
||||
|
||||
return () => {
|
||||
const {
|
||||
notFoundContent = slots.notFoundContent?.(),
|
||||
expandIcon = slots.expandIcon?.(),
|
||||
multiple,
|
||||
bordered,
|
||||
allowClear,
|
||||
choiceTransitionName,
|
||||
transitionName,
|
||||
id = formItemContext.id.value,
|
||||
...restProps
|
||||
} = props;
|
||||
// =================== No Found ====================
|
||||
const mergedNotFoundContent = notFoundContent || renderEmpty.value('Cascader');
|
||||
|
||||
// ===================== Icon ======================
|
||||
let mergedExpandIcon = expandIcon;
|
||||
if (!expandIcon) {
|
||||
mergedExpandIcon = isRtl.value ? <LeftOutlined /> : <RightOutlined />;
|
||||
}
|
||||
|
||||
const loadingIcon = (
|
||||
<span class={`${prefixCls.value}-menu-item-loading-icon`}>
|
||||
<RedoOutlined spin />
|
||||
</span>
|
||||
);
|
||||
|
||||
// ===================== Icons =====================
|
||||
const { suffixIcon, removeIcon, clearIcon } = getIcons(
|
||||
{
|
||||
...props,
|
||||
multiple,
|
||||
prefixCls: prefixCls.value,
|
||||
},
|
||||
slots,
|
||||
);
|
||||
return (
|
||||
<VcCascader
|
||||
{...restProps}
|
||||
{...attrs}
|
||||
id={id}
|
||||
prefixCls={prefixCls.value}
|
||||
class={[
|
||||
cascaderPrefixCls.value,
|
||||
{
|
||||
[`${prefixCls.value}-lg`]: size.value === 'large',
|
||||
[`${prefixCls.value}-sm`]: size.value === 'small',
|
||||
[`${prefixCls.value}-rtl`]: isRtl.value,
|
||||
[`${prefixCls.value}-borderless`]: !bordered,
|
||||
},
|
||||
attrs.class,
|
||||
]}
|
||||
direction={direction.value}
|
||||
notFoundContent={mergedNotFoundContent}
|
||||
allowClear={allowClear}
|
||||
showSearch={mergedShowSearch.value}
|
||||
expandIcon={mergedExpandIcon}
|
||||
inputIcon={suffixIcon}
|
||||
removeIcon={removeIcon}
|
||||
clearIcon={clearIcon}
|
||||
loadingIcon={loadingIcon}
|
||||
checkable={!!multiple}
|
||||
dropdownClassName={mergedDropdownClassName.value}
|
||||
dropdownPrefixCls={cascaderPrefixCls.value}
|
||||
choiceTransitionName={getTransitionName(rootPrefixCls.value, '', choiceTransitionName)}
|
||||
transitionName={getTransitionName(rootPrefixCls.value, 'slide-up', transitionName)}
|
||||
getPopupContainer={getPopupContainer.value}
|
||||
customSlots={{
|
||||
...slots,
|
||||
checkable: () => <span class={`${cascaderPrefixCls.value}-checkbox-inner`} />,
|
||||
}}
|
||||
displayRender={props.displayRender || slots.displayRender}
|
||||
maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
v-slots={slots}
|
||||
ref={selectRef}
|
||||
/>
|
||||
);
|
||||
};
|
||||
return <VcCascader {...cascaderProps}>{input}</VcCascader>;
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -20,29 +20,35 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
|
|||
<a-cascader :options="options" v-model:value="value" />
|
||||
```
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| allowClear | 是否支持清除 | boolean | true |
|
||||
| autofocus | 自动获取焦点 | boolean | false |
|
||||
| changeOnSelect | 当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 | boolean | false |
|
||||
| defaultValue | 默认的选中项 | string\[] \| number\[] | \[] |
|
||||
| disabled | 禁用 | boolean | false |
|
||||
| displayRender | 选择后展示的渲染函数,可使用 #displayRender="{labels, selectedOptions}" | `({labels, selectedOptions}) => VNode` | `labels => labels.join(' / ')` |
|
||||
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | 'click' |
|
||||
| fieldNames | 自定义 options 中 label name children 的字段 | object | `{ label: 'label', value: 'value', children: 'children' }` |
|
||||
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | () => document.body |
|
||||
| loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | `(selectedOptions) => void` | - |
|
||||
| notFoundContent | 当下拉列表为空时显示的内容 | string | 'Not Found' |
|
||||
| options | 可选项数据源 | [Option](#option)[] | - |
|
||||
| placeholder | 输入框占位文本 | string | '请选择' |
|
||||
| popupClassName | 自定义浮层类名 | string | - |
|
||||
| popupStyle | 自定义浮层样式 | object | {} |
|
||||
| popupPlacement | 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` | Enum | `bottomLeft` |
|
||||
| popupVisible | 控制浮层显隐 | boolean | - |
|
||||
| showSearch | 在选择框中显示搜索框 | boolean \| [object](#showsearch) | false |
|
||||
| size | 输入框大小,可选 `large` `default` `small` | string | `default` |
|
||||
| suffixIcon | 自定义的选择框后缀图标 | string \| VNode \| slot | - |
|
||||
| value(v-model) | 指定选中项 | string\[] \| number\[] | - |
|
||||
| 参数 | 说明 | 类型 | 默认值 | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| allowClear | 是否支持清除 | boolean | true | |
|
||||
| autofocus | 自动获取焦点 | boolean | false | |
|
||||
| changeOnSelect | 当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 | boolean | false | |
|
||||
| defaultValue | 默认的选中项 | string\[] \| number\[] | \[] | |
|
||||
| disabled | 禁用 | boolean | false | |
|
||||
| displayRender | 选择后展示的渲染函数,可使用 #displayRender="{labels, selectedOptions}" | `({labels, selectedOptions}) => VNode` | `labels => labels.join(' / ')` | |
|
||||
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | 'click' | |
|
||||
| fieldNames | 自定义 options 中 label name children 的字段 | object | `{ label: 'label', value: 'value', children: 'children' }` | |
|
||||
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | () => document.body | |
|
||||
| loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | `(selectedOptions) => void` | - | |
|
||||
| notFoundContent | 当下拉列表为空时显示的内容 | string \| slot | 'Not Found' | |
|
||||
| options | 可选项数据源 | [Option](#option)[] | - | |
|
||||
| placeholder | 输入框占位文本 | string | '请选择' | |
|
||||
| showSearch | 在选择框中显示搜索框 | boolean \| [object](#showsearch) | false | |
|
||||
| size | 输入框大小,可选 `large` `default` `small` | string | `default` | |
|
||||
| suffixIcon | 自定义的选择框后缀图标 | string \| VNode \| slot | - | |
|
||||
| value(v-model) | 指定选中项 | string\[] \| number\[] | - | |
|
||||
| expandIcon | 自定义次级菜单展开图标 | slot | - | 3.0 |
|
||||
| maxTagCount | 最多显示多少个 tag,响应式模式会对性能产生损耗 | number \| `responsive` | - | 3.0 |
|
||||
| maxTagPlaceholder | 隐藏 tag 时显示的内容 | v-slot \| function(omittedValues) | - | 3.0 |
|
||||
| dropdownClassName | 自定义浮层类名 | string | - | 3.0 |
|
||||
| dropdownStyle | 自定义浮层样式 | CSSProperties | {} | 3.0 |
|
||||
| open | 控制浮层显隐 | boolean | - | 3.0 |
|
||||
| placement | 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | 3.0 |
|
||||
| tagRender | 自定义 tag 内容,多选时生效 | (props) => ReactNode | - | 3.0 |
|
||||
| multiple | 支持多选节点 | boolean | - | 3.0 |
|
||||
| searchValue | 设置搜索的值,需要与 `showSearch` 配合使用 | string | - | 3.0 |
|
||||
|
||||
### showSearch
|
||||
|
||||
|
|
@ -58,18 +64,18 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
|
|||
|
||||
### 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| ------------------ | ------------------- | ---------------------------------- | ---- | ----- |
|
||||
| change | 选择完成后的回调 | `(value, selectedOptions) => void` | - | |
|
||||
| popupVisibleChange | 显示/隐藏浮层的回调 | `(value) => void` | - | |
|
||||
| search | 输入框变化时的回调 | `(value) => void` | - | 1.5.4 |
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| --------------------- | ---------------------- | ---------------------------------- | ---- | --- |
|
||||
| change | 选择完成后的回调 | `(value, selectedOptions) => void` | - | |
|
||||
| dropdownVisibleChange | 显示/隐藏浮层的回调 | `(value) => void` | - | 3.0 |
|
||||
| search | 监听搜索,返回输入的值 | `(value) => void` | - | 3.0 |
|
||||
|
||||
### Option
|
||||
|
||||
```ts
|
||||
interface Option {
|
||||
value: string | number;
|
||||
label?: VNode;
|
||||
label?: any;
|
||||
disabled?: boolean;
|
||||
children?: Option[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,169 +1,38 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
@import '../../input/style/mixin';
|
||||
@import '../../checkbox/style/mixin';
|
||||
|
||||
@cascader-prefix-cls: ~'@{ant-prefix}-cascader';
|
||||
|
||||
.antCheckboxFn(@checkbox-prefix-cls: ~'@{cascader-prefix-cls}-checkbox');
|
||||
|
||||
.@{cascader-prefix-cls} {
|
||||
.reset-component();
|
||||
width: 184px;
|
||||
|
||||
&-input.@{ant-prefix}-input {
|
||||
// Keep it static for https://github.com/ant-design/ant-design/issues/16738
|
||||
position: static;
|
||||
width: 100%;
|
||||
// https://github.com/ant-design/ant-design/issues/17582
|
||||
padding-right: 24px;
|
||||
// Add important to fix https://github.com/ant-design/ant-design/issues/5078
|
||||
// because input.less will compile after cascader.less
|
||||
background-color: transparent !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-picker-show-search &-input.@{ant-prefix}-input {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&-picker {
|
||||
.reset-component();
|
||||
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
background-color: @cascader-bg;
|
||||
border-radius: @border-radius-base;
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
|
||||
&-with-value &-label {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
&-disabled {
|
||||
color: @disabled-color;
|
||||
background: @input-disabled-bg;
|
||||
cursor: not-allowed;
|
||||
.@{cascader-prefix-cls}-input {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus .@{cascader-prefix-cls}-input {
|
||||
.active();
|
||||
}
|
||||
|
||||
&-show-search&-focused {
|
||||
color: @disabled-color;
|
||||
}
|
||||
|
||||
&-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
padding: 0 20px 0 @control-padding-horizontal;
|
||||
overflow: hidden;
|
||||
line-height: 20px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&-clear {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: @control-padding-horizontal;
|
||||
z-index: 2;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-top: -6px;
|
||||
color: @disabled-color;
|
||||
font-size: @font-size-sm;
|
||||
line-height: 12px;
|
||||
background: @component-background;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
transition: color 0.3s ease, opacity 0.15s ease;
|
||||
&:hover {
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover &-clear {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// arrow
|
||||
&-arrow {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: @control-padding-horizontal;
|
||||
z-index: 1;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-top: -6px;
|
||||
color: @disabled-color;
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
transition: transform 0.2s;
|
||||
&&-expand {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/ant-design/ant-design/pull/12407#issuecomment-424657810
|
||||
&-picker-label:hover + &-input {
|
||||
.hover();
|
||||
}
|
||||
|
||||
&-picker-small &-picker-clear,
|
||||
&-picker-small &-picker-arrow {
|
||||
right: @control-padding-horizontal-sm;
|
||||
&-checkbox {
|
||||
top: 0;
|
||||
margin-right: @padding-xs;
|
||||
}
|
||||
|
||||
&-menus {
|
||||
position: absolute;
|
||||
z-index: @zindex-dropdown;
|
||||
font-size: @cascader-dropdown-font-size;
|
||||
white-space: nowrap;
|
||||
background: @cascader-menu-bg;
|
||||
border-radius: @border-radius-base;
|
||||
box-shadow: @box-shadow-base;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: flex-start;
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
&-empty,
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
&.slide-up-enter.slide-up-enter-active&-placement-bottomLeft,
|
||||
&.slide-up-appear.slide-up-appear-active&-placement-bottomLeft {
|
||||
animation-name: antSlideUpIn;
|
||||
}
|
||||
|
||||
&.slide-up-enter.slide-up-enter-active&-placement-topLeft,
|
||||
&.slide-up-appear.slide-up-appear-active&-placement-topLeft {
|
||||
animation-name: antSlideDownIn;
|
||||
}
|
||||
|
||||
&.slide-up-leave.slide-up-leave-active&-placement-bottomLeft {
|
||||
animation-name: antSlideUpOut;
|
||||
}
|
||||
|
||||
&.slide-up-leave.slide-up-leave-active&-placement-topLeft {
|
||||
animation-name: antSlideDownOut;
|
||||
&.@{cascader-prefix-cls}-menu-empty {
|
||||
.@{cascader-prefix-cls}-menu {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-menu {
|
||||
display: inline-block;
|
||||
min-width: 111px;
|
||||
height: 180px;
|
||||
margin: 0;
|
||||
margin: -@dropdown-edge-child-vertical-padding 0;
|
||||
padding: @cascader-dropdown-edge-child-vertical-padding 0;
|
||||
overflow: auto;
|
||||
vertical-align: top;
|
||||
|
|
@ -171,60 +40,65 @@
|
|||
border-right: @border-width-base @border-style-base @cascader-menu-border-color-split;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar; // https://github.com/ant-design/ant-design/issues/11857
|
||||
|
||||
&:first-child {
|
||||
border-radius: @border-radius-base 0 0 @border-radius-base;
|
||||
}
|
||||
&:last-child {
|
||||
margin-right: -1px;
|
||||
border-right-color: transparent;
|
||||
border-radius: 0 @border-radius-base @border-radius-base 0;
|
||||
}
|
||||
&:only-child {
|
||||
border-radius: @border-radius-base;
|
||||
}
|
||||
}
|
||||
&-menu-item {
|
||||
padding: @cascader-dropdown-vertical-padding @control-padding-horizontal;
|
||||
line-height: @cascader-dropdown-line-height;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
&:hover {
|
||||
background: @item-hover-bg;
|
||||
}
|
||||
&-disabled {
|
||||
color: @disabled-color;
|
||||
cursor: not-allowed;
|
||||
&:hover {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
&-active:not(&-disabled) {
|
||||
&,
|
||||
&:hover {
|
||||
font-weight: @select-item-selected-font-weight;
|
||||
background-color: @cascader-item-selected-bg;
|
||||
}
|
||||
}
|
||||
&-expand {
|
||||
position: relative;
|
||||
padding-right: 24px;
|
||||
}
|
||||
&-item {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
padding: @cascader-dropdown-vertical-padding @control-padding-horizontal;
|
||||
overflow: hidden;
|
||||
line-height: @cascader-dropdown-line-height;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&-expand &-expand-icon,
|
||||
&-loading-icon {
|
||||
.iconfont-size-under-12px(10px);
|
||||
&:hover {
|
||||
background: @item-hover-bg;
|
||||
}
|
||||
|
||||
position: absolute;
|
||||
right: @control-padding-horizontal;
|
||||
color: @text-color-secondary;
|
||||
.@{cascader-prefix-cls}-menu-item-disabled& {
|
||||
&-disabled {
|
||||
color: @disabled-color;
|
||||
}
|
||||
}
|
||||
cursor: not-allowed;
|
||||
|
||||
& &-keyword {
|
||||
color: @highlight-color;
|
||||
&:hover {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.@{cascader-prefix-cls}-menu-empty & {
|
||||
color: @disabled-color;
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&-active:not(&-disabled) {
|
||||
&,
|
||||
&:hover {
|
||||
font-weight: @select-item-selected-font-weight;
|
||||
background-color: @cascader-item-selected-bg;
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
&-expand &-expand-icon,
|
||||
&-loading-icon {
|
||||
margin-left: @padding-xss;
|
||||
color: @text-color-secondary;
|
||||
font-size: 10px;
|
||||
|
||||
.@{cascader-prefix-cls}-menu-item-disabled& {
|
||||
color: @disabled-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-keyword {
|
||||
color: @highlight-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@import './rtl';
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ import './index.less';
|
|||
|
||||
// style dependencies
|
||||
import '../../empty/style';
|
||||
import '../../input/style';
|
||||
import '../../select/style';
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// We can not import reference of `./index` directly since it will make dead loop in less
|
||||
@import (reference) '../../style/themes/index';
|
||||
@cascader-prefix-cls: ~'@{ant-prefix}-cascader';
|
||||
|
||||
.@{cascader-prefix-cls}-rtl {
|
||||
.@{cascader-prefix-cls}-menu-item {
|
||||
&-expand-icon,
|
||||
&-loading-icon {
|
||||
margin-right: @padding-xss;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.@{cascader-prefix-cls}-checkbox {
|
||||
top: 0;
|
||||
margin-right: 0;
|
||||
margin-left: @padding-xs;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import { getTimeProps, Components } from '.';
|
|||
import { computed, defineComponent, nextTick, onMounted, ref } from 'vue';
|
||||
import useConfigInject from '../../_util/hooks/useConfigInject';
|
||||
import classNames from '../../_util/classNames';
|
||||
import type { CommonProps, RangePickerProps } from './props';
|
||||
import { commonProps, rangePickerProps } from './props';
|
||||
import type { PanelMode, RangeValue } from '../../vc-picker/interface';
|
||||
import type { RangePickerSharedProps } from '../../vc-picker/RangePicker';
|
||||
|
|
@ -41,7 +42,8 @@ export default function generateRangePicker<DateType, ExtraProps = {}>(
|
|||
'renderExtraFooter',
|
||||
// 'separator',
|
||||
],
|
||||
setup(props, { expose, slots, attrs, emit }) {
|
||||
setup(_props, { expose, slots, attrs, emit }) {
|
||||
const props = _props as unknown as CommonProps<DateType> & RangePickerProps<DateType>;
|
||||
const formItemContext = useInjectFormItemContext();
|
||||
devWarning(
|
||||
!attrs.getCalendarContainer,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { getTimeProps, Components } from '.';
|
|||
import { computed, defineComponent, nextTick, onMounted, ref } from 'vue';
|
||||
import useConfigInject from '../../_util/hooks/useConfigInject';
|
||||
import classNames from '../../_util/classNames';
|
||||
import type { CommonProps, DatePickerProps } from './props';
|
||||
import { commonProps, datePickerProps } from './props';
|
||||
|
||||
import devWarning from '../../vc-util/devWarning';
|
||||
|
|
@ -21,14 +22,15 @@ export default function generateSinglePicker<DateType, ExtraProps = {}>(
|
|||
extraProps: ExtraProps,
|
||||
) {
|
||||
function getPicker(picker?: PickerMode, displayName?: string) {
|
||||
const comProps = {
|
||||
...commonProps<DateType>(),
|
||||
...datePickerProps<DateType>(),
|
||||
...extraProps,
|
||||
};
|
||||
return defineComponent({
|
||||
name: displayName,
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
...commonProps<DateType>(),
|
||||
...datePickerProps<DateType>(),
|
||||
...extraProps,
|
||||
},
|
||||
props: comProps,
|
||||
slots: [
|
||||
'suffixIcon',
|
||||
// 'clearIcon',
|
||||
|
|
@ -41,7 +43,11 @@ export default function generateSinglePicker<DateType, ExtraProps = {}>(
|
|||
'renderExtraFooter',
|
||||
'monthCellRender',
|
||||
],
|
||||
setup(props, { slots, expose, attrs, emit }) {
|
||||
setup(_props, { slots, expose, attrs, emit }) {
|
||||
// 兼容 vue 3.2.7
|
||||
const props = _props as unknown as CommonProps<DateType> &
|
||||
DatePickerProps<DateType> &
|
||||
ExtraProps;
|
||||
const formItemContext = useInjectFormItemContext();
|
||||
devWarning(
|
||||
!(props.monthCellContentRender || slots.monthCellContentRender),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import type { SharedTimeProps } from '../../vc-picker/panels/TimePanel';
|
|||
import type { RangeDateRender, RangeInfo, RangeType } from '../../vc-picker/RangePicker';
|
||||
import type { VueNode } from '../../_util/type';
|
||||
|
||||
function commonProps<DateType>() {
|
||||
function commonProps<DateType = any>() {
|
||||
return {
|
||||
id: String,
|
||||
dropdownClassName: String,
|
||||
|
|
@ -138,7 +138,7 @@ export interface CommonProps<DateType> {
|
|||
valueFormat?: string;
|
||||
}
|
||||
|
||||
function datePickerProps<DateType>() {
|
||||
function datePickerProps<DateType = any>() {
|
||||
return {
|
||||
defaultPickerValue: { type: [String, Object] as PropType<DateType | string> },
|
||||
defaultValue: { type: [String, Object] as PropType<DateType | string> },
|
||||
|
|
|
|||
|
|
@ -41,17 +41,23 @@ exports[`renders ./components/empty/demo/config-provider.vue correctly 1`] = `
|
|||
<!---->
|
||||
</div>
|
||||
<h3>TreeSelect</h3>
|
||||
<div style="width: 200px;" class="ant-select ant-tree-select ant-select-single ant-select-show-arrow">
|
||||
<div style="width: 200px;" class="ant-select ant-tree-select ant-select-single ant-select-show-arrow" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"></span>
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder"><!----></span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
<h3>Cascader</h3>
|
||||
<!----><span class="ant-cascader-picker ant-cascader-picker-show-search" style="width: 200px;" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Please select" autocomplete="off" type="text" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div style="width: 200px;" class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder"><!----></span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
<h3>Transfer</h3>
|
||||
<div class="ant-transfer">
|
||||
<div class="ant-transfer-list">
|
||||
|
|
|
|||
|
|
@ -68,8 +68,14 @@ exports[`renders ./components/input-number/demo/addon.vue correctly 1`] = `
|
|||
<div class="ant-input-number-input-wrap"><input autocomplete="off" role="spinbutton" aria-valuenow="100" step="1" class="ant-input-number-input"></div>
|
||||
</div>
|
||||
<div class="ant-input-number-group-addon">
|
||||
<!----><span class="ant-cascader-picker" style="width: 150px;" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="cascader" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div style="width: 150px;" class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">cascader</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -79,8 +79,14 @@ exports[`renders ./components/input/demo/group.vue correctly 1`] = `
|
|||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
<!----><span class="ant-cascader-picker" style="width: 70%;" tabindex="0"><span class="ant-cascader-picker-label"></span><input placeholder="Select Address" autocomplete="off" type="text" readonly="" class="ant-input ant-cascader-input">
|
||||
<!----><span role="img" aria-label="down" class="anticon anticon-down ant-cascader-picker-arrow"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span></span></div>
|
||||
<div style="width: 70%;" class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Select Address</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div></span></div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/input/demo/password-input.vue correctly 1`] = `<span class="ant-input-affix-wrapper ant-input-password"><!----><input placeholder="input password" type="password" class="ant-input"><span class="ant-input-suffix"><!----><span tabindex="-1" role="img" aria-label="eye-invisible" class="anticon anticon-eye-invisible ant-input-password-icon"><svg focusable="false" class="" data-icon="eye-invisible" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"></path><path d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"></path></svg></span></span></span>`;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ exports[`renders ./components/layout/demo/fixed.vue correctly 1`] = `
|
|||
<li class="ant-menu-overflow-item ant-menu-item ant-menu-item-only-child" style="opacity: 1; order: 2;" role="menuitem" tabindex="-1" data-menu-id="3" aria-disabled="false">
|
||||
<!----><span class="ant-menu-title-content">nav 3</span>
|
||||
</li>
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<!---->
|
||||
<div class="ant-menu-submenu-title" tabindex="-1" data-menu-id="$$__vc-menu-more__key" aria-expanded="false" aria-haspopup="true" aria-controls="$$__vc-menu-more__key-popup" aria-disabled="false"><span class="ant-menu-title-content"><span role="img" aria-label="ellipsis" class="anticon anticon-ellipsis"><svg focusable="false" class="" data-icon="ellipsis" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"></path></svg></span></span><i class="ant-menu-submenu-arrow"></i></div>
|
||||
<!---->
|
||||
|
|
@ -317,7 +317,7 @@ exports[`renders ./components/layout/demo/top.vue correctly 1`] = `
|
|||
<li class="ant-menu-overflow-item ant-menu-item ant-menu-item-only-child" style="opacity: 1; order: 2;" role="menuitem" tabindex="-1" data-menu-id="3" aria-disabled="false">
|
||||
<!----><span class="ant-menu-title-content">nav 3</span>
|
||||
</li>
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<!---->
|
||||
<div class="ant-menu-submenu-title" tabindex="-1" data-menu-id="$$__vc-menu-more__key" aria-expanded="false" aria-haspopup="true" aria-controls="$$__vc-menu-more__key-popup" aria-disabled="false"><span class="ant-menu-title-content"><span role="img" aria-label="ellipsis" class="anticon anticon-ellipsis"><svg focusable="false" class="" data-icon="ellipsis" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"></path></svg></span></span><i class="ant-menu-submenu-arrow"></i></div>
|
||||
<!---->
|
||||
|
|
@ -356,7 +356,7 @@ exports[`renders ./components/layout/demo/top-side.vue correctly 1`] = `
|
|||
<li class="ant-menu-overflow-item ant-menu-item ant-menu-item-only-child" style="opacity: 1; order: 2;" role="menuitem" tabindex="-1" data-menu-id="3" aria-disabled="false">
|
||||
<!----><span class="ant-menu-title-content">nav 3</span>
|
||||
</li>
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<!---->
|
||||
<div class="ant-menu-submenu-title" tabindex="-1" data-menu-id="$$__vc-menu-more__key" aria-expanded="false" aria-haspopup="true" aria-controls="$$__vc-menu-more__key-popup" aria-disabled="false"><span class="ant-menu-title-content"><span role="img" aria-label="ellipsis" class="anticon anticon-ellipsis"><svg focusable="false" class="" data-icon="ellipsis" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"></path></svg></span></span><i class="ant-menu-submenu-arrow"></i></div>
|
||||
<!---->
|
||||
|
|
@ -486,7 +486,7 @@ exports[`renders ./components/layout/demo/top-side-2.vue correctly 1`] = `
|
|||
<li class="ant-menu-overflow-item ant-menu-item ant-menu-item-only-child" style="opacity: 1; order: 2;" role="menuitem" tabindex="-1" data-menu-id="3" aria-disabled="false">
|
||||
<!----><span class="ant-menu-title-content">nav 3</span>
|
||||
</li>
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<!---->
|
||||
<div class="ant-menu-submenu-title" tabindex="-1" data-menu-id="$$__vc-menu-more__key" aria-expanded="false" aria-haspopup="true" aria-controls="$$__vc-menu-more__key-popup" aria-disabled="false"><span class="ant-menu-title-content"><span role="img" aria-label="ellipsis" class="anticon anticon-ellipsis"><svg focusable="false" class="" data-icon="ellipsis" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"></path></svg></span></span><i class="ant-menu-submenu-arrow"></i></div>
|
||||
<!---->
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ exports[`renders ./components/menu/demo/horizontal.vue correctly 1`] = `
|
|||
<li class="ant-menu-overflow-item ant-menu-item ant-menu-item-only-child" style="opacity: 1; order: 3;" role="menuitem" tabindex="-1" data-menu-id="alipay" aria-disabled="false">
|
||||
<!----><span class="ant-menu-title-content"><a href="https://antdv.com" target="_blank" rel="noopener noreferrer"> Navigation Four - Link </a></span>
|
||||
</li>
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<li class="ant-menu-overflow-item ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true" role="none" data-submenu-id="$$__vc-menu-more__key">
|
||||
<!---->
|
||||
<div class="ant-menu-submenu-title" tabindex="-1" data-menu-id="$$__vc-menu-more__key" aria-expanded="false" aria-haspopup="true" aria-controls="$$__vc-menu-more__key-popup" aria-disabled="false"><span class="ant-menu-title-content"><span role="img" aria-label="ellipsis" class="anticon anticon-ellipsis"><svg focusable="false" class="" data-icon="ellipsis" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"></path></svg></span></span><i class="ant-menu-submenu-arrow"></i></div>
|
||||
<!---->
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ exports[`renders ./components/select/demo/option-label-prop.vue correctly 1`] =
|
|||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
<div class="ant-select-selection-overflow">
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="China"><span class="ant-select-selection-item-content">China</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item"><span class="ant-select-selection-item-content"><span role="img" aria-label="China">🇨🇳</span> China (中国) </span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<!---->
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
|
|
@ -271,6 +271,31 @@ exports[`renders ./components/select/demo/option-label-prop.vue correctly 1`] =
|
|||
<div class="ant-space-item"><span>Note: v-slot:option support from v2.2.5</span></div>
|
||||
<!---->
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class="ant-space ant-space-vertical" style="width: 100%;">
|
||||
<div class="ant-space-item" style="margin-bottom: 8px;">
|
||||
<div style="width: 100%;" class="ant-select ant-select-multiple ant-select-show-search">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
<div class="ant-select-selection-overflow">
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span><span class="ant-tag" style="margin-right: 3px;">China (中国) <span role="img" aria-label="china">🇨🇳</span><span tabindex="-1" role="img" aria-label="close" class="anticon anticon-close ant-tag-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<!---->
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
<div class="ant-space-item"><span>Note: v-slot:tagRender support from v3.0</span></div>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/select/demo/responsive.vue correctly 1`] = `
|
||||
|
|
@ -300,7 +325,7 @@ exports[`renders ./components/select/demo/responsive.vue correctly 1`] = `
|
|||
<div class="ant-select-selection-overflow">
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label: a10"><span class="ant-select-selection-item-content">Long Label: a10</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label: c12"><span class="ant-select-selection-item-content">Long Label: c12</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item-rest" style="opacity: 1;"><span class="ant-select-selection-item" title="+ 3 ..."><span class="ant-select-selection-item-content">+ 3 ...</span>
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-rest" style="opacity: 1;"><span class="ant-select-selection-item"><span class="ant-select-selection-item-content"><span style="color: red;">+ 3 ...</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
|
|
@ -324,7 +349,7 @@ exports[`renders ./components/select/demo/responsive.vue correctly 1`] = `
|
|||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
<div class="ant-select-selection-overflow">
|
||||
<div class="ant-select-selection-overflow-item-rest" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true"><span class="ant-select-selection-item" title="+ 4 ..."><span class="ant-select-selection-item-content">+ 4 ...</span>
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-rest" style="opacity: 0; height: 0px; overflow-y: hidden; order: 9007199254740991; pointer-events: none; position: absolute;" aria-hidden="true"><span class="ant-select-selection-item" title="+ 4 ..."><span class="ant-select-selection-item-content">+ 4 ...</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1; order: 0;">
|
||||
|
|
@ -361,11 +386,11 @@ exports[`renders ./components/select/demo/responsive.vue correctly 1`] = `
|
|||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
<div class="ant-select-selection-overflow">
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label..."><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label..."><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label..."><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label..."><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label..."><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label: a10"><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label: c12"><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label: h17"><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label: j19"><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Long Label: k20"><span class="ant-select-selection-item-content">Long Label...</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<!---->
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
|
|
@ -422,7 +447,7 @@ exports[`renders ./components/select/demo/select-users.vue correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/select/demo/size.vue correctly 1`] = `
|
||||
<div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="large"><span class="ant-radio-button-inner"></span></span><span>Large</span></label><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="default"><span class="ant-radio-button-inner"></span></span><span>Default</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="small"><span class="ant-radio-button-inner"></span></span><span>Small</span></label></div>
|
||||
<div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="large"><span class="ant-radio-button-inner"></span></span><span>Large</span></label><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="middle"><span class="ant-radio-button-inner"></span></span><span>Middle</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="small"><span class="ant-radio-button-inner"></span></span><span>Small</span></label></div>
|
||||
<br>
|
||||
<br>
|
||||
<div class="ant-space ant-space-vertical">
|
||||
|
|
|
|||
|
|
@ -10,10 +10,13 @@ title:
|
|||
|
||||
使用 `optionLabelProp` 指定回填到选择框的 `Option` 属性。
|
||||
|
||||
或者使用 `tagRender` 插槽自定义渲染节点
|
||||
|
||||
## en-US
|
||||
|
||||
Spacified the prop name of Option which will be rendered in select box.
|
||||
|
||||
or use `tagRender` slot for custom rendering of tags.
|
||||
</docs>
|
||||
|
||||
<template>
|
||||
|
|
@ -23,7 +26,7 @@ Spacified the prop name of Option which will be rendered in select box.
|
|||
mode="multiple"
|
||||
style="width: 100%"
|
||||
placeholder="select one country"
|
||||
option-label-prop="label"
|
||||
option-label-prop="children"
|
||||
>
|
||||
<a-select-option value="china" label="China">
|
||||
<span role="img" aria-label="China">🇨🇳</span>
|
||||
|
|
@ -58,6 +61,29 @@ Spacified the prop name of Option which will be rendered in select box.
|
|||
</a-select>
|
||||
<span>Note: v-slot:option support from v2.2.5</span>
|
||||
</a-space>
|
||||
<br />
|
||||
<br />
|
||||
<a-space direction="vertical" style="width: 100%">
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
mode="multiple"
|
||||
style="width: 100%"
|
||||
placeholder="select one country"
|
||||
:options="options"
|
||||
>
|
||||
<template #option="{ value: val, label, icon }">
|
||||
<span role="img" :aria-label="val">{{ icon }}</span>
|
||||
{{ label }}
|
||||
</template>
|
||||
<template #tagRender="{ value: val, label, closable, onClose, option }">
|
||||
<a-tag :closable="closable" style="margin-right: 3px" @close="onClose">
|
||||
{{ label }}
|
||||
<span role="img" :aria-label="val">{{ option.icon }}</span>
|
||||
</a-tag>
|
||||
</template>
|
||||
</a-select>
|
||||
<span>Note: v-slot:tagRender support from v3.0</span>
|
||||
</a-space>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
|
|
@ -91,7 +117,6 @@ export default defineComponent({
|
|||
watch(value, val => {
|
||||
console.log(`selected:`, val);
|
||||
});
|
||||
|
||||
return {
|
||||
options,
|
||||
value,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,11 @@ Set a number and automatically fold after exceeding.
|
|||
placeholder="Select Item..."
|
||||
:max-tag-count="maxTagCount"
|
||||
:options="options"
|
||||
></a-select>
|
||||
>
|
||||
<template #maxTagPlaceholder="omittedValues">
|
||||
<span style="color: red">+ {{ omittedValues.length }} ...</span>
|
||||
</template>
|
||||
</a-select>
|
||||
<h2>maxTagCount: responsive</h2>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ The height of the input field for the select defaults to 32px. If size is set to
|
|||
<template>
|
||||
<a-radio-group v-model:value="size">
|
||||
<a-radio-button value="large">Large</a-radio-button>
|
||||
<a-radio-button value="default">Default</a-radio-button>
|
||||
<a-radio-button value="middle">Middle</a-radio-button>
|
||||
<a-radio-button value="small">Small</a-radio-button>
|
||||
</a-radio-group>
|
||||
<br />
|
||||
|
|
@ -61,7 +61,7 @@ export default defineComponent({
|
|||
|
||||
return {
|
||||
popupScroll,
|
||||
size: ref<SelectProps['size']>('default'),
|
||||
size: ref<SelectProps['size']>('middle'),
|
||||
value1: ref('a1'),
|
||||
value2: ref(['a1', 'b2']),
|
||||
value3: ref(['a1', 'b2']),
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ Select component to select value from options.
|
|||
| clearIcon | The custom clear icon | VNode \| slot | - | |
|
||||
| menuItemSelectedIcon | The custom menuItemSelected icon | VNode \| slot | - | |
|
||||
| tokenSeparators | Separator used to tokenize on tag/multiple mode | string\[] | | |
|
||||
| tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | slot \| (props) => any | - | |
|
||||
| value(v-model) | Current selected option. | string\|number\|string\[]\|number\[] | - | |
|
||||
| options | Data of the selectOption, manual construction work is no longer needed if this property has been set | array<{value, label, [disabled, key, title]}> | \[] | |
|
||||
| option | custom render option by slot | v-slot:option="{value, label, [disabled, key, title]}" | - | 2.2.5 |
|
||||
|
|
|
|||
|
|
@ -1,21 +1,23 @@
|
|||
import type { App, PropType, Plugin, ExtractPropTypes } from 'vue';
|
||||
import { computed, defineComponent, ref } from 'vue';
|
||||
import classNames from '../_util/classNames';
|
||||
import type { BaseSelectRef } from '../vc-select';
|
||||
import RcSelect, { selectProps as vcSelectProps, Option, OptGroup } from '../vc-select';
|
||||
import type { OptionProps as OptionPropsType } from '../vc-select/Option';
|
||||
import type { BaseOptionType, DefaultOptionType } from '../vc-select/Select';
|
||||
import type { OptionProps } from '../vc-select/Option';
|
||||
import getIcons from './utils/iconUtil';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { tuple } from '../_util/type';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
import omit from '../_util/omit';
|
||||
import { useInjectFormItemContext } from '../form/FormItemContext';
|
||||
import { getTransitionName } from '../_util/transition';
|
||||
import type { SizeType } from '../config-provider';
|
||||
import { initDefaultProps } from '../_util/props-util';
|
||||
|
||||
type RawValue = string | number;
|
||||
|
||||
export type OptionProps = OptionPropsType;
|
||||
|
||||
export type OptionType = typeof Option;
|
||||
export type { OptionProps, BaseSelectRef as RefSelectProps, BaseOptionType, DefaultOptionType };
|
||||
|
||||
export interface LabeledValue {
|
||||
key?: string;
|
||||
|
|
@ -35,23 +37,28 @@ export const selectProps = () => ({
|
|||
notFoundContent: PropTypes.any,
|
||||
suffixIcon: PropTypes.any,
|
||||
itemIcon: PropTypes.any,
|
||||
size: PropTypes.oneOf(tuple('small', 'middle', 'large', 'default')),
|
||||
mode: PropTypes.oneOf(tuple('multiple', 'tags', 'SECRET_COMBOBOX_MODE_DO_NOT_USE')),
|
||||
bordered: PropTypes.looseBool.def(true),
|
||||
transitionName: PropTypes.string,
|
||||
choiceTransitionName: PropTypes.string.def(''),
|
||||
size: String as PropType<SizeType>,
|
||||
mode: String as PropType<'multiple' | 'tags' | 'SECRET_COMBOBOX_MODE_DO_NOT_USE'>,
|
||||
bordered: { type: Boolean, default: true },
|
||||
transitionName: String,
|
||||
choiceTransitionName: { type: String, default: '' },
|
||||
'onUpdate:value': Function as PropType<(val: SelectValue) => void>,
|
||||
});
|
||||
|
||||
export type SelectProps = Partial<ExtractPropTypes<ReturnType<typeof selectProps>>>;
|
||||
|
||||
const SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
|
||||
const Select = defineComponent({
|
||||
name: 'ASelect',
|
||||
Option,
|
||||
OptGroup,
|
||||
inheritAttrs: false,
|
||||
props: selectProps(),
|
||||
SECRET_COMBOBOX_MODE_DO_NOT_USE: 'SECRET_COMBOBOX_MODE_DO_NOT_USE',
|
||||
emits: ['change', 'update:value', 'blur'],
|
||||
props: initDefaultProps(selectProps(), {
|
||||
listHeight: 256,
|
||||
listItemHeight: 24,
|
||||
}),
|
||||
SECRET_COMBOBOX_MODE_DO_NOT_USE,
|
||||
// emits: ['change', 'update:value', 'blur'],
|
||||
slots: [
|
||||
'notFoundContent',
|
||||
'suffixIcon',
|
||||
|
|
@ -61,20 +68,22 @@ const Select = defineComponent({
|
|||
'dropdownRender',
|
||||
'option',
|
||||
'placeholder',
|
||||
'tagRender',
|
||||
'maxTagPlaceholder',
|
||||
],
|
||||
setup(props, { attrs, emit, slots, expose }) {
|
||||
const selectRef = ref();
|
||||
const selectRef = ref<BaseSelectRef>();
|
||||
const formItemContext = useInjectFormItemContext();
|
||||
const focus = () => {
|
||||
if (selectRef.value) {
|
||||
selectRef.value.focus();
|
||||
}
|
||||
selectRef.value?.focus();
|
||||
};
|
||||
|
||||
const blur = () => {
|
||||
if (selectRef.value) {
|
||||
selectRef.value.blur();
|
||||
}
|
||||
selectRef.value?.blur();
|
||||
};
|
||||
|
||||
const scrollTo: BaseSelectRef['scrollTo'] = arg => {
|
||||
selectRef.value?.scrollTo(arg);
|
||||
};
|
||||
|
||||
const mode = computed(() => {
|
||||
|
|
@ -84,7 +93,7 @@ const Select = defineComponent({
|
|||
return undefined;
|
||||
}
|
||||
|
||||
if (mode === Select.SECRET_COMBOBOX_MODE_DO_NOT_USE) {
|
||||
if (mode === SECRET_COMBOBOX_MODE_DO_NOT_USE) {
|
||||
return 'combobox';
|
||||
}
|
||||
|
||||
|
|
@ -103,19 +112,21 @@ const Select = defineComponent({
|
|||
[`${prefixCls.value}-borderless`]: !props.bordered,
|
||||
}),
|
||||
);
|
||||
const triggerChange = (...args: any[]) => {
|
||||
const triggerChange: SelectProps['onChange'] = (...args) => {
|
||||
emit('update:value', args[0]);
|
||||
emit('change', ...args);
|
||||
formItemContext.onFieldChange();
|
||||
};
|
||||
const handleBlur = (e: InputEvent) => {
|
||||
const handleBlur: SelectProps['onBlur'] = e => {
|
||||
emit('blur', e);
|
||||
formItemContext.onFieldBlur();
|
||||
};
|
||||
expose({
|
||||
blur,
|
||||
focus,
|
||||
scrollTo,
|
||||
});
|
||||
const isMultiple = computed(() => mode.value === 'multiple' || mode.value === 'tags');
|
||||
return () => {
|
||||
const {
|
||||
notFoundContent,
|
||||
|
|
@ -131,8 +142,6 @@ const Select = defineComponent({
|
|||
|
||||
const { renderEmpty, getPopupContainer: getContextPopupContainer } = configProvider;
|
||||
|
||||
const isMultiple = mode.value === 'multiple' || mode.value === 'tags';
|
||||
|
||||
// ===================== Empty =====================
|
||||
let mergedNotFound: any;
|
||||
if (notFoundContent !== undefined) {
|
||||
|
|
@ -149,7 +158,7 @@ const Select = defineComponent({
|
|||
const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons(
|
||||
{
|
||||
...props,
|
||||
multiple: isMultiple,
|
||||
multiple: isMultiple.value,
|
||||
prefixCls: prefixCls.value,
|
||||
},
|
||||
slots,
|
||||
|
|
@ -195,9 +204,10 @@ const Select = defineComponent({
|
|||
dropdownRender={selectProps.dropdownRender || slots.dropdownRender}
|
||||
v-slots={{ option: slots.option }}
|
||||
transitionName={transitionName.value}
|
||||
>
|
||||
{slots.default?.()}
|
||||
</RcSelect>
|
||||
children={slots.default?.()}
|
||||
tagRender={props.tagRender || slots.tagRender}
|
||||
maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder}
|
||||
></RcSelect>
|
||||
);
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
|
|||
| clearIcon | 自定义的多选框清空图标 | VNode \| slot | - | |
|
||||
| menuItemSelectedIcon | 自定义当前选中的条目图标 | VNode \| slot | - | |
|
||||
| tokenSeparators | 在 tags 和 multiple 模式下自动分词的分隔符 | string\[] | | |
|
||||
| tagRender | 自定义 tag 内容 render,仅在 `mode` 为 `multiple` 或 `tags` 时生效 | slot \| (props) => any | - | 3.0 |
|
||||
| value(v-model) | 指定当前选中的条目 | string\|string\[]\|number\|number\[] | - | |
|
||||
| options | options 数据,如果设置则不需要手动构造 selectOption 节点 | array<{value, label, [disabled, key, title]}> | \[] | |
|
||||
| option | 通过 option 插槽,自定义节点 | v-slot:option="{value, label, [disabled, key, title]}" | - | 2.2.5 |
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
@import '../../input/style/mixin';
|
||||
|
||||
@import './single';
|
||||
@import './multiple';
|
||||
|
||||
|
|
@ -59,6 +58,7 @@
|
|||
|
||||
&::-webkit-search-cancel-button {
|
||||
display: none;
|
||||
/* stylelint-disable-next-line property-no-vendor-prefix */
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
}
|
||||
|
|
@ -83,6 +83,7 @@
|
|||
&-selection-item {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
|
|
@ -117,7 +118,7 @@
|
|||
&-arrow {
|
||||
.iconfont-mixin();
|
||||
position: absolute;
|
||||
top: 53%;
|
||||
top: 50%;
|
||||
right: @control-padding-horizontal - 1px;
|
||||
width: @font-size-sm;
|
||||
height: @font-size-sm;
|
||||
|
|
@ -167,9 +168,11 @@
|
|||
opacity: 0;
|
||||
transition: color 0.3s ease, opacity 0.15s ease;
|
||||
text-rendering: auto;
|
||||
|
||||
&::before {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: @text-color-secondary;
|
||||
}
|
||||
|
|
@ -286,6 +289,9 @@
|
|||
}
|
||||
|
||||
&-disabled {
|
||||
&.@{select-prefix-cls}-item-option-selected {
|
||||
background-color: @select-multiple-disabled-background;
|
||||
}
|
||||
color: @disabled-color;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@import './index';
|
||||
@import (reference) '../../style/themes/index';
|
||||
@select-prefix-cls: ~'@{ant-prefix}-select';
|
||||
|
||||
@select-overflow-prefix-cls: ~'@{select-prefix-cls}-selection-overflow';
|
||||
@select-multiple-item-border-width: 1px;
|
||||
|
|
@ -128,8 +129,6 @@
|
|||
.@{select-prefix-cls}-selection-search {
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
margin-top: @select-multiple-item-spacing-half;
|
||||
margin-bottom: @select-multiple-item-spacing-half;
|
||||
margin-inline-start: @input-padding-horizontal-base - @input-padding-vertical-base;
|
||||
|
||||
&-input,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@import './index';
|
||||
@import (reference) '../../style/themes/index';
|
||||
@select-prefix-cls: ~'@{ant-prefix}-select';
|
||||
|
||||
@selection-item-padding: ceil(@font-size-base * 1.25);
|
||||
|
||||
|
|
@ -39,14 +40,15 @@
|
|||
}
|
||||
|
||||
.@{select-prefix-cls}-selection-placeholder {
|
||||
transition: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// For common baseline align
|
||||
&::after,
|
||||
// For '' value baseline align
|
||||
/* For '' value baseline align */
|
||||
.@{select-prefix-cls}-selection-item::after,
|
||||
// For undefined value baseline align
|
||||
/* For undefined value baseline align */
|
||||
.@{select-prefix-cls}-selection-placeholder::after {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
|
|
|
|||
|
|
@ -940,19 +940,24 @@ exports[`renders ./components/transfer/demo/tree-transfer.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">0-1</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">0-1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-1-0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-1-0</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-1-0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-1-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-1-1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-1-1</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-1-1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-1-1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-3" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-3</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="0-3" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-3</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/tree-select/demo/async.vue correctly 1`] = `
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-single ant-select-show-arrow">
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-single ant-select-show-arrow" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"></span>
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
|
|
@ -12,10 +12,10 @@ exports[`renders ./components/tree-select/demo/async.vue correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/basic.vue correctly 1`] = `
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search">
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" type="search"></span>
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
|
|
@ -23,7 +23,7 @@ exports[`renders ./components/tree-select/demo/basic.vue correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/checkable.vue correctly 1`] = `
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-multiple ant-select-allow-clear ant-select-show-search">
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-multiple ant-select-allow-clear ant-select-show-search" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
|
|
@ -31,7 +31,27 @@ exports[`renders ./components/tree-select/demo/checkable.vue correctly 1`] = `
|
|||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="Node1"><span class="ant-select-selection-item-content">Node1</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<!---->
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!----><span class="ant-select-clear" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close-circle" class="anticon anticon-close-circle"><svg focusable="false" class="" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg></span></span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/custom-tag-render.vue correctly 1`] = `
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-multiple ant-select-allow-clear ant-select-show-search" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
<div class="ant-select-selection-overflow">
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span><span class="ant-tag ant-tag-pink" style="margin-right: 3px;">parent 1 <span tabindex="-1" role="img" aria-label="close" class="anticon anticon-close ant-tag-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span><span class="ant-tag ant-tag-orange" style="margin-right: 3px;">parent 1-0 <span tabindex="-1" role="img" aria-label="close" class="anticon anticon-close ant-tag-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span><span class="ant-tag ant-tag-green" style="margin-right: 3px;">my leaf <span tabindex="-1" role="img" aria-label="close" class="anticon anticon-close ant-tag-close-icon"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<!---->
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
|
|
@ -41,10 +61,10 @@ exports[`renders ./components/tree-select/demo/checkable.vue correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/highlight.vue correctly 1`] = `
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search">
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" type="search"></span>
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
|
|
@ -52,14 +72,14 @@ exports[`renders ./components/tree-select/demo/highlight.vue correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/multiple.vue correctly 1`] = `
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-multiple ant-select-allow-clear ant-select-show-search" multiple="true">
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-multiple ant-select-allow-clear ant-select-show-search" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
<div class="ant-select-selection-overflow">
|
||||
<!---->
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
</div>
|
||||
</div><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div>
|
||||
|
|
@ -71,10 +91,10 @@ exports[`renders ./components/tree-select/demo/multiple.vue correctly 1`] = `
|
|||
exports[`renders ./components/tree-select/demo/suffix.vue correctly 1`] = `
|
||||
<div class="ant-space ant-space-vertical" style="width: 100%;">
|
||||
<div class="ant-space-item" style="margin-bottom: 8px;">
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search">
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" type="search"></span>
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="smile" class="anticon anticon-smile"><svg focusable="false" class="" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"></path></svg></span></span>
|
||||
<!---->
|
||||
|
|
@ -82,14 +102,14 @@ exports[`renders ./components/tree-select/demo/suffix.vue correctly 1`] = `
|
|||
</div>
|
||||
<!---->
|
||||
<div class="ant-space-item">
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-multiple ant-select-allow-clear ant-select-show-arrow ant-select-show-search" multiple="true">
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-multiple ant-select-allow-clear ant-select-show-arrow ant-select-show-search" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
<div class="ant-select-selection-overflow">
|
||||
<!---->
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
</div>
|
||||
</div><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="smile" class="anticon anticon-smile"><svg focusable="false" class="" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"></path></svg></span></span>
|
||||
|
|
@ -100,13 +120,46 @@ exports[`renders ./components/tree-select/demo/suffix.vue correctly 1`] = `
|
|||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/treeData.vue correctly 1`] = `
|
||||
<div style="width: 100%;" class="ant-select ant-tree-select ant-select-single ant-select-show-arrow">
|
||||
exports[`renders ./components/tree-select/demo/tree-line.vue correctly 1`] = `
|
||||
<div class="ant-space ant-space-vertical">
|
||||
<div class="ant-space-item" style="margin-bottom: 8px;"><button type="button" role="switch" aria-checked="true" class="ant-switch-checked ant-switch">
|
||||
<!----><span class="ant-switch-inner">treeLine</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
<div class="ant-space-item" style="margin-bottom: 8px;"><button type="button" role="switch" aria-checked="false" class="ant-switch">
|
||||
<!----><span class="ant-switch-inner">showLeafIcon</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
<div class="ant-space-item">
|
||||
<div style="width: 300px;" class="ant-select ant-tree-select ant-select-single ant-select-show-arrow" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tree-select/demo/virtual-scroll.vue correctly 1`] = `
|
||||
<div style="width: 100%;" height="233" class="ant-select ant-tree-select ant-select-multiple ant-select-show-search" customslots="[object Object]">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector">
|
||||
<div class="ant-select-selection-overflow">
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="0-0-0"><span class="ant-select-selection-item-content">0-0-0</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<div class="ant-select-selection-overflow-item" style="opacity: 1;"><span class="ant-select-selection-item" title="0-0-1"><span class="ant-select-selection-item-content">0-0-1</span><span class="ant-select-selection-item-remove" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="close" class="anticon anticon-close"><svg focusable="false" class="" data-icon="close" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg></span></span></span></div>
|
||||
<!---->
|
||||
<div class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" style="opacity: 1;">
|
||||
<div class="ant-select-selection-search" style="width: 0px;"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" readonly="" unselectable="on" type="search"><span class="ant-select-selection-search-mirror" aria-hidden="true"> </span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Please select</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ Multiple and checkable.
|
|||
/>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { TreeSelect } from 'ant-design-vue';
|
||||
import type { TreeSelectProps } from 'ant-design-vue';
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
import { TreeSelect } from 'ant-design-vue';
|
||||
const SHOW_PARENT = TreeSelect.SHOW_PARENT;
|
||||
|
||||
const treeData: TreeSelectProps['treeData'] = [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
<docs>
|
||||
---
|
||||
order: 24
|
||||
title:
|
||||
zh-CN: 自定义选择标签
|
||||
en-US: Custom Tag Render
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
允许自定义选择标签的样式。仅支持多选模式,单选可直接使用 `title` 插槽
|
||||
|
||||
## en-US
|
||||
|
||||
Allows for custom rendering of tags.
|
||||
|
||||
</docs>
|
||||
|
||||
<template>
|
||||
<a-tree-select
|
||||
v-model:value="value"
|
||||
show-search
|
||||
style="width: 100%"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="Please select"
|
||||
allow-clear
|
||||
multiple
|
||||
:show-checked-strategy="SHOW_ALL"
|
||||
tree-default-expand-all
|
||||
:tree-data="treeData"
|
||||
>
|
||||
<template #tagRender="{ label, closable, onClose, option }">
|
||||
<a-tag :closable="closable" :color="option.color" style="margin-right: 3px" @close="onClose">
|
||||
{{ label }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template #title="{ value: val, title }">
|
||||
<b v-if="val === 'parent 1-1'" style="color: #08c">{{ val }}</b>
|
||||
<template v-else>{{ title }}</template>
|
||||
</template>
|
||||
</a-tree-select>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { TreeSelectProps } from 'ant-design-vue';
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
import { TreeSelect } from 'ant-design-vue';
|
||||
const SHOW_ALL = TreeSelect.SHOW_ALL;
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const value = ref<string[]>(['parent 1', 'parent 1-0', 'leaf1']);
|
||||
const treeData = ref<TreeSelectProps['treeData']>([
|
||||
{
|
||||
title: 'parent 1',
|
||||
value: 'parent 1',
|
||||
color: 'pink',
|
||||
children: [
|
||||
{
|
||||
title: 'parent 1-0',
|
||||
value: 'parent 1-0',
|
||||
color: 'orange',
|
||||
children: [
|
||||
{
|
||||
title: 'my leaf',
|
||||
value: 'leaf1',
|
||||
color: 'green',
|
||||
},
|
||||
{
|
||||
title: 'your leaf',
|
||||
value: 'leaf2',
|
||||
color: 'cyan',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'parent 1-1',
|
||||
value: 'parent 1-1',
|
||||
color: 'blue',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
watch(value, () => {
|
||||
console.log('select', value.value);
|
||||
});
|
||||
|
||||
return {
|
||||
value,
|
||||
treeData,
|
||||
SHOW_ALL,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
@ -7,6 +7,9 @@
|
|||
<suffix />
|
||||
<async />
|
||||
<Highlight />
|
||||
<treeLineVue />
|
||||
<virtualScrollVue />
|
||||
<customTagRenderVue />
|
||||
</demo-sort>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
|
|
@ -17,6 +20,9 @@ import Checkable from './checkable.vue';
|
|||
import Suffix from './suffix.vue';
|
||||
import Async from './async.vue';
|
||||
import Highlight from './highlight.vue';
|
||||
import treeLineVue from './tree-line.vue';
|
||||
import virtualScrollVue from './virtual-scroll.vue';
|
||||
import customTagRenderVue from './custom-tag-render.vue';
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
import { defineComponent } from 'vue';
|
||||
|
|
@ -32,6 +38,9 @@ export default defineComponent({
|
|||
Suffix,
|
||||
Async,
|
||||
Highlight,
|
||||
treeLineVue,
|
||||
virtualScrollVue,
|
||||
customTagRenderVue,
|
||||
},
|
||||
setup() {
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -27,7 +27,12 @@ Multiple selection usage.
|
|||
multiple
|
||||
tree-default-expand-all
|
||||
:tree-data="treeData"
|
||||
></a-tree-select>
|
||||
>
|
||||
<template #title="{ value: val, title }">
|
||||
<b v-if="val === 'parent 1-1'" style="color: #08c">{{ val }}</b>
|
||||
<template v-else>{{ title }}</template>
|
||||
</template>
|
||||
</a-tree-select>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { TreeSelectProps } from 'ant-design-vue';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
<docs>
|
||||
---
|
||||
order: 6
|
||||
title:
|
||||
zh-CN: 线性样式
|
||||
en-US: Show Tree Line
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
通过 `treeLine` 配置线性样式。
|
||||
|
||||
## en-US
|
||||
|
||||
Use `treeLine` to show the line style.
|
||||
|
||||
</docs>
|
||||
|
||||
<template>
|
||||
<a-space direction="vertical">
|
||||
<a-switch
|
||||
v-model:checked="treeLine"
|
||||
checked-children="treeLine"
|
||||
un-checked-children="treeLine"
|
||||
></a-switch>
|
||||
<a-switch
|
||||
v-model:checked="showLeafIcon"
|
||||
:disabled="!treeLine"
|
||||
checked-children="showLeafIcon"
|
||||
un-checked-children="showLeafIcon"
|
||||
></a-switch>
|
||||
<a-tree-select
|
||||
v-model:value="value"
|
||||
style="width: 300px"
|
||||
placeholder="Please select"
|
||||
:tree-line="treeLine && { showLeafIcon }"
|
||||
:tree-data="treeData"
|
||||
>
|
||||
<template #title="{ value: val, title }">
|
||||
<b v-if="val === 'parent 1-1'" style="color: #08c">sss</b>
|
||||
<template v-else>{{ title }}</template>
|
||||
</template>
|
||||
</a-tree-select>
|
||||
</a-space>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { TreeSelectProps } from 'ant-design-vue';
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const treeLine = ref(true);
|
||||
const showLeafIcon = ref(false);
|
||||
const value = ref<string>();
|
||||
const treeData = ref<TreeSelectProps['treeData']>([
|
||||
{
|
||||
title: 'parent 1',
|
||||
value: 'parent 1',
|
||||
children: [
|
||||
{
|
||||
title: 'parent 1-0',
|
||||
value: 'parent 1-0',
|
||||
children: [
|
||||
{
|
||||
title: 'my leaf',
|
||||
value: 'leaf1',
|
||||
},
|
||||
{
|
||||
title: 'your leaf',
|
||||
value: 'leaf2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'parent 1-1',
|
||||
value: 'parent 1-1',
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
watch(value, () => {
|
||||
console.log(value.value);
|
||||
});
|
||||
return {
|
||||
treeLine,
|
||||
showLeafIcon,
|
||||
value,
|
||||
treeData,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<docs>
|
||||
---
|
||||
order: 2
|
||||
title:
|
||||
zh-CN: 从数据直接生成
|
||||
en-US: Generate form tree data
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
使用 `treeData` 把 JSON 数据直接生成树结构。
|
||||
|
||||
## en-US
|
||||
|
||||
The tree structure can be populated using `treeData` property. This is a quick and easy way to provide the tree content.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<a-tree-select
|
||||
v-model:value="value"
|
||||
style="width: 100%"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:tree-data="treeData"
|
||||
placeholder="Please select"
|
||||
tree-default-expand-all
|
||||
>
|
||||
<template #title="{ key, value: val, title }">
|
||||
<span v-if="key === '0-0-1'" style="color: #08c">Child Node1 {{ val }}</span>
|
||||
<template v-else>{{ title }}</template>
|
||||
</template>
|
||||
</a-tree-select>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { TreeSelectProps } from 'ant-design-vue';
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
|
||||
const treeData: TreeSelectProps['treeData'] = [
|
||||
{
|
||||
title: 'Node1',
|
||||
value: '0-0',
|
||||
key: '0-0',
|
||||
children: [
|
||||
{
|
||||
value: '0-0-1',
|
||||
key: '0-0-1',
|
||||
},
|
||||
{
|
||||
title: 'Child Node2',
|
||||
value: '0-0-2',
|
||||
key: '0-0-2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Node2',
|
||||
value: '0-1',
|
||||
key: '0-1',
|
||||
},
|
||||
];
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const value = ref<string>();
|
||||
|
||||
watch(value, () => {
|
||||
console.log(value.value);
|
||||
});
|
||||
return {
|
||||
value,
|
||||
treeData,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<docs>
|
||||
---
|
||||
order: 9
|
||||
title:
|
||||
zh-CN: 虚拟滚动
|
||||
en-US: Virtual scroll
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
使用 `height` 属性则切换为虚拟滚动。
|
||||
|
||||
## en-US
|
||||
|
||||
Use virtual list through `height` prop.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<a-tree-select
|
||||
v-model:value="checkedKeys"
|
||||
style="width: 100%"
|
||||
tree-checkable
|
||||
tree-default-expand-all
|
||||
:show-checked-strategy="SHOW_PARENT"
|
||||
:height="233"
|
||||
:tree-data="treeData"
|
||||
:max-tag-count="10"
|
||||
>
|
||||
<template #title="{ title, value }">
|
||||
<span v-if="value === '0-0-1-0'" style="color: #1890ff">{{ title }}</span>
|
||||
<template v-else>{{ title }}</template>
|
||||
</template>
|
||||
</a-tree-select>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { TreeSelectProps } from 'ant-design-vue';
|
||||
import { TreeSelect } from 'ant-design-vue';
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
const SHOW_PARENT = TreeSelect.SHOW_PARENT;
|
||||
|
||||
function dig(path = '0', level = 3) {
|
||||
const list: TreeSelectProps['treeData'] = [];
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
const value = `${path}-${i}`;
|
||||
const treeNode: TreeSelectProps['treeData'][number] = {
|
||||
title: value,
|
||||
value,
|
||||
};
|
||||
|
||||
if (level > 0) {
|
||||
treeNode.children = dig(value, level - 1);
|
||||
}
|
||||
|
||||
list.push(treeNode);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const checkedKeys = ref<string[]>(['0-0-0', '0-0-1']);
|
||||
watch(checkedKeys, () => {
|
||||
console.log('checkedKeys', checkedKeys);
|
||||
});
|
||||
|
||||
return {
|
||||
treeData: dig(),
|
||||
checkedKeys,
|
||||
SHOW_PARENT,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
@ -47,6 +47,7 @@ Tree selection control.
|
|||
| treeDefaultExpandAll | Whether to expand all treeNodes by default | boolean | false | |
|
||||
| treeDefaultExpandedKeys | Default expanded treeNodes | string\[] \| number\[] | - | |
|
||||
| treeExpandedKeys(v-model) | Set expanded keys | string\[] \| number\[] | - | |
|
||||
| treeLine | Show the line. Ref [Tree - showLine](/components/tree/#components-tree-demo-line) | boolean \| object | false | 3.0 |
|
||||
| treeNodeFilterProp | Will be used for filtering if `filterTreeNode` returns true | string | 'value' | |
|
||||
| treeNodeLabelProp | Will render as content of select | string | 'title' | |
|
||||
| value(v-model) | To set the current selected treeNode(s). | string\|string\[] | - | |
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import VcTreeSelect, {
|
|||
import classNames from '../_util/classNames';
|
||||
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
||||
import type { SizeType } from '../config-provider';
|
||||
import type { DefaultValueType, FieldNames } from '../vc-tree-select/interface';
|
||||
import type { FieldNames, Key } from '../vc-tree-select/interface';
|
||||
import omit from '../_util/omit';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
|
|
@ -21,6 +21,9 @@ import type { AntTreeNodeProps } from '../tree/Tree';
|
|||
import { warning } from '../vc-util/warning';
|
||||
import { flattenChildren } from '../_util/props-util';
|
||||
import { useInjectFormItemContext } from '../form/FormItemContext';
|
||||
import type { BaseSelectRef } from '../vc-select';
|
||||
import type { BaseOptionType, DefaultOptionType } from '../vc-tree-select/TreeSelect';
|
||||
import type { TreeProps } from '../tree';
|
||||
|
||||
const getTransitionName = (rootPrefixCls: string, motion: string, transitionName?: string) => {
|
||||
if (transitionName !== undefined) {
|
||||
|
|
@ -34,29 +37,42 @@ type RawValue = string | number;
|
|||
export interface LabeledValue {
|
||||
key?: string;
|
||||
value: RawValue;
|
||||
label: any;
|
||||
label?: any;
|
||||
}
|
||||
|
||||
export type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[];
|
||||
|
||||
export interface RefTreeSelectProps {
|
||||
focus: () => void;
|
||||
blur: () => void;
|
||||
export type RefTreeSelectProps = BaseSelectRef;
|
||||
|
||||
export function treeSelectProps<
|
||||
ValueType = any,
|
||||
OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,
|
||||
>() {
|
||||
return {
|
||||
...omit(vcTreeSelectProps<ValueType, OptionType>(), [
|
||||
'showTreeIcon',
|
||||
'treeMotion',
|
||||
'inputIcon',
|
||||
'getInputElement',
|
||||
'treeLine',
|
||||
'customSlots',
|
||||
]),
|
||||
suffixIcon: PropTypes.any,
|
||||
size: { type: String as PropType<SizeType> },
|
||||
bordered: { type: Boolean, default: undefined },
|
||||
treeLine: { type: [Boolean, Object] as PropType<TreeProps['showLine']>, default: undefined },
|
||||
replaceFields: { type: Object as PropType<FieldNames> },
|
||||
'onUpdate:value': { type: Function as PropType<(value: any) => void> },
|
||||
'onUpdate:treeExpandedKeys': { type: Function as PropType<(keys: Key[]) => void> },
|
||||
'onUpdate:searchValue': { type: Function as PropType<(value: string) => void> },
|
||||
};
|
||||
}
|
||||
export const treeSelectProps = {
|
||||
...omit(vcTreeSelectProps<DefaultValueType>(), ['showTreeIcon', 'treeMotion', 'inputIcon']),
|
||||
suffixIcon: PropTypes.any,
|
||||
size: { type: String as PropType<SizeType> },
|
||||
bordered: { type: Boolean, default: undefined },
|
||||
replaceFields: { type: Object as PropType<FieldNames> },
|
||||
};
|
||||
export type TreeSelectProps = Partial<ExtractPropTypes<typeof treeSelectProps>>;
|
||||
export type TreeSelectProps = Partial<ExtractPropTypes<ReturnType<typeof treeSelectProps>>>;
|
||||
|
||||
const TreeSelect = defineComponent({
|
||||
TreeNode,
|
||||
name: 'ATreeSelect',
|
||||
inheritAttrs: false,
|
||||
props: initDefaultProps(treeSelectProps, {
|
||||
props: initDefaultProps(treeSelectProps(), {
|
||||
choiceTransitionName: '',
|
||||
listHeight: 256,
|
||||
treeIcon: false,
|
||||
|
|
@ -135,18 +151,18 @@ const TreeSelect = defineComponent({
|
|||
},
|
||||
});
|
||||
|
||||
const handleChange = (...args: any[]) => {
|
||||
const handleChange: TreeSelectProps['onChange'] = (...args: any[]) => {
|
||||
emit('update:value', args[0]);
|
||||
emit('change', ...args);
|
||||
formItemContext.onFieldChange();
|
||||
};
|
||||
const handleTreeExpand = (...args: any[]) => {
|
||||
emit('update:treeExpandedKeys', args[0]);
|
||||
emit('treeExpand', ...args);
|
||||
const handleTreeExpand: TreeSelectProps['onTreeExpand'] = (keys: Key[]) => {
|
||||
emit('update:treeExpandedKeys', keys);
|
||||
emit('treeExpand', keys);
|
||||
};
|
||||
const handleSearch = (...args: any[]) => {
|
||||
emit('update:searchValue', args[0]);
|
||||
emit('search', ...args);
|
||||
const handleSearch: TreeSelectProps['onSearch'] = (value: string) => {
|
||||
emit('update:searchValue', value);
|
||||
emit('search', value);
|
||||
};
|
||||
const handleBlur = () => {
|
||||
emit('blur');
|
||||
|
|
@ -190,6 +206,10 @@ const TreeSelect = defineComponent({
|
|||
'removeIcon',
|
||||
'clearIcon',
|
||||
'switcherIcon',
|
||||
'bordered',
|
||||
'onUpdate:value',
|
||||
'onUpdate:treeExpandedKeys',
|
||||
'onUpdate:searchValue',
|
||||
]);
|
||||
|
||||
const mergedClassName = classNames(
|
||||
|
|
@ -242,6 +262,11 @@ const TreeSelect = defineComponent({
|
|||
}}
|
||||
{...otherProps}
|
||||
transitionName={transitionName.value}
|
||||
customSlots={{
|
||||
...slots,
|
||||
treeCheckable: () => <span class={`${prefixCls.value}-tree-checkbox-inner`} />,
|
||||
}}
|
||||
maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/Ax4DA0njr/TreeSelect.svg
|
|||
| treeDefaultExpandAll | 默认展开所有树节点 | boolean | false | |
|
||||
| treeDefaultExpandedKeys | 默认展开的树节点 | string\[] \| number\[] | - | |
|
||||
| treeExpandedKeys(v-model) | 设置展开的树节点 | string\[] \| number\[] | - | |
|
||||
| treeLine | 是否展示线条样式,请参考 [Tree - showLine](/components/tree/#components-tree-demo-line) | boolean \| object | false | 3.0 |
|
||||
| treeNodeFilterProp | 输入项过滤对应的 treeNode 属性 | string | 'value' | |
|
||||
| treeNodeLabelProp | 作为显示的 prop 设置 | string | 'title' | |
|
||||
| value(v-model) | 指定当前选中的条目 | string/string\[] | - | |
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
.@{tree-select-prefix-cls} {
|
||||
// ======================= Dropdown =======================
|
||||
&-dropdown {
|
||||
padding: @padding-xs (@padding-xs / 2) 0;
|
||||
padding: @padding-xs (@padding-xs / 2);
|
||||
|
||||
&-rtl {
|
||||
direction: rtl;
|
||||
|
|
@ -24,8 +24,6 @@
|
|||
align-items: stretch;
|
||||
|
||||
.@{select-tree-prefix-cls}-treenode {
|
||||
padding-bottom: @padding-xs;
|
||||
|
||||
.@{select-tree-prefix-cls}-node-content-wrapper {
|
||||
flex: auto;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
import { flattenChildren, isValidElement } from '../_util/props-util';
|
||||
|
||||
export function convertChildrenToData(nodes: any[]): any[] {
|
||||
return flattenChildren(nodes)
|
||||
.map(node => {
|
||||
if (!isValidElement(node) || !node.type) {
|
||||
return null;
|
||||
}
|
||||
const { default: d, ...restSlot } = node.children || {};
|
||||
const children = d ? d() : [];
|
||||
const {
|
||||
key,
|
||||
props: { value, ...restProps },
|
||||
} = node;
|
||||
|
||||
const data = {
|
||||
key,
|
||||
value,
|
||||
...restProps,
|
||||
};
|
||||
Object.keys(restSlot).forEach(p => {
|
||||
if (typeof restSlot[p] === 'function') {
|
||||
data[p] = <>{restSlot[p]()}</>;
|
||||
}
|
||||
});
|
||||
const childData = convertChildrenToData(children);
|
||||
if (childData.length) {
|
||||
data.children = childData;
|
||||
}
|
||||
|
||||
return data;
|
||||
})
|
||||
.filter(data => data);
|
||||
}
|
||||
|
|
@ -81,7 +81,10 @@ export interface AntTreeNodeDropEvent {
|
|||
export const treeProps = () => {
|
||||
return {
|
||||
...vcTreeProps(),
|
||||
showLine: { type: Boolean, default: undefined },
|
||||
showLine: {
|
||||
type: [Boolean, Object] as PropType<boolean | { showLeafIcon: boolean }>,
|
||||
default: undefined,
|
||||
},
|
||||
/** 是否支持多选 */
|
||||
multiple: { type: Boolean, default: undefined },
|
||||
/** 是否自动展开父节点 */
|
||||
|
|
|
|||
|
|
@ -13,11 +13,13 @@ exports[`renders ./components/tree/demo/accordion.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">parent 1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">parent 2</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
|
|
@ -42,22 +44,28 @@ exports[`renders ./components/tree/demo/basic.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-disabled ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-selected"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked ant-tree-checkbox-disabled"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1-0</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-disabled ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-selected" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked ant-tree-checkbox-disabled"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-disabled"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-disabled"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1-1</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1-1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><span style="color: rgb(24, 144, 255);">sss</span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><span style="color: rgb(24, 144, 255);">sss</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -81,39 +89,48 @@ exports[`renders ./components/tree/demo/context-menu.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title"><!----><span class="ant-dropdown-trigger">0-0</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title"><!----><span class="ant-dropdown-trigger">0-0-0</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><!----><span class="ant-dropdown-trigger">0-0-0-0</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><!----><span class="ant-dropdown-trigger">0-0-0-1</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><!----><span class="ant-dropdown-trigger">0-0-0-2</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title"><!----><span class="ant-dropdown-trigger">0-0-1</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><!----><span class="ant-dropdown-trigger">0-0-1-0</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><!----><span class="ant-dropdown-trigger">0-0-1-1</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><!----><span class="ant-dropdown-trigger">0-0-1-2</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
|
|
@ -138,15 +155,18 @@ exports[`renders ./components/tree/demo/customized-icon.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!----><span title="parent 1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><span class="ant-tree-iconEle ant-tree-icon__customize"><span role="img" aria-label="smile" class="anticon anticon-smile"><svg focusable="false" class="" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"></path></svg></span></span><span class="ant-tree-title">parent 1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-selected"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-selected" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="leaf" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal ant-tree-node-selected"><span class="ant-tree-iconEle ant-tree-icon__customize"><span role="img" aria-label="smile" class="anticon anticon-smile"><svg focusable="false" class="" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"></path></svg></span></span><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="leaf" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><span class="ant-tree-iconEle ant-tree-icon__customize"><span role="img" aria-label="frown" class="anticon anticon-frown"><svg focusable="false" class="" data-icon="frown" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM512 533c-85.5 0-155.6 67.3-160 151.6a8 8 0 008 8.4h48.1c4.2 0 7.8-3.2 8.1-7.4C420 636.1 461.5 597 512 597s92.1 39.1 95.8 88.6c.3 4.2 3.9 7.4 8.1 7.4H664a8 8 0 008-8.4C667.6 600.3 597.5 533 512 533z"></path></svg></span></span><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
|
|
@ -171,27 +191,33 @@ exports[`renders ./components/tree/demo/directory.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="parent 0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><span class="ant-tree-iconEle ant-tree-icon__customize"><span role="img" aria-label="folder-open" class="anticon anticon-folder-open"><svg focusable="false" class="" data-icon="folder-open" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M928 444H820V330.4c0-17.7-14.3-32-32-32H473L355.7 186.2a8.15 8.15 0 00-5.5-2.2H96c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h698c13 0 24.8-7.9 29.7-20l134-332c1.5-3.8 2.3-7.9 2.3-12 0-17.7-14.3-32-32-32zM136 256h188.5l119.6 114.4H748V444H238c-13 0-24.8 7.9-29.7 20L136 643.2V256zm635.3 512H159l103.3-256h612.4L771.3 768z"></path></svg></span></span><span class="ant-tree-title">parent 0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="leaf 0-0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><span class="ant-tree-iconEle ant-tree-icon__customize"><span role="img" aria-label="file" class="anticon anticon-file"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span><span class="ant-tree-title">leaf 0-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="leaf 0-1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><span class="ant-tree-iconEle ant-tree-icon__customize"><span role="img" aria-label="file" class="anticon anticon-file"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span><span class="ant-tree-title">leaf 0-1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="parent 1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><span class="ant-tree-iconEle ant-tree-icon__customize"><span role="img" aria-label="folder-open" class="anticon anticon-folder-open"><svg focusable="false" class="" data-icon="folder-open" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M928 444H820V330.4c0-17.7-14.3-32-32-32H473L355.7 186.2a8.15 8.15 0 00-5.5-2.2H96c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h698c13 0 24.8-7.9 29.7-20l134-332c1.5-3.8 2.3-7.9 2.3-12 0-17.7-14.3-32-32-32zM136 256h188.5l119.6 114.4H748V444H238c-13 0-24.8 7.9-29.7 20L136 643.2V256zm635.3 512H159l103.3-256h612.4L771.3 768z"></path></svg></span></span><span class="ant-tree-title">parent 1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="leaf 1-0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><span class="ant-tree-iconEle ant-tree-icon__customize"><span role="img" aria-label="file" class="anticon anticon-file"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span><span class="ant-tree-title">leaf 1-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="leaf 1-1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><span class="ant-tree-iconEle ant-tree-icon__customize"><span role="img" aria-label="file" class="anticon anticon-file"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span><span class="ant-tree-title">leaf 1-1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
|
|
@ -216,16 +242,19 @@ exports[`renders ./components/tree/demo/draggable.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="0-0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close draggable" draggable="true" aria-grabbed="true"><!----><span class="ant-tree-title">0-0</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-draggable" draggable="true" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="0-0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">0-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="0-1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close draggable" draggable="true" aria-grabbed="true"><!----><span class="ant-tree-title">0-1</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-draggable" draggable="true" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="0-1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">0-1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="0-2" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal draggable" draggable="true" aria-grabbed="true"><!----><span class="ant-tree-title">0-2</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last ant-tree-treenode-draggable" draggable="true" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="0-2" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-2</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -249,15 +278,18 @@ exports[`renders ./components/tree/demo/dynamic.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="Expand to load" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">Expand to load</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="Expand to load" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">Expand to load</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="Tree Node" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">Tree Node</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
|
|
@ -288,35 +320,43 @@ exports[`renders ./components/tree/demo/line.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="minus-square" class="anticon anticon-minus-square ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="minus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="minus-square" class="anticon anticon-minus-square ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="minus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="minus-square" class="anticon anticon-minus-square ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="minus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="minus-square" class="anticon anticon-minus-square ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="minus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><div>multiple line title</div><div>multiple line title</div></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="plus-square" class="anticon anticon-plus-square ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="plus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M328 544h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="plus-square" class="anticon anticon-plus-square ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="plus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M328 544h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">parent 1-1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="smile" class="anticon anticon-smile"><svg focusable="false" class="" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="#1890ff"></path><path d="M512 140c-205.4 0-372 166.6-372 372s166.6 372 372 372 372-166.6 372-372-166.6-372-372-372zM288 421a48.01 48.01 0 0196 0 48.01 48.01 0 01-96 0zm224 272c-85.5 0-155.6-67.3-160-151.6a8 8 0 018-8.4h48.1c4.2 0 7.8 3.2 8.1 7.4C420 589.9 461.5 629 512 629s92.1-39.1 95.8-88.6c.3-4.2 3.9-7.4 8.1-7.4H664a8 8 0 018 8.4C667.6 625.7 597.5 693 512 693zm176-224a48.01 48.01 0 010-96 48.01 48.01 0 010 96z" fill="#e6f7ff"></path><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm376 112h-48.1c-4.2 0-7.8 3.2-8.1 7.4-3.7 49.5-45.3 88.6-95.8 88.6s-92-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4zm-24-112a48 48 0 1096 0 48 48 0 10-96 0z" fill="#1890ff"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="smile" class="anticon anticon-smile"><svg focusable="false" class="" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="#1890ff"></path><path d="M512 140c-205.4 0-372 166.6-372 372s166.6 372 372 372 372-166.6 372-372-166.6-372-372-372zM288 421a48.01 48.01 0 0196 0 48.01 48.01 0 01-96 0zm224 272c-85.5 0-155.6-67.3-160-151.6a8 8 0 018-8.4h48.1c4.2 0 7.8 3.2 8.1 7.4C420 589.9 461.5 629 512 629s92.1-39.1 95.8-88.6c.3-4.2 3.9-7.4 8.1-7.4H664a8 8 0 018 8.4C667.6 625.7 597.5 693 512 693zm176-224a48.01 48.01 0 010-96 48.01 48.01 0 010 96z" fill="#e6f7ff"></path><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm376 112h-48.1c-4.2 0-7.8 3.2-8.1 7.4-3.7 49.5-45.3 88.6-95.8 88.6s-92-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4zm-24-112a48 48 0 1096 0 48 48 0 10-96 0z" fill="#1890ff"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">parent 1-2</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="plus-square" class="anticon anticon-plus-square ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="plus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M328 544h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="plus-square" class="anticon anticon-plus-square ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="plus-square" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M328 544h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"></path><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">parent 2</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
|
|
@ -342,22 +382,28 @@ exports[`renders ./components/tree/demo/replaceFields.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-disabled ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-selected"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked ant-tree-checkbox-disabled"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">张晨成</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-disabled ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-selected" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked ant-tree-checkbox-disabled"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">张晨成</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-disabled"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-disabled"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title"><span style="color: rgb(24, 144, 255);">parent 1-1</span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title"><span style="color: rgb(24, 144, 255);">parent 1-1</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">zcvc</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-checkbox-checked ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">zcvc</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -382,15 +428,18 @@ exports[`renders ./components/tree/demo/search.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title"><span> <span style="color: rgb(255, 85, 0);"></span> 0-0</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title"><span> <span style="color: rgb(255, 85, 0);"></span> 0-1</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span>
|
||||
<!----><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title"><span> <span style="color: rgb(255, 85, 0);"></span> 0-2</span></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
|
|
@ -416,31 +465,38 @@ exports[`renders ./components/tree/demo/switcher-icon.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder">
|
||||
<div>
|
||||
<div style="display: flex; flex-direction: column;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!----><span title="parent 1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!----><span title="parent 1-0" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">parent 1-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<!----><span title="leaf" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<!----><span title="leaf" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><span role="img" aria-label="file" class="anticon anticon-file ant-tree-switcher-line-icon"><svg focusable="false" class="" data-icon="file" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"></path></svg></span></span>
|
||||
<!----><span title="leaf" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">leaf</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!----><span title="parent 1-1" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">parent 1-1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-close ant-tree-treenode-leaf-last" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start ant-tree-indent-unit-end"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_close"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!----><span title="parent 1-2" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-close"><!----><span class="ant-tree-title">parent 1-2</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
|
|
@ -465,34 +521,44 @@ exports[`renders ./components/tree/demo/virtual-scroll.vue correctly 1`] = `
|
|||
<div class="ant-tree-list-holder" style="max-height: 233px; overflow-y: hidden;">
|
||||
<div style="height: 311080px; position: relative; overflow: hidden;">
|
||||
<div style="display: flex; flex-direction: column; transform: translateY(0px); position: absolute; left: 0px; right: 0px; top: 0px;" class="ant-tree-list-holder-inner">
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-indeterminate"><span aria-hidden="true" class="ant-tree-indent"></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-indeterminate"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">0-0</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-indeterminate" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-indeterminate"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">0-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-selected"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open ant-tree-node-selected"><!----><span class="ant-tree-title">0-0-0</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked ant-tree-treenode-selected" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open ant-tree-node-selected"><!----><span class="ant-tree-title">0-0-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">0-0-0-0</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher_open"><span role="img" aria-label="caret-down" class="anticon anticon-caret-down ant-tree-switcher-icon"><svg focusable="false" class="" data-icon="caret-down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="0 0 1024 1024"><path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path></svg></span></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"><!----><span class="ant-tree-title">0-0-0-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-0</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-0</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-1</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-1</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-2</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-2</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-3</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-3</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-4</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-4</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-5</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-5</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-6</span>
|
||||
<div class="ant-tree-treenode ant-tree-treenode-switcher-open ant-tree-treenode-checkbox-checked" draggable="false" aria-grabbed="false"><span aria-hidden="true" class="ant-tree-indent"><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span><span class="ant-tree-indent-unit ant-tree-indent-unit-start"></span></span>
|
||||
<!----><span class="ant-tree-switcher ant-tree-switcher-noop"><!----></span><span class="ant-tree-checkbox ant-tree-checkbox-checked"><span class="ant-tree-checkbox-inner"></span></span><span title="" class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"><!----><span class="ant-tree-title">0-0-0-0-6</span>
|
||||
<!----></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ Almost anything can be represented in a tree structure. Examples include directo
|
|||
| selectedKeys(v-model) | (Controlled) Specifies the keys of the selected treeNodes | string\[] \| number\[] | - | |
|
||||
| showIcon | Shows the icon before a TreeNode's title. There is no default style; you must set a custom style for it if set to `true` | boolean | false | |
|
||||
| switcherIcon | customize collapse/expand icon of tree node | slot | - | |
|
||||
| showLine | Shows a connecting line | boolean | false | |
|
||||
| showLine | Shows a connecting line | boolean \| {showLeafIcon: boolean}(3.0+) | false | |
|
||||
| title | custom title | slot | | 2.0.0 |
|
||||
|
||||
### Events
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/Xh-oWqg9k/Tree.svg
|
|||
| selectedKeys(v-model) | (受控)设置选中的树节点 | string\[] \| number\[] | - | |
|
||||
| showIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true,需要自行定义图标相关样式 | boolean | false | |
|
||||
| switcherIcon | 自定义树节点的展开/折叠图标 | slot | - | |
|
||||
| showLine | 是否展示连接线 | boolean | false | |
|
||||
| showLine | 是否展示连接线 | boolean \| {showLeafIcon: boolean}(3.0+) | false | |
|
||||
| title | 自定义标题 | slot | | 2.0.0 |
|
||||
|
||||
### 事件
|
||||
|
|
|
|||
|
|
@ -1,388 +0,0 @@
|
|||
import { getComponent, getSlot, hasProp, getEvents } from '../_util/props-util';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import Trigger from '../vc-trigger';
|
||||
import Menus from './Menus';
|
||||
import KeyCode from '../_util/KeyCode';
|
||||
import arrayTreeFilter from 'array-tree-filter';
|
||||
import shallowEqualArrays from 'shallow-equal/arrays';
|
||||
import BaseMixin from '../_util/BaseMixin';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import { defineComponent } from 'vue';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
|
||||
const BUILT_IN_PLACEMENTS = {
|
||||
bottomLeft: {
|
||||
points: ['tl', 'bl'],
|
||||
offset: [0, 4],
|
||||
overflow: {
|
||||
adjustX: 1,
|
||||
adjustY: 1,
|
||||
},
|
||||
},
|
||||
topLeft: {
|
||||
points: ['bl', 'tl'],
|
||||
offset: [0, -4],
|
||||
overflow: {
|
||||
adjustX: 1,
|
||||
adjustY: 1,
|
||||
},
|
||||
},
|
||||
bottomRight: {
|
||||
points: ['tr', 'br'],
|
||||
offset: [0, 4],
|
||||
overflow: {
|
||||
adjustX: 1,
|
||||
adjustY: 1,
|
||||
},
|
||||
},
|
||||
topRight: {
|
||||
points: ['br', 'tr'],
|
||||
offset: [0, -4],
|
||||
overflow: {
|
||||
adjustX: 1,
|
||||
adjustY: 1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Cascader',
|
||||
mixins: [BaseMixin],
|
||||
inheritAttrs: false,
|
||||
// model: {
|
||||
// prop: 'value',
|
||||
// event: 'change',
|
||||
// },
|
||||
props: {
|
||||
value: PropTypes.array,
|
||||
defaultValue: PropTypes.array,
|
||||
options: PropTypes.array,
|
||||
// onChange: PropTypes.func,
|
||||
// onPopupVisibleChange: PropTypes.func,
|
||||
popupVisible: PropTypes.looseBool,
|
||||
disabled: PropTypes.looseBool.def(false),
|
||||
transitionName: PropTypes.string.def(''),
|
||||
popupClassName: PropTypes.string.def(''),
|
||||
popupStyle: PropTypes.object.def(() => ({})),
|
||||
popupPlacement: PropTypes.string.def('bottomLeft'),
|
||||
prefixCls: PropTypes.string.def('rc-cascader'),
|
||||
dropdownMenuColumnStyle: PropTypes.object,
|
||||
builtinPlacements: PropTypes.object.def(BUILT_IN_PLACEMENTS),
|
||||
loadData: PropTypes.func,
|
||||
changeOnSelect: PropTypes.looseBool,
|
||||
// onKeyDown: PropTypes.func,
|
||||
expandTrigger: PropTypes.string.def('click'),
|
||||
fieldNames: PropTypes.object.def(() => ({
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
children: 'children',
|
||||
})),
|
||||
expandIcon: PropTypes.any,
|
||||
loadingIcon: PropTypes.any,
|
||||
getPopupContainer: PropTypes.func,
|
||||
},
|
||||
data() {
|
||||
let initialValue = [];
|
||||
const { value, defaultValue, popupVisible } = this;
|
||||
if (hasProp(this, 'value')) {
|
||||
initialValue = value || [];
|
||||
} else if (hasProp(this, 'defaultValue')) {
|
||||
initialValue = defaultValue || [];
|
||||
}
|
||||
this.children = undefined;
|
||||
// warning(!('filedNames' in props),
|
||||
// '`filedNames` of Cascader is a typo usage and deprecated, please use `fieldNames` instead.');
|
||||
this.defaultFieldNames = { label: 'label', value: 'value', children: 'children' };
|
||||
return {
|
||||
sPopupVisible: popupVisible,
|
||||
sActiveValue: initialValue,
|
||||
sValue: initialValue,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(val, oldValue) {
|
||||
if (!shallowEqualArrays(val, oldValue)) {
|
||||
const newValues = {
|
||||
sValue: val || [],
|
||||
};
|
||||
// allow activeValue diff from value
|
||||
// https://github.com/ant-design/ant-design/issues/2767
|
||||
if (!hasProp(this, 'loadData')) {
|
||||
newValues.sActiveValue = val || [];
|
||||
}
|
||||
this.setState(newValues);
|
||||
}
|
||||
},
|
||||
popupVisible(val) {
|
||||
this.setState({
|
||||
sPopupVisible: val,
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getPopupDOMNode() {
|
||||
return this.trigger.getPopupDomNode();
|
||||
},
|
||||
getFieldName(name) {
|
||||
const { defaultFieldNames, fieldNames } = this;
|
||||
return fieldNames[name] || defaultFieldNames[name];
|
||||
},
|
||||
getFieldNames() {
|
||||
return this.fieldNames;
|
||||
},
|
||||
getCurrentLevelOptions() {
|
||||
const { options = [], sActiveValue = [] } = this;
|
||||
const result = arrayTreeFilter(
|
||||
options,
|
||||
(o, level) => isEqual(o[this.getFieldName('value')], sActiveValue[level]),
|
||||
{ childrenKeyName: this.getFieldName('children') },
|
||||
);
|
||||
if (result[result.length - 2]) {
|
||||
return result[result.length - 2][this.getFieldName('children')];
|
||||
}
|
||||
return [...options].filter(o => !o.disabled);
|
||||
},
|
||||
getActiveOptions(activeValue) {
|
||||
return arrayTreeFilter(
|
||||
this.options || [],
|
||||
(o, level) => isEqual(o[this.getFieldName('value')], activeValue[level]),
|
||||
{ childrenKeyName: this.getFieldName('children') },
|
||||
);
|
||||
},
|
||||
setPopupVisible(popupVisible) {
|
||||
if (!hasProp(this, 'popupVisible')) {
|
||||
this.setState({ sPopupVisible: popupVisible });
|
||||
}
|
||||
// sync activeValue with value when panel open
|
||||
if (popupVisible && !this.sPopupVisible) {
|
||||
this.setState({
|
||||
sActiveValue: this.sValue,
|
||||
});
|
||||
}
|
||||
this.__emit('popupVisibleChange', popupVisible);
|
||||
},
|
||||
handleChange(options, setProps, e) {
|
||||
if (e.type !== 'keydown' || e.keyCode === KeyCode.ENTER) {
|
||||
const value = options.map(o => o[this.getFieldName('value')]);
|
||||
this.__emit('change', value, options);
|
||||
this.setPopupVisible(setProps.visible);
|
||||
}
|
||||
},
|
||||
handlePopupVisibleChange(popupVisible) {
|
||||
this.setPopupVisible(popupVisible);
|
||||
},
|
||||
handleMenuSelect(targetOption, menuIndex, e) {
|
||||
// Keep focused state for keyboard support
|
||||
const triggerNode = this.trigger.getRootDomNode();
|
||||
if (triggerNode && triggerNode.focus) {
|
||||
triggerNode.focus();
|
||||
}
|
||||
const { changeOnSelect, loadData, expandTrigger } = this;
|
||||
if (!targetOption || targetOption.disabled) {
|
||||
return;
|
||||
}
|
||||
let { sActiveValue } = this;
|
||||
sActiveValue = sActiveValue.slice(0, menuIndex + 1);
|
||||
sActiveValue[menuIndex] = targetOption[this.getFieldName('value')];
|
||||
const activeOptions = this.getActiveOptions(sActiveValue);
|
||||
if (
|
||||
targetOption.isLeaf === false &&
|
||||
!targetOption[this.getFieldName('children')] &&
|
||||
loadData
|
||||
) {
|
||||
if (changeOnSelect) {
|
||||
this.handleChange(activeOptions, { visible: true }, e);
|
||||
}
|
||||
this.setState({ sActiveValue });
|
||||
loadData(activeOptions);
|
||||
return;
|
||||
}
|
||||
const newState = {};
|
||||
if (
|
||||
!targetOption[this.getFieldName('children')] ||
|
||||
!targetOption[this.getFieldName('children')].length
|
||||
) {
|
||||
this.handleChange(activeOptions, { visible: false }, e);
|
||||
// set value to activeValue when select leaf option
|
||||
newState.sValue = sActiveValue;
|
||||
// add e.type judgement to prevent `onChange` being triggered by mouseEnter
|
||||
} else if (changeOnSelect && (e.type === 'click' || e.type === 'keydown')) {
|
||||
if (expandTrigger === 'hover') {
|
||||
this.handleChange(activeOptions, { visible: false }, e);
|
||||
} else {
|
||||
this.handleChange(activeOptions, { visible: true }, e);
|
||||
}
|
||||
// set value to activeValue on every select
|
||||
newState.sValue = sActiveValue;
|
||||
}
|
||||
newState.sActiveValue = sActiveValue;
|
||||
// not change the value by keyboard
|
||||
if (hasProp(this, 'value') || (e.type === 'keydown' && e.keyCode !== KeyCode.ENTER)) {
|
||||
delete newState.sValue;
|
||||
}
|
||||
this.setState(newState);
|
||||
},
|
||||
handleItemDoubleClick() {
|
||||
const { changeOnSelect } = this.$props;
|
||||
if (changeOnSelect) {
|
||||
this.setPopupVisible(false);
|
||||
}
|
||||
},
|
||||
handleKeyDown(e) {
|
||||
const children = this.children;
|
||||
// https://github.com/ant-design/ant-design/issues/6717
|
||||
// Don't bind keyboard support when children specify the onKeyDown
|
||||
if (children) {
|
||||
const keydown = getEvents(children).onKeydown;
|
||||
if (keydown) {
|
||||
keydown(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const activeValue = [...this.sActiveValue];
|
||||
const currentLevel = activeValue.length - 1 < 0 ? 0 : activeValue.length - 1;
|
||||
const currentOptions = this.getCurrentLevelOptions();
|
||||
const currentIndex = currentOptions
|
||||
.map(o => o[this.getFieldName('value')])
|
||||
.findIndex(val => isEqual(activeValue[currentLevel], val));
|
||||
if (
|
||||
e.keyCode !== KeyCode.DOWN &&
|
||||
e.keyCode !== KeyCode.UP &&
|
||||
e.keyCode !== KeyCode.LEFT &&
|
||||
e.keyCode !== KeyCode.RIGHT &&
|
||||
e.keyCode !== KeyCode.ENTER &&
|
||||
e.keyCode !== KeyCode.SPACE &&
|
||||
e.keyCode !== KeyCode.BACKSPACE &&
|
||||
e.keyCode !== KeyCode.ESC &&
|
||||
e.keyCode !== KeyCode.TAB
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// Press any keys above to reopen menu
|
||||
if (
|
||||
!this.sPopupVisible &&
|
||||
e.keyCode !== KeyCode.BACKSPACE &&
|
||||
e.keyCode !== KeyCode.LEFT &&
|
||||
e.keyCode !== KeyCode.RIGHT &&
|
||||
e.keyCode !== KeyCode.ESC &&
|
||||
e.keyCode !== KeyCode.TAB
|
||||
) {
|
||||
this.setPopupVisible(true);
|
||||
return;
|
||||
}
|
||||
if (e.keyCode === KeyCode.DOWN || e.keyCode === KeyCode.UP) {
|
||||
e.preventDefault();
|
||||
let nextIndex = currentIndex;
|
||||
if (nextIndex !== -1) {
|
||||
if (e.keyCode === KeyCode.DOWN) {
|
||||
nextIndex += 1;
|
||||
nextIndex = nextIndex >= currentOptions.length ? 0 : nextIndex;
|
||||
} else {
|
||||
nextIndex -= 1;
|
||||
nextIndex = nextIndex < 0 ? currentOptions.length - 1 : nextIndex;
|
||||
}
|
||||
} else {
|
||||
nextIndex = 0;
|
||||
}
|
||||
activeValue[currentLevel] = currentOptions[nextIndex][this.getFieldName('value')];
|
||||
} else if (e.keyCode === KeyCode.LEFT || e.keyCode === KeyCode.BACKSPACE) {
|
||||
e.preventDefault();
|
||||
activeValue.splice(activeValue.length - 1, 1);
|
||||
} else if (e.keyCode === KeyCode.RIGHT) {
|
||||
e.preventDefault();
|
||||
if (
|
||||
currentOptions[currentIndex] &&
|
||||
currentOptions[currentIndex][this.getFieldName('children')]
|
||||
) {
|
||||
activeValue.push(
|
||||
currentOptions[currentIndex][this.getFieldName('children')][0][
|
||||
this.getFieldName('value')
|
||||
],
|
||||
);
|
||||
}
|
||||
} else if (e.keyCode === KeyCode.ESC || e.keyCode === KeyCode.TAB) {
|
||||
this.setPopupVisible(false);
|
||||
return;
|
||||
}
|
||||
if (!activeValue || activeValue.length === 0) {
|
||||
this.setPopupVisible(false);
|
||||
}
|
||||
const activeOptions = this.getActiveOptions(activeValue);
|
||||
const targetOption = activeOptions[activeOptions.length - 1];
|
||||
this.handleMenuSelect(targetOption, activeOptions.length - 1, e);
|
||||
this.__emit('keydown', e);
|
||||
},
|
||||
saveTrigger(node) {
|
||||
this.trigger = node;
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const {
|
||||
$props,
|
||||
sActiveValue,
|
||||
handleMenuSelect,
|
||||
sPopupVisible,
|
||||
handlePopupVisibleChange,
|
||||
handleKeyDown,
|
||||
} = this;
|
||||
const {
|
||||
prefixCls,
|
||||
transitionName,
|
||||
popupClassName,
|
||||
options = [],
|
||||
disabled,
|
||||
builtinPlacements,
|
||||
popupPlacement,
|
||||
...restProps
|
||||
} = $props;
|
||||
// Did not show popup when there is no options
|
||||
let menus = <div />;
|
||||
let emptyMenuClassName = '';
|
||||
if (options && options.length > 0) {
|
||||
const loadingIcon = getComponent(this, 'loadingIcon');
|
||||
const expandIcon = getComponent(this, 'expandIcon') || '>';
|
||||
const menusProps = {
|
||||
...$props,
|
||||
...this.$attrs,
|
||||
fieldNames: this.getFieldNames(),
|
||||
defaultFieldNames: this.defaultFieldNames,
|
||||
activeValue: sActiveValue,
|
||||
visible: sPopupVisible,
|
||||
loadingIcon,
|
||||
expandIcon,
|
||||
onSelect: handleMenuSelect,
|
||||
onItemDoubleClick: this.handleItemDoubleClick,
|
||||
};
|
||||
menus = <Menus {...menusProps} />;
|
||||
} else {
|
||||
emptyMenuClassName = ` ${prefixCls}-menus-empty`;
|
||||
}
|
||||
const triggerProps = {
|
||||
...restProps,
|
||||
...this.$attrs,
|
||||
disabled,
|
||||
popupPlacement,
|
||||
builtinPlacements,
|
||||
popupTransitionName: transitionName,
|
||||
action: disabled ? [] : ['click'],
|
||||
popupVisible: disabled ? false : sPopupVisible,
|
||||
prefixCls: `${prefixCls}-menus`,
|
||||
popupClassName: popupClassName + emptyMenuClassName,
|
||||
popup: menus,
|
||||
onPopupVisibleChange: handlePopupVisibleChange,
|
||||
ref: this.saveTrigger,
|
||||
};
|
||||
const children = getSlot(this);
|
||||
this.children = children;
|
||||
return (
|
||||
<Trigger {...triggerProps}>
|
||||
{children &&
|
||||
cloneElement(children[0], {
|
||||
onKeydown: handleKeyDown,
|
||||
tabindex: disabled ? undefined : 0,
|
||||
})}
|
||||
</Trigger>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,566 @@
|
|||
import { computed, defineComponent, ref, toRef, toRefs, watchEffect } from 'vue';
|
||||
import type { CSSProperties, ExtractPropTypes, PropType, Ref } from 'vue';
|
||||
import type { BaseSelectRef, BaseSelectProps } from '../vc-select';
|
||||
import type { DisplayValueType, Placement } from '../vc-select/BaseSelect';
|
||||
import { baseSelectPropsWithoutPrivate } from '../vc-select/BaseSelect';
|
||||
import omit from '../_util/omit';
|
||||
import type { Key, VueNode } from '../_util/type';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { initDefaultProps } from '../_util/props-util';
|
||||
import useId from '../vc-select/hooks/useId';
|
||||
import useMergedState from '../_util/hooks/useMergedState';
|
||||
import { fillFieldNames, toPathKey, toPathKeys } from './utils/commonUtil';
|
||||
import useEntities from './hooks/useEntities';
|
||||
import useSearchConfig from './hooks/useSearchConfig';
|
||||
import useSearchOptions from './hooks/useSearchOptions';
|
||||
import useMissingValues from './hooks/useMissingValues';
|
||||
import { formatStrategyValues, toPathOptions } from './utils/treeUtil';
|
||||
import { conductCheck } from '../vc-tree/utils/conductUtil';
|
||||
import useDisplayValues from './hooks/useDisplayValues';
|
||||
import { useProvideCascader } from './context';
|
||||
import OptionList from './OptionList';
|
||||
import { BaseSelect } from '../vc-select';
|
||||
import devWarning from '../vc-util/devWarning';
|
||||
|
||||
export interface ShowSearchType<OptionType extends BaseOptionType = DefaultOptionType> {
|
||||
filter?: (inputValue: string, options: OptionType[], fieldNames: FieldNames) => boolean;
|
||||
render?: (arg?: {
|
||||
inputValue: string;
|
||||
path: OptionType[];
|
||||
prefixCls: string;
|
||||
fieldNames: FieldNames;
|
||||
}) => any;
|
||||
sort?: (a: OptionType[], b: OptionType[], inputValue: string, fieldNames: FieldNames) => number;
|
||||
matchInputWidth?: boolean;
|
||||
limit?: number | false;
|
||||
}
|
||||
|
||||
export interface FieldNames {
|
||||
label?: string;
|
||||
value?: string;
|
||||
children?: string;
|
||||
}
|
||||
|
||||
export interface InternalFieldNames extends Required<FieldNames> {
|
||||
key: string;
|
||||
}
|
||||
|
||||
export type SingleValueType = (string | number)[];
|
||||
|
||||
export type ValueType = SingleValueType | SingleValueType[];
|
||||
|
||||
export interface BaseOptionType {
|
||||
disabled?: boolean;
|
||||
[name: string]: any;
|
||||
}
|
||||
export interface DefaultOptionType extends BaseOptionType {
|
||||
label?: any;
|
||||
value?: string | number | null;
|
||||
children?: DefaultOptionType[];
|
||||
}
|
||||
|
||||
function baseCascaderProps<OptionType extends BaseOptionType = DefaultOptionType>() {
|
||||
return {
|
||||
...omit(baseSelectPropsWithoutPrivate(), ['tokenSeparators', 'mode', 'showSearch']),
|
||||
// MISC
|
||||
id: String,
|
||||
prefixCls: String,
|
||||
fieldNames: Object as PropType<FieldNames>,
|
||||
children: Array as PropType<VueNode[]>,
|
||||
|
||||
// Value
|
||||
value: { type: [String, Number, Array] as PropType<ValueType> },
|
||||
defaultValue: { type: [String, Number, Array] as PropType<ValueType> },
|
||||
changeOnSelect: { type: Boolean, default: undefined },
|
||||
onChange: Function as PropType<
|
||||
(value: ValueType, selectedOptions?: OptionType[] | OptionType[][]) => void
|
||||
>,
|
||||
displayRender: Function as PropType<
|
||||
(opt: { labels: string[]; selectedOptions?: OptionType[] }) => any
|
||||
>,
|
||||
checkable: { type: Boolean, default: undefined },
|
||||
|
||||
// Search
|
||||
showSearch: {
|
||||
type: [Boolean, Object] as PropType<boolean | ShowSearchType<OptionType>>,
|
||||
default: undefined as boolean | ShowSearchType<OptionType>,
|
||||
},
|
||||
searchValue: String,
|
||||
onSearch: Function as PropType<(value: string) => void>,
|
||||
|
||||
// Trigger
|
||||
expandTrigger: String as PropType<'hover' | 'click'>,
|
||||
|
||||
// Options
|
||||
options: Array as PropType<OptionType[]>,
|
||||
/** @private Internal usage. Do not use in your production. */
|
||||
dropdownPrefixCls: String,
|
||||
loadData: Function as PropType<(selectOptions: OptionType[]) => void>,
|
||||
|
||||
// Open
|
||||
/** @deprecated Use `open` instead */
|
||||
popupVisible: { type: Boolean, default: undefined },
|
||||
|
||||
/** @deprecated Use `dropdownClassName` instead */
|
||||
popupClassName: String,
|
||||
dropdownClassName: String,
|
||||
dropdownMenuColumnStyle: {
|
||||
type: Object as PropType<CSSProperties>,
|
||||
default: undefined as CSSProperties,
|
||||
},
|
||||
|
||||
/** @deprecated Use `dropdownStyle` instead */
|
||||
popupStyle: { type: Object as PropType<CSSProperties>, default: undefined as CSSProperties },
|
||||
dropdownStyle: { type: Object as PropType<CSSProperties>, default: undefined as CSSProperties },
|
||||
|
||||
/** @deprecated Use `placement` instead */
|
||||
popupPlacement: String as PropType<Placement>,
|
||||
placement: String as PropType<Placement>,
|
||||
|
||||
/** @deprecated Use `onDropdownVisibleChange` instead */
|
||||
onPopupVisibleChange: Function as PropType<(open: boolean) => void>,
|
||||
onDropdownVisibleChange: Function as PropType<(open: boolean) => void>,
|
||||
|
||||
// Icon
|
||||
expandIcon: PropTypes.any,
|
||||
loadingIcon: PropTypes.any,
|
||||
};
|
||||
}
|
||||
|
||||
export type BaseCascaderProps = Partial<ExtractPropTypes<ReturnType<typeof baseCascaderProps>>>;
|
||||
|
||||
type OnSingleChange<OptionType> = (value: SingleValueType, selectOptions: OptionType[]) => void;
|
||||
type OnMultipleChange<OptionType> = (
|
||||
value: SingleValueType[],
|
||||
selectOptions: OptionType[][],
|
||||
) => void;
|
||||
|
||||
export function singleCascaderProps<OptionType extends BaseOptionType = DefaultOptionType>() {
|
||||
return {
|
||||
...baseCascaderProps(),
|
||||
checkable: Boolean as PropType<false>,
|
||||
onChange: Function as PropType<OnSingleChange<OptionType>>,
|
||||
};
|
||||
}
|
||||
|
||||
export type SingleCascaderProps = Partial<ExtractPropTypes<ReturnType<typeof singleCascaderProps>>>;
|
||||
|
||||
export function multipleCascaderProps<OptionType extends BaseOptionType = DefaultOptionType>() {
|
||||
return {
|
||||
...baseCascaderProps(),
|
||||
checkable: Boolean as PropType<true>,
|
||||
onChange: Function as PropType<OnMultipleChange<OptionType>>,
|
||||
};
|
||||
}
|
||||
|
||||
export type MultipleCascaderProps = Partial<
|
||||
ExtractPropTypes<ReturnType<typeof singleCascaderProps>>
|
||||
>;
|
||||
|
||||
export function internalCascaderProps<OptionType extends BaseOptionType = DefaultOptionType>() {
|
||||
return {
|
||||
...baseCascaderProps(),
|
||||
onChange: Function as PropType<
|
||||
(value: ValueType, selectOptions: OptionType[] | OptionType[][]) => void
|
||||
>,
|
||||
customSlots: Object as PropType<Record<string, Function>>,
|
||||
};
|
||||
}
|
||||
|
||||
export type CascaderProps = Partial<ExtractPropTypes<ReturnType<typeof internalCascaderProps>>>;
|
||||
export type CascaderRef = Omit<BaseSelectRef, 'scrollTo'>;
|
||||
|
||||
function isMultipleValue(value: ValueType): value is SingleValueType[] {
|
||||
return Array.isArray(value) && Array.isArray(value[0]);
|
||||
}
|
||||
|
||||
function toRawValues(value: ValueType): SingleValueType[] {
|
||||
if (!value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (isMultipleValue(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return value.length === 0 ? [] : [value];
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Cascader',
|
||||
inheritAttrs: false,
|
||||
props: initDefaultProps(internalCascaderProps(), {}),
|
||||
setup(props, { attrs, expose, slots }) {
|
||||
const mergedId = useId(toRef(props, 'id'));
|
||||
const multiple = computed(() => !!props.checkable);
|
||||
|
||||
// =========================== Values ===========================
|
||||
const [rawValues, setRawValues] = useMergedState<ValueType, Ref<SingleValueType[]>>(
|
||||
props.defaultValue,
|
||||
{
|
||||
value: computed(() => props.value),
|
||||
postState: toRawValues,
|
||||
},
|
||||
);
|
||||
|
||||
// ========================= FieldNames =========================
|
||||
const mergedFieldNames = computed(() => fillFieldNames(props.fieldNames));
|
||||
|
||||
// =========================== Option ===========================
|
||||
const mergedOptions = computed(() => props.options || []);
|
||||
|
||||
// Only used in multiple mode, this fn will not call in single mode
|
||||
const pathKeyEntities = useEntities(mergedOptions, mergedFieldNames);
|
||||
|
||||
/** Convert path key back to value format */
|
||||
const getValueByKeyPath = (pathKeys: Key[]): SingleValueType[] => {
|
||||
const ketPathEntities = pathKeyEntities.value;
|
||||
|
||||
return pathKeys.map(pathKey => {
|
||||
const { nodes } = ketPathEntities[pathKey];
|
||||
|
||||
return nodes.map(node => node[mergedFieldNames.value.value]);
|
||||
});
|
||||
};
|
||||
|
||||
// =========================== Search ===========================
|
||||
const [mergedSearchValue, setSearchValue] = useMergedState('', {
|
||||
value: computed(() => props.searchValue),
|
||||
postState: search => search || '',
|
||||
});
|
||||
|
||||
const onInternalSearch: BaseSelectProps['onSearch'] = (searchText, info) => {
|
||||
setSearchValue(searchText);
|
||||
|
||||
if (info.source !== 'blur' && props.onSearch) {
|
||||
props.onSearch(searchText);
|
||||
}
|
||||
};
|
||||
|
||||
const { showSearch: mergedShowSearch, searchConfig: mergedSearchConfig } = useSearchConfig(
|
||||
toRef(props, 'showSearch'),
|
||||
);
|
||||
|
||||
const searchOptions = useSearchOptions(
|
||||
mergedSearchValue,
|
||||
mergedOptions,
|
||||
mergedFieldNames,
|
||||
computed(() => props.dropdownPrefixCls || props.prefixCls),
|
||||
mergedSearchConfig,
|
||||
toRef(props, 'changeOnSelect'),
|
||||
);
|
||||
|
||||
// =========================== Values ===========================
|
||||
const missingValuesInfo = useMissingValues(mergedOptions, mergedFieldNames, rawValues);
|
||||
|
||||
// Fill `rawValues` with checked conduction values
|
||||
const [checkedValues, halfCheckedValues, missingCheckedValues] = [
|
||||
ref<SingleValueType[]>([]),
|
||||
ref<SingleValueType[]>([]),
|
||||
ref<SingleValueType[]>([]),
|
||||
];
|
||||
watchEffect(() => {
|
||||
const [existValues, missingValues] = missingValuesInfo.value;
|
||||
|
||||
if (!multiple.value || !rawValues.value.length) {
|
||||
[checkedValues.value, halfCheckedValues.value, missingCheckedValues.value] = [
|
||||
existValues,
|
||||
[],
|
||||
missingValues,
|
||||
];
|
||||
return;
|
||||
}
|
||||
|
||||
const keyPathValues = toPathKeys(existValues);
|
||||
const ketPathEntities = pathKeyEntities.value;
|
||||
|
||||
const { checkedKeys, halfCheckedKeys } = conductCheck(keyPathValues, true, ketPathEntities);
|
||||
|
||||
// Convert key back to value cells
|
||||
[checkedValues.value, halfCheckedValues.value, missingCheckedValues.value] = [
|
||||
getValueByKeyPath(checkedKeys),
|
||||
getValueByKeyPath(halfCheckedKeys),
|
||||
missingValues,
|
||||
];
|
||||
});
|
||||
|
||||
const deDuplicatedValues = computed(() => {
|
||||
const checkedKeys = toPathKeys(checkedValues.value);
|
||||
const deduplicateKeys = formatStrategyValues(checkedKeys, pathKeyEntities.value);
|
||||
return [...missingCheckedValues.value, ...getValueByKeyPath(deduplicateKeys)];
|
||||
});
|
||||
|
||||
const displayValues = useDisplayValues(
|
||||
deDuplicatedValues,
|
||||
mergedOptions,
|
||||
mergedFieldNames,
|
||||
multiple,
|
||||
toRef(props, 'displayRender'),
|
||||
);
|
||||
|
||||
// =========================== Change ===========================
|
||||
const triggerChange = (nextValues: ValueType) => {
|
||||
setRawValues(nextValues);
|
||||
|
||||
// Save perf if no need trigger event
|
||||
if (props.onChange) {
|
||||
const nextRawValues = toRawValues(nextValues);
|
||||
|
||||
const valueOptions = nextRawValues.map(valueCells =>
|
||||
toPathOptions(valueCells, mergedOptions.value, mergedFieldNames.value).map(
|
||||
valueOpt => valueOpt.option,
|
||||
),
|
||||
);
|
||||
|
||||
const triggerValues = multiple.value ? nextRawValues : nextRawValues[0];
|
||||
const triggerOptions = multiple.value ? valueOptions : valueOptions[0];
|
||||
|
||||
props.onChange(triggerValues, triggerOptions);
|
||||
}
|
||||
};
|
||||
|
||||
// =========================== Select ===========================
|
||||
const onInternalSelect = (valuePath: SingleValueType) => {
|
||||
if (!multiple.value) {
|
||||
triggerChange(valuePath);
|
||||
} else {
|
||||
// Prepare conduct required info
|
||||
const pathKey = toPathKey(valuePath);
|
||||
const checkedPathKeys = toPathKeys(checkedValues.value);
|
||||
const halfCheckedPathKeys = toPathKeys(halfCheckedValues.value);
|
||||
|
||||
const existInChecked = checkedPathKeys.includes(pathKey);
|
||||
const existInMissing = missingCheckedValues.value.some(
|
||||
valueCells => toPathKey(valueCells) === pathKey,
|
||||
);
|
||||
|
||||
// Do update
|
||||
let nextCheckedValues = checkedValues.value;
|
||||
let nextMissingValues = missingCheckedValues.value;
|
||||
|
||||
if (existInMissing && !existInChecked) {
|
||||
// Missing value only do filter
|
||||
nextMissingValues = missingCheckedValues.value.filter(
|
||||
valueCells => toPathKey(valueCells) !== pathKey,
|
||||
);
|
||||
} else {
|
||||
// Update checked key first
|
||||
const nextRawCheckedKeys = existInChecked
|
||||
? checkedPathKeys.filter(key => key !== pathKey)
|
||||
: [...checkedPathKeys, pathKey];
|
||||
|
||||
// Conduction by selected or not
|
||||
let checkedKeys: Key[];
|
||||
if (existInChecked) {
|
||||
({ checkedKeys } = conductCheck(
|
||||
nextRawCheckedKeys,
|
||||
{ checked: false, halfCheckedKeys: halfCheckedPathKeys },
|
||||
pathKeyEntities.value,
|
||||
));
|
||||
} else {
|
||||
({ checkedKeys } = conductCheck(nextRawCheckedKeys, true, pathKeyEntities.value));
|
||||
}
|
||||
|
||||
// Roll up to parent level keys
|
||||
const deDuplicatedKeys = formatStrategyValues(checkedKeys, pathKeyEntities.value);
|
||||
nextCheckedValues = getValueByKeyPath(deDuplicatedKeys);
|
||||
}
|
||||
|
||||
triggerChange([...nextMissingValues, ...nextCheckedValues]);
|
||||
}
|
||||
};
|
||||
|
||||
// Display Value change logic
|
||||
const onDisplayValuesChange: BaseSelectProps['onDisplayValuesChange'] = (_, info) => {
|
||||
if (info.type === 'clear') {
|
||||
triggerChange([]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Cascader do not support `add` type. Only support `remove`
|
||||
const { valueCells } = info.values[0] as DisplayValueType & { valueCells: SingleValueType };
|
||||
onInternalSelect(valueCells);
|
||||
};
|
||||
|
||||
// ============================ Open ============================
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
watchEffect(() => {
|
||||
devWarning(
|
||||
!props.onPopupVisibleChange,
|
||||
'Cascader',
|
||||
'`popupVisibleChange` is deprecated. Please use `dropdownVisibleChange` instead.',
|
||||
);
|
||||
devWarning(
|
||||
props.popupVisible === undefined,
|
||||
'Cascader',
|
||||
'`popupVisible` is deprecated. Please use `open` instead.',
|
||||
);
|
||||
devWarning(
|
||||
props.popupClassName === undefined,
|
||||
'Cascader',
|
||||
'`popupClassName` is deprecated. Please use `dropdownClassName` instead.',
|
||||
);
|
||||
devWarning(
|
||||
props.popupPlacement === undefined,
|
||||
'Cascader',
|
||||
'`popupPlacement` is deprecated. Please use `placement` instead.',
|
||||
);
|
||||
devWarning(
|
||||
props.popupStyle === undefined,
|
||||
'Cascader',
|
||||
'`popupStyle` is deprecated. Please use `dropdownStyle` instead.',
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const mergedOpen = computed(() => (props.open !== undefined ? props.open : props.popupVisible));
|
||||
|
||||
const mergedDropdownClassName = computed(() => props.dropdownClassName || props.popupClassName);
|
||||
|
||||
const mergedDropdownStyle = computed(() => props.dropdownStyle || props.popupStyle || {});
|
||||
|
||||
const mergedPlacement = computed(() => props.placement || props.popupPlacement);
|
||||
|
||||
const onInternalDropdownVisibleChange = (nextVisible: boolean) => {
|
||||
props.onDropdownVisibleChange?.(nextVisible);
|
||||
props.onPopupVisibleChange?.(nextVisible);
|
||||
};
|
||||
const {
|
||||
changeOnSelect,
|
||||
checkable,
|
||||
dropdownPrefixCls,
|
||||
loadData,
|
||||
expandTrigger,
|
||||
expandIcon,
|
||||
loadingIcon,
|
||||
dropdownMenuColumnStyle,
|
||||
customSlots,
|
||||
} = toRefs(props);
|
||||
useProvideCascader({
|
||||
options: mergedOptions,
|
||||
fieldNames: mergedFieldNames,
|
||||
values: checkedValues,
|
||||
halfValues: halfCheckedValues,
|
||||
changeOnSelect,
|
||||
onSelect: onInternalSelect,
|
||||
checkable,
|
||||
searchOptions,
|
||||
dropdownPrefixCls,
|
||||
loadData,
|
||||
expandTrigger,
|
||||
expandIcon,
|
||||
loadingIcon,
|
||||
dropdownMenuColumnStyle,
|
||||
customSlots,
|
||||
});
|
||||
const selectRef = ref<BaseSelectRef>();
|
||||
|
||||
expose({
|
||||
focus() {
|
||||
selectRef.value?.focus();
|
||||
},
|
||||
blur() {
|
||||
selectRef.value?.blur();
|
||||
},
|
||||
scrollTo(arg) {
|
||||
selectRef.value?.scrollTo(arg);
|
||||
},
|
||||
} as BaseSelectRef);
|
||||
|
||||
const pickProps = computed(() => {
|
||||
return omit(props, [
|
||||
'id',
|
||||
'prefixCls',
|
||||
'fieldNames',
|
||||
|
||||
// Value
|
||||
'defaultValue',
|
||||
'value',
|
||||
'changeOnSelect',
|
||||
'onChange',
|
||||
'displayRender',
|
||||
'checkable',
|
||||
|
||||
// Search
|
||||
'searchValue',
|
||||
'onSearch',
|
||||
'showSearch',
|
||||
|
||||
// Trigger
|
||||
'expandTrigger',
|
||||
|
||||
// Options
|
||||
'options',
|
||||
'dropdownPrefixCls',
|
||||
'loadData',
|
||||
|
||||
// Open
|
||||
'popupVisible',
|
||||
'open',
|
||||
|
||||
'popupClassName',
|
||||
'dropdownClassName',
|
||||
'dropdownMenuColumnStyle',
|
||||
|
||||
'popupPlacement',
|
||||
'placement',
|
||||
|
||||
'onDropdownVisibleChange',
|
||||
'onPopupVisibleChange',
|
||||
|
||||
// Icon
|
||||
'expandIcon',
|
||||
'loadingIcon',
|
||||
'customSlots',
|
||||
|
||||
// Children
|
||||
'children',
|
||||
]);
|
||||
});
|
||||
return () => {
|
||||
const emptyOptions = !(mergedSearchValue.value ? searchOptions.value : mergedOptions.value)
|
||||
.length;
|
||||
|
||||
const dropdownStyle: CSSProperties =
|
||||
// Search to match width
|
||||
(mergedSearchValue.value && mergedSearchConfig.value.matchInputWidth) ||
|
||||
// Empty keep the width
|
||||
emptyOptions
|
||||
? {}
|
||||
: {
|
||||
minWidth: 'auto',
|
||||
};
|
||||
return (
|
||||
<BaseSelect
|
||||
{...pickProps.value}
|
||||
{...attrs}
|
||||
// MISC
|
||||
ref={selectRef}
|
||||
id={mergedId}
|
||||
prefixCls={props.prefixCls}
|
||||
dropdownMatchSelectWidth={false}
|
||||
dropdownStyle={{ ...mergedDropdownStyle.value, ...dropdownStyle }}
|
||||
// Value
|
||||
displayValues={displayValues.value}
|
||||
onDisplayValuesChange={onDisplayValuesChange}
|
||||
mode={multiple.value ? 'multiple' : undefined}
|
||||
// Search
|
||||
searchValue={mergedSearchValue.value}
|
||||
onSearch={onInternalSearch}
|
||||
showSearch={mergedShowSearch.value}
|
||||
// Options
|
||||
OptionList={OptionList}
|
||||
emptyOptions={emptyOptions}
|
||||
// Open
|
||||
open={mergedOpen.value}
|
||||
dropdownClassName={mergedDropdownClassName.value}
|
||||
placement={mergedPlacement.value}
|
||||
onDropdownVisibleChange={onInternalDropdownVisibleChange}
|
||||
// Children
|
||||
getRawInputElement={() => slots.default?.()}
|
||||
v-slots={slots}
|
||||
/>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
import { getComponent, findDOMNode } from '../_util/props-util';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import arrayTreeFilter from 'array-tree-filter';
|
||||
import BaseMixin from '../_util/BaseMixin';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
|
||||
export default {
|
||||
name: 'CascaderMenus',
|
||||
mixins: [BaseMixin],
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
value: PropTypes.array.def([]),
|
||||
activeValue: PropTypes.array.def([]),
|
||||
options: PropTypes.array,
|
||||
prefixCls: PropTypes.string.def('rc-cascader-menus'),
|
||||
expandTrigger: PropTypes.string.def('click'),
|
||||
// onSelect: PropTypes.func,
|
||||
visible: PropTypes.looseBool.def(false),
|
||||
dropdownMenuColumnStyle: PropTypes.object,
|
||||
defaultFieldNames: PropTypes.object,
|
||||
fieldNames: PropTypes.object,
|
||||
expandIcon: PropTypes.any,
|
||||
loadingIcon: PropTypes.any,
|
||||
},
|
||||
data() {
|
||||
this.menuItems = {};
|
||||
return {};
|
||||
},
|
||||
watch: {
|
||||
visible(val) {
|
||||
if (val) {
|
||||
this.$nextTick(() => {
|
||||
this.scrollActiveItemToView();
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.scrollActiveItemToView();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
getFieldName(name) {
|
||||
const { fieldNames, defaultFieldNames } = this.$props;
|
||||
// 防止只设置单个属性的名字
|
||||
return fieldNames[name] || defaultFieldNames[name];
|
||||
},
|
||||
getOption(option, menuIndex) {
|
||||
const { prefixCls, expandTrigger } = this;
|
||||
const loadingIcon = getComponent(this, 'loadingIcon');
|
||||
const expandIcon = getComponent(this, 'expandIcon');
|
||||
const onSelect = e => {
|
||||
this.__emit('select', option, menuIndex, e);
|
||||
};
|
||||
const onItemDoubleClick = e => {
|
||||
this.__emit('itemDoubleClick', option, menuIndex, e);
|
||||
};
|
||||
const key = option[this.getFieldName('value')];
|
||||
let expandProps = {
|
||||
onClick: onSelect,
|
||||
onDblclick: onItemDoubleClick,
|
||||
};
|
||||
let menuItemCls = `${prefixCls}-menu-item`;
|
||||
let expandIconNode = null;
|
||||
const hasChildren =
|
||||
option[this.getFieldName('children')] && option[this.getFieldName('children')].length > 0;
|
||||
if (hasChildren || option.isLeaf === false) {
|
||||
menuItemCls += ` ${prefixCls}-menu-item-expand`;
|
||||
if (!option.loading) {
|
||||
expandIconNode = <span class={`${prefixCls}-menu-item-expand-icon`}>{expandIcon}</span>;
|
||||
}
|
||||
}
|
||||
if (expandTrigger === 'hover' && (hasChildren || option.isLeaf === false)) {
|
||||
expandProps = {
|
||||
onMouseenter: this.delayOnSelect.bind(this, onSelect),
|
||||
onMouseleave: this.delayOnSelect.bind(this),
|
||||
onClick: onSelect,
|
||||
};
|
||||
}
|
||||
if (this.isActiveOption(option, menuIndex)) {
|
||||
menuItemCls += ` ${prefixCls}-menu-item-active`;
|
||||
expandProps.ref = this.saveMenuItem(menuIndex);
|
||||
}
|
||||
if (option.disabled) {
|
||||
menuItemCls += ` ${prefixCls}-menu-item-disabled`;
|
||||
}
|
||||
let loadingIconNode = null;
|
||||
if (option.loading) {
|
||||
menuItemCls += ` ${prefixCls}-menu-item-loading`;
|
||||
loadingIconNode = loadingIcon || null;
|
||||
}
|
||||
let title = '';
|
||||
if (option.title) {
|
||||
title = option.title;
|
||||
} else if (typeof option[this.getFieldName('label')] === 'string') {
|
||||
title = option[this.getFieldName('label')];
|
||||
}
|
||||
return (
|
||||
<li
|
||||
key={Array.isArray(key) ? key.join('__ant__') : key}
|
||||
class={menuItemCls}
|
||||
title={title}
|
||||
{...expandProps}
|
||||
role="menuitem"
|
||||
onMousedown={e => e.preventDefault()}
|
||||
>
|
||||
{option[this.getFieldName('label')]}
|
||||
{expandIconNode}
|
||||
{loadingIconNode}
|
||||
</li>
|
||||
);
|
||||
},
|
||||
|
||||
getActiveOptions(values) {
|
||||
const activeValue = values || this.activeValue;
|
||||
const options = this.options;
|
||||
return arrayTreeFilter(
|
||||
options,
|
||||
(o, level) => isEqual(o[this.getFieldName('value')], activeValue[level]),
|
||||
{ childrenKeyName: this.getFieldName('children') },
|
||||
);
|
||||
},
|
||||
|
||||
getShowOptions() {
|
||||
const { options } = this;
|
||||
const result = this.getActiveOptions()
|
||||
.map(activeOption => activeOption[this.getFieldName('children')])
|
||||
.filter(activeOption => !!activeOption);
|
||||
result.unshift(options);
|
||||
return result;
|
||||
},
|
||||
|
||||
delayOnSelect(onSelect, ...args) {
|
||||
if (this.delayTimer) {
|
||||
clearTimeout(this.delayTimer);
|
||||
this.delayTimer = null;
|
||||
}
|
||||
if (typeof onSelect === 'function') {
|
||||
this.delayTimer = setTimeout(() => {
|
||||
onSelect(args);
|
||||
this.delayTimer = null;
|
||||
}, 150);
|
||||
}
|
||||
},
|
||||
|
||||
scrollActiveItemToView() {
|
||||
// scroll into view
|
||||
const optionsLength = this.getShowOptions().length;
|
||||
for (let i = 0; i < optionsLength; i++) {
|
||||
const itemComponent = this.menuItems[i];
|
||||
if (itemComponent) {
|
||||
const target = findDOMNode(itemComponent);
|
||||
target.parentNode.scrollTop = target.offsetTop;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isActiveOption(option, menuIndex) {
|
||||
const { activeValue = [] } = this;
|
||||
return isEqual(activeValue[menuIndex], option[this.getFieldName('value')]);
|
||||
},
|
||||
saveMenuItem(index) {
|
||||
return node => {
|
||||
this.menuItems[index] = node;
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { prefixCls, dropdownMenuColumnStyle } = this;
|
||||
return (
|
||||
<div>
|
||||
{this.getShowOptions().map((options, menuIndex) => (
|
||||
<ul class={`${prefixCls}-menu`} key={menuIndex} style={dropdownMenuColumnStyle}>
|
||||
{options.map(option => this.getOption(option, menuIndex))}
|
||||
</ul>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import type { MouseEventHandler } from '../../_util/EventInterface';
|
||||
import { useInjectCascader } from '../context';
|
||||
|
||||
export interface CheckboxProps {
|
||||
prefixCls: string;
|
||||
checked?: boolean;
|
||||
halfChecked?: boolean;
|
||||
disabled?: boolean;
|
||||
onClick?: MouseEventHandler;
|
||||
}
|
||||
|
||||
export default function Checkbox({
|
||||
prefixCls,
|
||||
checked,
|
||||
halfChecked,
|
||||
disabled,
|
||||
onClick,
|
||||
}: CheckboxProps) {
|
||||
const { customSlots, checkable } = useInjectCascader();
|
||||
|
||||
const mergedCheckable = checkable.value !== false ? customSlots.value.checkable : checkable.value;
|
||||
const customCheckbox =
|
||||
typeof mergedCheckable === 'function'
|
||||
? mergedCheckable()
|
||||
: typeof mergedCheckable === 'boolean'
|
||||
? null
|
||||
: mergedCheckable;
|
||||
return (
|
||||
<span
|
||||
class={{
|
||||
[prefixCls]: true,
|
||||
[`${prefixCls}-checked`]: checked,
|
||||
[`${prefixCls}-indeterminate`]: !checked && halfChecked,
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
}}
|
||||
onClick={onClick}
|
||||
>
|
||||
{customCheckbox}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Checkbox.props = ['prefixCls', 'checked', 'halfChecked', 'disabled', 'onClick'];
|
||||
Checkbox.displayName = 'Checkbox';
|
||||
Checkbox.inheritAttrs = false;
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
import { isLeaf, toPathKey } from '../utils/commonUtil';
|
||||
import Checkbox from './Checkbox';
|
||||
import type { DefaultOptionType, SingleValueType } from '../Cascader';
|
||||
import { SEARCH_MARK } from '../hooks/useSearchOptions';
|
||||
import type { Key } from '../../_util/type';
|
||||
import { useInjectCascader } from '../context';
|
||||
|
||||
export interface ColumnProps {
|
||||
prefixCls: string;
|
||||
multiple?: boolean;
|
||||
options: DefaultOptionType[];
|
||||
/** Current Column opened item key */
|
||||
activeValue?: Key;
|
||||
/** The value path before current column */
|
||||
prevValuePath: Key[];
|
||||
onToggleOpen: (open: boolean) => void;
|
||||
onSelect: (valuePath: SingleValueType, leaf: boolean) => void;
|
||||
onActive: (valuePath: SingleValueType) => void;
|
||||
checkedSet: Set<Key>;
|
||||
halfCheckedSet: Set<Key>;
|
||||
loadingKeys: Key[];
|
||||
isSelectable: (option: DefaultOptionType) => boolean;
|
||||
}
|
||||
|
||||
export default function Column({
|
||||
prefixCls,
|
||||
multiple,
|
||||
options,
|
||||
activeValue,
|
||||
prevValuePath,
|
||||
onToggleOpen,
|
||||
onSelect,
|
||||
onActive,
|
||||
checkedSet,
|
||||
halfCheckedSet,
|
||||
loadingKeys,
|
||||
isSelectable,
|
||||
}: ColumnProps) {
|
||||
const menuPrefixCls = `${prefixCls}-menu`;
|
||||
const menuItemPrefixCls = `${prefixCls}-menu-item`;
|
||||
|
||||
const {
|
||||
fieldNames,
|
||||
changeOnSelect,
|
||||
expandTrigger,
|
||||
expandIcon: expandIconRef,
|
||||
loadingIcon: loadingIconRef,
|
||||
dropdownMenuColumnStyle,
|
||||
customSlots,
|
||||
} = useInjectCascader();
|
||||
const expandIcon = expandIconRef.value ?? customSlots.value.expandIcon?.();
|
||||
const loadingIcon = loadingIconRef.value ?? customSlots.value.loadingIcon?.();
|
||||
|
||||
const hoverOpen = expandTrigger.value === 'hover';
|
||||
// ============================ Render ============================
|
||||
return (
|
||||
<ul class={menuPrefixCls} role="menu">
|
||||
{options.map(option => {
|
||||
const { disabled } = option;
|
||||
const searchOptions = option[SEARCH_MARK];
|
||||
const label = option[fieldNames.value.label];
|
||||
const value = option[fieldNames.value.value];
|
||||
|
||||
const isMergedLeaf = isLeaf(option, fieldNames.value);
|
||||
|
||||
// Get real value of option. Search option is different way.
|
||||
const fullPath = searchOptions
|
||||
? searchOptions.map(opt => opt[fieldNames.value.value])
|
||||
: [...prevValuePath, value];
|
||||
const fullPathKey = toPathKey(fullPath);
|
||||
|
||||
const isLoading = loadingKeys.includes(fullPathKey);
|
||||
|
||||
// >>>>> checked
|
||||
const checked = checkedSet.has(fullPathKey);
|
||||
|
||||
// >>>>> halfChecked
|
||||
const halfChecked = halfCheckedSet.has(fullPathKey);
|
||||
// >>>>> Open
|
||||
const triggerOpenPath = () => {
|
||||
if (!disabled && (!hoverOpen || !isMergedLeaf)) {
|
||||
onActive(fullPath);
|
||||
}
|
||||
};
|
||||
|
||||
// >>>>> Selection
|
||||
const triggerSelect = () => {
|
||||
if (isSelectable(option)) {
|
||||
onSelect(fullPath, isMergedLeaf);
|
||||
}
|
||||
};
|
||||
|
||||
// >>>>> Title
|
||||
let title: string;
|
||||
if (typeof option.title === 'string') {
|
||||
title = option.title;
|
||||
} else if (typeof label === 'string') {
|
||||
title = label;
|
||||
}
|
||||
|
||||
// >>>>> Render
|
||||
return (
|
||||
<li
|
||||
key={fullPathKey}
|
||||
class={[
|
||||
menuItemPrefixCls,
|
||||
{
|
||||
[`${menuItemPrefixCls}-expand`]: !isMergedLeaf,
|
||||
[`${menuItemPrefixCls}-active`]: activeValue === value,
|
||||
[`${menuItemPrefixCls}-disabled`]: disabled,
|
||||
[`${menuItemPrefixCls}-loading`]: isLoading,
|
||||
},
|
||||
]}
|
||||
style={dropdownMenuColumnStyle.value}
|
||||
role="menuitemcheckbox"
|
||||
title={title}
|
||||
aria-checked={checked}
|
||||
data-path-key={fullPathKey}
|
||||
onClick={() => {
|
||||
triggerOpenPath();
|
||||
if (!multiple || isMergedLeaf) {
|
||||
triggerSelect();
|
||||
}
|
||||
}}
|
||||
onDblclick={() => {
|
||||
if (changeOnSelect.value) {
|
||||
onToggleOpen(false);
|
||||
}
|
||||
}}
|
||||
onMouseenter={() => {
|
||||
if (hoverOpen) {
|
||||
triggerOpenPath();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{multiple && (
|
||||
<Checkbox
|
||||
prefixCls={`${prefixCls}-checkbox`}
|
||||
checked={checked}
|
||||
halfChecked={halfChecked}
|
||||
disabled={disabled}
|
||||
onClick={(e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
triggerSelect();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div class={`${menuItemPrefixCls}-content`}>{option[fieldNames.value.label]}</div>
|
||||
{!isLoading && expandIcon && !isMergedLeaf && (
|
||||
<div class={`${menuItemPrefixCls}-expand-icon`}>{expandIcon}</div>
|
||||
)}
|
||||
{isLoading && loadingIcon && (
|
||||
<div class={`${menuItemPrefixCls}-loading-icon`}>{loadingIcon}</div>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
Column.props = [
|
||||
'prefixCls',
|
||||
'multiple',
|
||||
'options',
|
||||
'activeValue',
|
||||
'prevValuePath',
|
||||
'onToggleOpen',
|
||||
'onSelect',
|
||||
'onActive',
|
||||
'checkedSet',
|
||||
'halfCheckedSet',
|
||||
'loadingKeys',
|
||||
'isSelectable',
|
||||
];
|
||||
Column.displayName = 'Column';
|
||||
Column.inheritAttrs = false;
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
/* eslint-disable default-case */
|
||||
import Column from './Column';
|
||||
import type { DefaultOptionType, SingleValueType } from '../Cascader';
|
||||
import { isLeaf, toPathKey, toPathKeys, toPathValueStr } from '../utils/commonUtil';
|
||||
import useActive from './useActive';
|
||||
import useKeyboard from './useKeyboard';
|
||||
import { toPathOptions } from '../utils/treeUtil';
|
||||
import { computed, defineComponent, ref, shallowRef, watchEffect } from 'vue';
|
||||
import { useBaseProps } from '../../vc-select';
|
||||
import { useInjectCascader } from '../context';
|
||||
import type { Key } from '../../_util/type';
|
||||
import type { EventHandler } from '../../_util/EventInterface';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'OptionList',
|
||||
inheritAttrs: false,
|
||||
setup(_props, context) {
|
||||
const { attrs, slots } = context;
|
||||
const baseProps = useBaseProps();
|
||||
const containerRef = ref<HTMLDivElement>();
|
||||
const rtl = computed(() => baseProps.direction === 'rtl');
|
||||
const {
|
||||
options,
|
||||
values,
|
||||
halfValues,
|
||||
fieldNames,
|
||||
changeOnSelect,
|
||||
onSelect,
|
||||
searchOptions,
|
||||
dropdownPrefixCls,
|
||||
loadData,
|
||||
expandTrigger,
|
||||
customSlots,
|
||||
} = useInjectCascader();
|
||||
|
||||
const mergedPrefixCls = computed(() => dropdownPrefixCls.value || baseProps.prefixCls);
|
||||
|
||||
// ========================= loadData =========================
|
||||
const loadingKeys = shallowRef<string[]>([]);
|
||||
const internalLoadData = (valueCells: Key[]) => {
|
||||
// Do not load when search
|
||||
if (!loadData.value || baseProps.searchValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
const optionList = toPathOptions(valueCells, options.value, fieldNames.value);
|
||||
const rawOptions = optionList.map(({ option }) => option);
|
||||
const lastOption = rawOptions[rawOptions.length - 1];
|
||||
|
||||
if (lastOption && !isLeaf(lastOption, fieldNames.value)) {
|
||||
const pathKey = toPathKey(valueCells);
|
||||
|
||||
loadingKeys.value = [...loadingKeys.value, pathKey];
|
||||
loadData.value(rawOptions);
|
||||
}
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
if (loadingKeys.value.length) {
|
||||
loadingKeys.value.forEach(loadingKey => {
|
||||
const valueStrCells = toPathValueStr(loadingKey);
|
||||
const optionList = toPathOptions(
|
||||
valueStrCells,
|
||||
options.value,
|
||||
fieldNames.value,
|
||||
true,
|
||||
).map(({ option }) => option);
|
||||
const lastOption = optionList[optionList.length - 1];
|
||||
|
||||
if (
|
||||
!lastOption ||
|
||||
lastOption[fieldNames.value.children] ||
|
||||
isLeaf(lastOption, fieldNames.value)
|
||||
) {
|
||||
loadingKeys.value = loadingKeys.value.filter(key => key !== loadingKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// ========================== Values ==========================
|
||||
const checkedSet = computed(() => new Set(toPathKeys(values.value)));
|
||||
const halfCheckedSet = computed(() => new Set(toPathKeys(halfValues.value)));
|
||||
|
||||
// ====================== Accessibility =======================
|
||||
const [activeValueCells, setActiveValueCells] = useActive();
|
||||
|
||||
// =========================== Path ===========================
|
||||
const onPathOpen = (nextValueCells: Key[]) => {
|
||||
setActiveValueCells(nextValueCells);
|
||||
|
||||
// Trigger loadData
|
||||
internalLoadData(nextValueCells);
|
||||
};
|
||||
|
||||
const isSelectable = (option: DefaultOptionType) => {
|
||||
const { disabled } = option;
|
||||
|
||||
const isMergedLeaf = isLeaf(option, fieldNames.value);
|
||||
return !disabled && (isMergedLeaf || changeOnSelect.value || baseProps.multiple);
|
||||
};
|
||||
|
||||
const onPathSelect = (valuePath: SingleValueType, leaf: boolean, fromKeyboard = false) => {
|
||||
onSelect(valuePath);
|
||||
|
||||
if (
|
||||
!baseProps.multiple &&
|
||||
(leaf || (changeOnSelect.value && (expandTrigger.value === 'hover' || fromKeyboard)))
|
||||
) {
|
||||
baseProps.toggleOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
// ========================== Option ==========================
|
||||
const mergedOptions = computed(() => {
|
||||
if (baseProps.searchValue) {
|
||||
return searchOptions.value;
|
||||
}
|
||||
|
||||
return options.value;
|
||||
});
|
||||
|
||||
// ========================== Column ==========================
|
||||
const optionColumns = computed(() => {
|
||||
const optionList = [{ options: mergedOptions.value }];
|
||||
let currentList = mergedOptions.value;
|
||||
for (let i = 0; i < activeValueCells.value.length; i += 1) {
|
||||
const activeValueCell = activeValueCells.value[i];
|
||||
const currentOption = currentList.find(
|
||||
option => option[fieldNames.value.value] === activeValueCell,
|
||||
);
|
||||
|
||||
const subOptions = currentOption?.[fieldNames.value.children];
|
||||
if (!subOptions?.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentList = subOptions;
|
||||
optionList.push({ options: subOptions });
|
||||
}
|
||||
|
||||
return optionList;
|
||||
});
|
||||
|
||||
// ========================= Keyboard =========================
|
||||
const onKeyboardSelect = (selectValueCells: SingleValueType, option: DefaultOptionType) => {
|
||||
if (isSelectable(option)) {
|
||||
onPathSelect(selectValueCells, isLeaf(option, fieldNames.value), true);
|
||||
}
|
||||
};
|
||||
|
||||
useKeyboard(
|
||||
context,
|
||||
mergedOptions,
|
||||
fieldNames,
|
||||
activeValueCells,
|
||||
onPathOpen,
|
||||
containerRef,
|
||||
onKeyboardSelect,
|
||||
);
|
||||
const onListMouseDown: EventHandler = event => {
|
||||
event.preventDefault();
|
||||
};
|
||||
return () => {
|
||||
// ========================== Render ==========================
|
||||
const {
|
||||
notFoundContent = slots.notFoundContent?.() || customSlots.value.notFoundContent?.(),
|
||||
multiple,
|
||||
toggleOpen,
|
||||
} = baseProps;
|
||||
// >>>>> Empty
|
||||
const isEmpty = !optionColumns.value[0]?.options?.length;
|
||||
|
||||
const emptyList: DefaultOptionType[] = [
|
||||
{
|
||||
[fieldNames.value.label as 'label']: notFoundContent,
|
||||
[fieldNames.value.value as 'value']: '__EMPTY__',
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
const columnProps = {
|
||||
...attrs,
|
||||
multiple: !isEmpty && multiple,
|
||||
onSelect: onPathSelect,
|
||||
onActive: onPathOpen,
|
||||
onToggleOpen: toggleOpen,
|
||||
checkedSet: checkedSet.value,
|
||||
halfCheckedSet: halfCheckedSet.value,
|
||||
loadingKeys: loadingKeys.value,
|
||||
isSelectable,
|
||||
};
|
||||
|
||||
// >>>>> Columns
|
||||
const mergedOptionColumns = isEmpty ? [{ options: emptyList }] : optionColumns.value;
|
||||
|
||||
const columnNodes = mergedOptionColumns.map((col, index) => {
|
||||
const prevValuePath = activeValueCells.value.slice(0, index);
|
||||
const activeValue = activeValueCells.value[index];
|
||||
|
||||
return (
|
||||
<Column
|
||||
key={index}
|
||||
{...columnProps}
|
||||
prefixCls={mergedPrefixCls.value}
|
||||
options={col.options}
|
||||
prevValuePath={prevValuePath}
|
||||
activeValue={activeValue}
|
||||
/>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div
|
||||
class={[
|
||||
`${mergedPrefixCls.value}-menus`,
|
||||
{
|
||||
[`${mergedPrefixCls.value}-menu-empty`]: isEmpty,
|
||||
[`${mergedPrefixCls.value}-rtl`]: rtl.value,
|
||||
},
|
||||
]}
|
||||
onMousedown={onListMouseDown}
|
||||
ref={containerRef}
|
||||
>
|
||||
{columnNodes}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import { useInjectCascader } from '../context';
|
||||
import type { Ref } from 'vue';
|
||||
import { watch } from 'vue';
|
||||
import { useBaseProps } from '../../vc-select';
|
||||
import type { Key } from '../../_util/type';
|
||||
import useState from '../../_util/hooks/useState';
|
||||
|
||||
/**
|
||||
* Control the active open options path.
|
||||
*/
|
||||
export default (): [Ref<Key[]>, (activeValueCells: Key[]) => void] => {
|
||||
const baseProps = useBaseProps();
|
||||
const { values } = useInjectCascader();
|
||||
|
||||
// Record current dropdown active options
|
||||
// This also control the open status
|
||||
const [activeValueCells, setActiveValueCells] = useState<Key[]>([]);
|
||||
|
||||
watch(
|
||||
() => baseProps.open,
|
||||
() => {
|
||||
if (baseProps.open && !baseProps.multiple) {
|
||||
const firstValueCells = values.value[0];
|
||||
setActiveValueCells(firstValueCells || []);
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
return [activeValueCells, setActiveValueCells];
|
||||
};
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
import type { RefOptionListProps } from '../../vc-select/OptionList';
|
||||
import type { Key } from 'ant-design-vue/es/_util/type';
|
||||
import type { Ref, SetupContext } from 'vue';
|
||||
import { computed, ref, watchEffect } from 'vue';
|
||||
import type { DefaultOptionType, InternalFieldNames, SingleValueType } from '../Cascader';
|
||||
import { toPathKey } from '../utils/commonUtil';
|
||||
import { useBaseProps } from '../../vc-select';
|
||||
import KeyCode from '../../_util/KeyCode';
|
||||
|
||||
export default (
|
||||
context: SetupContext,
|
||||
options: Ref<DefaultOptionType[]>,
|
||||
fieldNames: Ref<InternalFieldNames>,
|
||||
activeValueCells: Ref<Key[]>,
|
||||
setActiveValueCells: (activeValueCells: Key[]) => void,
|
||||
containerRef: Ref<HTMLElement>,
|
||||
onKeyBoardSelect: (valueCells: SingleValueType, option: DefaultOptionType) => void,
|
||||
) => {
|
||||
const baseProps = useBaseProps();
|
||||
const rtl = computed(() => baseProps.direction === 'rtl');
|
||||
const [validActiveValueCells, lastActiveIndex, lastActiveOptions] = [
|
||||
ref<Key[]>([]),
|
||||
ref<number>(),
|
||||
ref<DefaultOptionType[]>([]),
|
||||
];
|
||||
watchEffect(() => {
|
||||
let activeIndex = -1;
|
||||
let currentOptions = options.value;
|
||||
|
||||
const mergedActiveIndexes: number[] = [];
|
||||
const mergedActiveValueCells: Key[] = [];
|
||||
|
||||
const len = activeValueCells.value.length;
|
||||
// Fill validate active value cells and index
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
// Mark the active index for current options
|
||||
const nextActiveIndex = currentOptions.findIndex(
|
||||
option => option[fieldNames.value.value] === activeValueCells.value[i],
|
||||
);
|
||||
|
||||
if (nextActiveIndex === -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
activeIndex = nextActiveIndex;
|
||||
mergedActiveIndexes.push(activeIndex);
|
||||
mergedActiveValueCells.push(activeValueCells.value[i]);
|
||||
|
||||
currentOptions = currentOptions[activeIndex][fieldNames.value.children];
|
||||
}
|
||||
|
||||
// Fill last active options
|
||||
let activeOptions = options.value;
|
||||
for (let i = 0; i < mergedActiveIndexes.length - 1; i += 1) {
|
||||
activeOptions = activeOptions[mergedActiveIndexes[i]][fieldNames.value.children];
|
||||
}
|
||||
|
||||
[validActiveValueCells.value, lastActiveIndex.value, lastActiveOptions.value] = [
|
||||
mergedActiveValueCells,
|
||||
activeIndex,
|
||||
activeOptions,
|
||||
];
|
||||
});
|
||||
|
||||
// Update active value cells and scroll to target element
|
||||
const internalSetActiveValueCells = (next: Key[]) => {
|
||||
setActiveValueCells(next);
|
||||
|
||||
const ele = containerRef.value?.querySelector(`li[data-path-key="${toPathKey(next)}"]`);
|
||||
ele?.scrollIntoView?.({ block: 'nearest' });
|
||||
};
|
||||
|
||||
// Same options offset
|
||||
const offsetActiveOption = (offset: number) => {
|
||||
const len = lastActiveOptions.value.length;
|
||||
|
||||
let currentIndex = lastActiveIndex.value;
|
||||
if (currentIndex === -1 && offset < 0) {
|
||||
currentIndex = len;
|
||||
}
|
||||
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
currentIndex = (currentIndex + offset + len) % len;
|
||||
const option = lastActiveOptions.value[currentIndex];
|
||||
|
||||
if (option && !option.disabled) {
|
||||
const value = option[fieldNames.value.value];
|
||||
const nextActiveCells = validActiveValueCells.value.slice(0, -1).concat(value);
|
||||
internalSetActiveValueCells(nextActiveCells);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Different options offset
|
||||
const prevColumn = () => {
|
||||
if (validActiveValueCells.value.length > 1) {
|
||||
const nextActiveCells = validActiveValueCells.value.slice(0, -1);
|
||||
internalSetActiveValueCells(nextActiveCells);
|
||||
} else {
|
||||
baseProps.toggleOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
const nextColumn = () => {
|
||||
const nextOptions: DefaultOptionType[] =
|
||||
lastActiveOptions.value[lastActiveIndex.value]?.[fieldNames.value.children] || [];
|
||||
|
||||
const nextOption = nextOptions.find(option => !option.disabled);
|
||||
|
||||
if (nextOption) {
|
||||
const nextActiveCells = [...validActiveValueCells.value, nextOption[fieldNames.value.value]];
|
||||
internalSetActiveValueCells(nextActiveCells);
|
||||
}
|
||||
};
|
||||
|
||||
context.expose({
|
||||
// scrollTo: treeRef.current?.scrollTo,
|
||||
onKeydown: event => {
|
||||
const { which } = event;
|
||||
|
||||
switch (which) {
|
||||
// >>> Arrow keys
|
||||
case KeyCode.UP:
|
||||
case KeyCode.DOWN: {
|
||||
let offset = 0;
|
||||
if (which === KeyCode.UP) {
|
||||
offset = -1;
|
||||
} else if (which === KeyCode.DOWN) {
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
if (offset !== 0) {
|
||||
offsetActiveOption(offset);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyCode.LEFT: {
|
||||
if (rtl.value) {
|
||||
nextColumn();
|
||||
} else {
|
||||
prevColumn();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyCode.RIGHT: {
|
||||
if (rtl.value) {
|
||||
prevColumn();
|
||||
} else {
|
||||
nextColumn();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyCode.BACKSPACE: {
|
||||
if (!baseProps.searchValue) {
|
||||
prevColumn();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// >>> Select
|
||||
case KeyCode.ENTER: {
|
||||
if (validActiveValueCells.value.length) {
|
||||
onKeyBoardSelect(
|
||||
validActiveValueCells.value,
|
||||
lastActiveOptions.value[lastActiveIndex.value],
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// >>> Close
|
||||
case KeyCode.ESC: {
|
||||
baseProps.toggleOpen(false);
|
||||
|
||||
if (open) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onKeyup: () => {},
|
||||
} as RefOptionListProps);
|
||||
};
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
.effect() {
|
||||
animation-duration: 0.3s;
|
||||
animation-fill-mode: both;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
.rc-cascader {
|
||||
font-size: 12px;
|
||||
&-menus {
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.17);
|
||||
white-space: nowrap;
|
||||
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.slide-up-enter,
|
||||
&.slide-up-appear {
|
||||
.effect();
|
||||
opacity: 0;
|
||||
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
&.slide-up-leave {
|
||||
.effect();
|
||||
opacity: 1;
|
||||
animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
&.slide-up-enter.slide-up-enter-active&-placement-bottomLeft,
|
||||
&.slide-up-appear.slide-up-appear-active&-placement-bottomLeft {
|
||||
animation-name: SlideUpIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&.slide-up-enter.slide-up-enter-active&-placement-topLeft,
|
||||
&.slide-up-appear.slide-up-appear-active&-placement-topLeft {
|
||||
animation-name: SlideDownIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&.slide-up-leave.slide-up-leave-active&-placement-bottomLeft {
|
||||
animation-name: SlideUpOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&.slide-up-leave.slide-up-leave-active&-placement-topLeft {
|
||||
animation-name: SlideDownOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
}
|
||||
&-menu {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 192px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-right: 1px solid #e9e9e9;
|
||||
overflow: auto;
|
||||
&:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
}
|
||||
&-menu-item {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0 16px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
&:hover {
|
||||
background: tint(#2db7f5, 90%);
|
||||
}
|
||||
&-disabled {
|
||||
cursor: not-allowed;
|
||||
color: #ccc;
|
||||
&:hover {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
&-loading:after {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
content: 'loading';
|
||||
color: #aaa;
|
||||
font-style: italic;
|
||||
}
|
||||
&-active {
|
||||
background: tint(#2db7f5, 80%);
|
||||
&:hover {
|
||||
background: tint(#2db7f5, 80%);
|
||||
}
|
||||
}
|
||||
&-expand {
|
||||
position: relative;
|
||||
&:after {
|
||||
content: '>';
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes SlideUpIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@keyframes SlideUpOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes SlideDownIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@keyframes SlideDownOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import type { CSSProperties, InjectionKey, Ref } from 'vue';
|
||||
import { inject, provide } from 'vue';
|
||||
import type { VueNode } from '../_util/type';
|
||||
import type {
|
||||
BaseCascaderProps,
|
||||
InternalFieldNames,
|
||||
DefaultOptionType,
|
||||
SingleValueType,
|
||||
} from './Cascader';
|
||||
|
||||
export interface CascaderContextProps {
|
||||
options: Ref<BaseCascaderProps['options']>;
|
||||
fieldNames: Ref<InternalFieldNames>;
|
||||
values: Ref<SingleValueType[]>;
|
||||
halfValues: Ref<SingleValueType[]>;
|
||||
changeOnSelect: Ref<boolean>;
|
||||
onSelect: (valuePath: SingleValueType) => void;
|
||||
checkable: Ref<boolean | VueNode>;
|
||||
searchOptions: Ref<DefaultOptionType[]>;
|
||||
dropdownPrefixCls?: Ref<string>;
|
||||
loadData: Ref<(selectOptions: DefaultOptionType[]) => void>;
|
||||
expandTrigger: Ref<'hover' | 'click'>;
|
||||
expandIcon: Ref<VueNode>;
|
||||
loadingIcon: Ref<VueNode>;
|
||||
dropdownMenuColumnStyle: Ref<CSSProperties>;
|
||||
customSlots: Ref<Record<string, Function>>;
|
||||
}
|
||||
|
||||
const CascaderContextKey: InjectionKey<CascaderContextProps> = Symbol('CascaderContextKey');
|
||||
export const useProvideCascader = (props: CascaderContextProps) => {
|
||||
provide(CascaderContextKey, props);
|
||||
};
|
||||
|
||||
export const useInjectCascader = () => {
|
||||
return inject(CascaderContextKey);
|
||||
};
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
import { toPathOptions } from '../utils/treeUtil';
|
||||
import type {
|
||||
DefaultOptionType,
|
||||
SingleValueType,
|
||||
BaseCascaderProps,
|
||||
InternalFieldNames,
|
||||
} from '../Cascader';
|
||||
import { toPathKey } from '../utils/commonUtil';
|
||||
import type { Ref } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
import { isValidElement } from '../../_util/props-util';
|
||||
import { cloneElement } from '../../_util/vnode';
|
||||
|
||||
export default (
|
||||
rawValues: Ref<SingleValueType[]>,
|
||||
options: Ref<DefaultOptionType[]>,
|
||||
fieldNames: Ref<InternalFieldNames>,
|
||||
multiple: Ref<boolean>,
|
||||
displayRender: Ref<BaseCascaderProps['displayRender']>,
|
||||
) => {
|
||||
return computed(() => {
|
||||
const mergedDisplayRender =
|
||||
displayRender.value ||
|
||||
// Default displayRender
|
||||
(({ labels }) => {
|
||||
const mergedLabels = multiple.value ? labels.slice(-1) : labels;
|
||||
const SPLIT = ' / ';
|
||||
|
||||
if (mergedLabels.every(label => ['string', 'number'].includes(typeof label))) {
|
||||
return mergedLabels.join(SPLIT);
|
||||
}
|
||||
|
||||
// If exist non-string value, use VueNode instead
|
||||
return mergedLabels.reduce((list, label, index) => {
|
||||
const keyedLabel = isValidElement(label) ? cloneElement(label, { key: index }) : label;
|
||||
|
||||
if (index === 0) {
|
||||
return [keyedLabel];
|
||||
}
|
||||
|
||||
return [...list, SPLIT, keyedLabel];
|
||||
}, []);
|
||||
});
|
||||
|
||||
return rawValues.value.map(valueCells => {
|
||||
const valueOptions = toPathOptions(valueCells, options.value, fieldNames.value);
|
||||
|
||||
const label = mergedDisplayRender({
|
||||
labels: valueOptions.map(({ option, value }) => option?.[fieldNames.value.label] ?? value),
|
||||
selectedOptions: valueOptions.map(({ option }) => option),
|
||||
});
|
||||
|
||||
return {
|
||||
label,
|
||||
value: toPathKey(valueCells),
|
||||
valueCells,
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import { convertDataToEntities } from '../../vc-tree/utils/treeUtil';
|
||||
import type { DataEntity } from '../../vc-tree/interface';
|
||||
import type { DefaultOptionType, InternalFieldNames } from '../Cascader';
|
||||
import { VALUE_SPLIT } from '../utils/commonUtil';
|
||||
import type { Ref } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
export interface OptionsInfo {
|
||||
keyEntities: Record<string, DataEntity>;
|
||||
pathKeyEntities: Record<string, DataEntity>;
|
||||
}
|
||||
|
||||
/** Lazy parse options data into conduct-able info to avoid perf issue in single mode */
|
||||
export default (options: Ref<DefaultOptionType[]>, fieldNames: Ref<InternalFieldNames>) => {
|
||||
const entities = computed(() => {
|
||||
return (
|
||||
convertDataToEntities(options.value as any, {
|
||||
fieldNames: fieldNames.value,
|
||||
initWrapper: wrapper => ({
|
||||
...wrapper,
|
||||
pathKeyEntities: {},
|
||||
}),
|
||||
processEntity: (entity, wrapper: any) => {
|
||||
const pathKey = entity.nodes.map(node => node[fieldNames.value.value]).join(VALUE_SPLIT);
|
||||
|
||||
wrapper.pathKeyEntities[pathKey] = entity;
|
||||
|
||||
// Overwrite origin key.
|
||||
// this is very hack but we need let conduct logic work with connect path
|
||||
entity.key = pathKey;
|
||||
},
|
||||
}) as any
|
||||
).pathKeyEntities;
|
||||
});
|
||||
return entities;
|
||||
};
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import type { Ref } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
import type { SingleValueType, DefaultOptionType, InternalFieldNames } from '../Cascader';
|
||||
import { toPathOptions } from '../utils/treeUtil';
|
||||
|
||||
export default (
|
||||
options: Ref<DefaultOptionType[]>,
|
||||
fieldNames: Ref<InternalFieldNames>,
|
||||
rawValues: Ref<SingleValueType[]>,
|
||||
) => {
|
||||
return computed(() => {
|
||||
const missingValues: SingleValueType[] = [];
|
||||
const existsValues: SingleValueType[] = [];
|
||||
|
||||
rawValues.value.forEach(valueCell => {
|
||||
const pathOptions = toPathOptions(valueCell, options.value, fieldNames.value);
|
||||
if (pathOptions.every(opt => opt.option)) {
|
||||
existsValues.push(valueCell);
|
||||
} else {
|
||||
missingValues.push(valueCell);
|
||||
}
|
||||
});
|
||||
|
||||
return [existsValues, missingValues];
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
import type { BaseCascaderProps, ShowSearchType } from '../Cascader';
|
||||
import type { Ref } from 'vue';
|
||||
import { ref, watchEffect } from 'vue';
|
||||
import { warning } from '../../vc-util/warning';
|
||||
|
||||
// Convert `showSearch` to unique config
|
||||
export default function useSearchConfig(showSearch?: Ref<BaseCascaderProps['showSearch']>) {
|
||||
const mergedShowSearch = ref(false);
|
||||
const mergedSearchConfig = ref<ShowSearchType>({});
|
||||
watchEffect(() => {
|
||||
if (!showSearch.value) {
|
||||
mergedShowSearch.value = false;
|
||||
mergedSearchConfig.value = {};
|
||||
return;
|
||||
}
|
||||
|
||||
let searchConfig: ShowSearchType = {
|
||||
matchInputWidth: true,
|
||||
limit: 50,
|
||||
};
|
||||
|
||||
if (showSearch.value && typeof showSearch.value === 'object') {
|
||||
searchConfig = {
|
||||
...searchConfig,
|
||||
...showSearch.value,
|
||||
};
|
||||
}
|
||||
|
||||
if (searchConfig.limit <= 0) {
|
||||
delete searchConfig.limit;
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
warning(false, "'limit' of showSearch should be positive number or false.");
|
||||
}
|
||||
}
|
||||
mergedShowSearch.value = true;
|
||||
mergedSearchConfig.value = searchConfig;
|
||||
return;
|
||||
});
|
||||
return { showSearch: mergedShowSearch, searchConfig: mergedSearchConfig };
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import type { Ref } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
import type { DefaultOptionType, ShowSearchType, InternalFieldNames } from '../Cascader';
|
||||
|
||||
export const SEARCH_MARK = '__rc_cascader_search_mark__';
|
||||
|
||||
const defaultFilter: ShowSearchType['filter'] = (search, options, { label }) =>
|
||||
options.some(opt => String(opt[label]).toLowerCase().includes(search.toLowerCase()));
|
||||
|
||||
const defaultRender: ShowSearchType['render'] = ({ path, fieldNames }) =>
|
||||
path.map(opt => opt[fieldNames.label]).join(' / ');
|
||||
|
||||
export default (
|
||||
search: Ref<string>,
|
||||
options: Ref<DefaultOptionType[]>,
|
||||
fieldNames: Ref<InternalFieldNames>,
|
||||
prefixCls: Ref<string>,
|
||||
config: Ref<ShowSearchType>,
|
||||
changeOnSelect: Ref<boolean>,
|
||||
) => {
|
||||
return computed(() => {
|
||||
const { filter = defaultFilter, render = defaultRender, limit = 50, sort } = config.value;
|
||||
const filteredOptions: DefaultOptionType[] = [];
|
||||
if (!search.value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
function dig(list: DefaultOptionType[], pathOptions: DefaultOptionType[]) {
|
||||
list.forEach(option => {
|
||||
// Perf saving when `sort` is disabled and `limit` is provided
|
||||
if (!sort && limit > 0 && filteredOptions.length >= limit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const connectedPathOptions = [...pathOptions, option];
|
||||
const children = option[fieldNames.value.children];
|
||||
|
||||
// If current option is filterable
|
||||
if (
|
||||
// If is leaf option
|
||||
!children ||
|
||||
// If is changeOnSelect
|
||||
changeOnSelect.value
|
||||
) {
|
||||
if (filter(search.value, connectedPathOptions, { label: fieldNames.value.label })) {
|
||||
filteredOptions.push({
|
||||
...option,
|
||||
[fieldNames.value.label as 'label']: render({
|
||||
inputValue: search.value,
|
||||
path: connectedPathOptions,
|
||||
prefixCls: prefixCls.value,
|
||||
fieldNames: fieldNames.value,
|
||||
}),
|
||||
[SEARCH_MARK]: connectedPathOptions,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (children) {
|
||||
dig(option[fieldNames.value.children] as DefaultOptionType[], connectedPathOptions);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dig(options.value, []);
|
||||
|
||||
// Do sort
|
||||
if (sort) {
|
||||
filteredOptions.sort((a, b) => {
|
||||
return sort(a[SEARCH_MARK], b[SEARCH_MARK], search.value, fieldNames.value);
|
||||
});
|
||||
}
|
||||
|
||||
return limit > 0 ? filteredOptions.slice(0, limit as number) : filteredOptions;
|
||||
});
|
||||
};
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
// based on rc-cascader 0.17.4
|
||||
import Cascader from './Cascader';
|
||||
export default Cascader;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// rc-cascader@3.0.0-alpha.6
|
||||
import Cascader, { internalCascaderProps as cascaderProps } from './Cascader';
|
||||
|
||||
export type {
|
||||
CascaderProps,
|
||||
FieldNames,
|
||||
ShowSearchType,
|
||||
DefaultOptionType,
|
||||
BaseOptionType,
|
||||
} from './Cascader';
|
||||
export { cascaderProps };
|
||||
export default Cascader;
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import type {
|
||||
DefaultOptionType,
|
||||
FieldNames,
|
||||
InternalFieldNames,
|
||||
SingleValueType,
|
||||
} from '../Cascader';
|
||||
|
||||
export const VALUE_SPLIT = '__RC_CASCADER_SPLIT__';
|
||||
|
||||
export function toPathKey(value: SingleValueType) {
|
||||
return value.join(VALUE_SPLIT);
|
||||
}
|
||||
|
||||
export function toPathKeys(value: SingleValueType[]) {
|
||||
return value.map(toPathKey);
|
||||
}
|
||||
|
||||
export function toPathValueStr(pathKey: string) {
|
||||
return pathKey.split(VALUE_SPLIT);
|
||||
}
|
||||
|
||||
export function fillFieldNames(fieldNames?: FieldNames): InternalFieldNames {
|
||||
const { label, value, children } = fieldNames || {};
|
||||
const val = value || 'value';
|
||||
return {
|
||||
label: label || 'label',
|
||||
value: val,
|
||||
key: val,
|
||||
children: children || 'children',
|
||||
};
|
||||
}
|
||||
|
||||
export function isLeaf(option: DefaultOptionType, fieldNames: FieldNames) {
|
||||
return option.isLeaf ?? !option[fieldNames.children]?.length;
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import type { Key } from '../../_util/type';
|
||||
import type { SingleValueType, DefaultOptionType, InternalFieldNames } from '../Cascader';
|
||||
import type { OptionsInfo } from '../hooks/useEntities';
|
||||
|
||||
export function formatStrategyValues(
|
||||
pathKeys: Key[],
|
||||
keyPathEntities: OptionsInfo['pathKeyEntities'],
|
||||
) {
|
||||
const valueSet = new Set(pathKeys);
|
||||
|
||||
return pathKeys.filter(key => {
|
||||
const entity = keyPathEntities[key];
|
||||
const parent = entity ? entity.parent : null;
|
||||
|
||||
if (parent && !parent.node.disabled && valueSet.has(parent.key)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function toPathOptions(
|
||||
valueCells: SingleValueType,
|
||||
options: DefaultOptionType[],
|
||||
fieldNames: InternalFieldNames,
|
||||
// Used for loadingKeys which saved loaded keys as string
|
||||
stringMode = false,
|
||||
) {
|
||||
let currentList = options;
|
||||
const valueOptions: {
|
||||
value: SingleValueType[number];
|
||||
index: number;
|
||||
option: DefaultOptionType;
|
||||
}[] = [];
|
||||
|
||||
for (let i = 0; i < valueCells.length; i += 1) {
|
||||
const valueCell = valueCells[i];
|
||||
const foundIndex = currentList?.findIndex(option => {
|
||||
const val = option[fieldNames.value];
|
||||
return stringMode ? String(val) === String(valueCell) : val === valueCell;
|
||||
});
|
||||
const foundOption = foundIndex !== -1 ? currentList?.[foundIndex] : null;
|
||||
|
||||
valueOptions.push({
|
||||
value: foundOption?.[fieldNames.value] ?? valueCell,
|
||||
index: foundIndex,
|
||||
option: foundOption,
|
||||
});
|
||||
|
||||
currentList = foundOption?.[fieldNames.children];
|
||||
}
|
||||
|
||||
return valueOptions;
|
||||
}
|
||||
|
|
@ -307,7 +307,7 @@ const Overflow = defineComponent({
|
|||
let restNode = () => null;
|
||||
const restContextProps = {
|
||||
order: displayRest ? mergedDisplayCount.value : Number.MAX_SAFE_INTEGER,
|
||||
className: `${itemPrefixCls.value}-rest`,
|
||||
className: `${itemPrefixCls.value} ${itemPrefixCls.value}-rest`,
|
||||
registerSize: registerOverflowSize,
|
||||
display: displayRest,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,895 @@
|
|||
import { getSeparatedContent } from './utils/valueUtil';
|
||||
import type { RefTriggerProps } from './SelectTrigger';
|
||||
import SelectTrigger from './SelectTrigger';
|
||||
import type { RefSelectorProps } from './Selector';
|
||||
import Selector from './Selector';
|
||||
import useSelectTriggerControl from './hooks/useSelectTriggerControl';
|
||||
import useDelayReset from './hooks/useDelayReset';
|
||||
import TransBtn from './TransBtn';
|
||||
import useLock from './hooks/useLock';
|
||||
import type { BaseSelectContextProps } from './hooks/useBaseProps';
|
||||
import { useProvideBaseSelectProps } from './hooks/useBaseProps';
|
||||
import type { Key, VueNode } from '../_util/type';
|
||||
import type {
|
||||
FocusEventHandler,
|
||||
KeyboardEventHandler,
|
||||
MouseEventHandler,
|
||||
} from '../_util/EventInterface';
|
||||
import type { ScrollTo } from '../vc-virtual-list/List';
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
getCurrentInstance,
|
||||
onBeforeUnmount,
|
||||
onMounted,
|
||||
provide,
|
||||
ref,
|
||||
toRefs,
|
||||
watch,
|
||||
watchEffect,
|
||||
} from 'vue';
|
||||
import type { CSSProperties, ExtractPropTypes, PropType, VNode } from 'vue';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { initDefaultProps, isValidElement } from '../_util/props-util';
|
||||
import isMobile from '../vc-util/isMobile';
|
||||
import KeyCode from '../_util/KeyCode';
|
||||
import { toReactive } from '../_util/toReactive';
|
||||
import classNames from '../_util/classNames';
|
||||
import createRef from '../_util/createRef';
|
||||
import type { BaseOptionType } from './Select';
|
||||
import useInjectLegacySelectContext from '../vc-tree-select/LegacyContext';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
|
||||
const DEFAULT_OMIT_PROPS = [
|
||||
'value',
|
||||
'onChange',
|
||||
'removeIcon',
|
||||
'placeholder',
|
||||
'autofocus',
|
||||
'maxTagCount',
|
||||
'maxTagTextLength',
|
||||
'maxTagPlaceholder',
|
||||
'choiceTransitionName',
|
||||
'onInputKeyDown',
|
||||
'onPopupScroll',
|
||||
'tabindex',
|
||||
'OptionList',
|
||||
'notFoundContent',
|
||||
] as const;
|
||||
|
||||
export type RenderNode = VueNode | ((props: any) => VueNode);
|
||||
|
||||
export type RenderDOMFunc = (props: any) => HTMLElement;
|
||||
|
||||
export type Mode = 'multiple' | 'tags' | 'combobox';
|
||||
|
||||
export type Placement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';
|
||||
|
||||
export type RawValueType = string | number;
|
||||
|
||||
export interface RefOptionListProps {
|
||||
onKeydown: KeyboardEventHandler;
|
||||
onKeyup: KeyboardEventHandler;
|
||||
scrollTo?: (index: number) => void;
|
||||
}
|
||||
|
||||
export type CustomTagProps = {
|
||||
label: any;
|
||||
value: any;
|
||||
disabled: boolean;
|
||||
onClose: (event?: MouseEvent) => void;
|
||||
closable: boolean;
|
||||
option: BaseOptionType;
|
||||
};
|
||||
|
||||
export interface DisplayValueType {
|
||||
key?: Key;
|
||||
value?: RawValueType;
|
||||
label?: any;
|
||||
disabled?: boolean;
|
||||
option?: BaseOptionType;
|
||||
}
|
||||
|
||||
export type BaseSelectRef = {
|
||||
focus: () => void;
|
||||
blur: () => void;
|
||||
scrollTo: ScrollTo;
|
||||
};
|
||||
|
||||
const baseSelectPrivateProps = () => {
|
||||
return {
|
||||
prefixCls: String,
|
||||
id: String,
|
||||
omitDomProps: Array as PropType<string[]>,
|
||||
|
||||
// >>> Value
|
||||
displayValues: Array as PropType<DisplayValueType[]>,
|
||||
onDisplayValuesChange: Function as PropType<
|
||||
(
|
||||
values: DisplayValueType[],
|
||||
info: {
|
||||
type: 'add' | 'remove' | 'clear';
|
||||
values: DisplayValueType[];
|
||||
},
|
||||
) => void
|
||||
>,
|
||||
|
||||
// >>> Active
|
||||
/** Current dropdown list active item string value */
|
||||
activeValue: String,
|
||||
/** Link search input with target element */
|
||||
activeDescendantId: String,
|
||||
onActiveValueChange: Function as PropType<(value: string | null) => void>,
|
||||
|
||||
// >>> Search
|
||||
searchValue: String,
|
||||
/** Trigger onSearch, return false to prevent trigger open event */
|
||||
onSearch: Function as PropType<
|
||||
(
|
||||
searchValue: string,
|
||||
info: {
|
||||
source:
|
||||
| 'typing' //User typing
|
||||
| 'effect' // Code logic trigger
|
||||
| 'submit' // tag mode only
|
||||
| 'blur'; // Not trigger event
|
||||
},
|
||||
) => void
|
||||
>,
|
||||
/** Trigger when search text match the `tokenSeparators`. Will provide split content */
|
||||
onSearchSplit: Function as PropType<(words: string[]) => void>,
|
||||
maxLength: Number,
|
||||
|
||||
OptionList: PropTypes.any,
|
||||
|
||||
/** Tell if provided `options` is empty */
|
||||
emptyOptions: Boolean,
|
||||
};
|
||||
};
|
||||
|
||||
export type DropdownObject = {
|
||||
menuNode?: VueNode;
|
||||
props?: Record<string, any>;
|
||||
};
|
||||
|
||||
export type DropdownRender = (opt?: DropdownObject) => VueNode;
|
||||
export const baseSelectPropsWithoutPrivate = () => {
|
||||
return {
|
||||
showSearch: { type: Boolean, default: undefined },
|
||||
tagRender: { type: Function as PropType<(props: CustomTagProps) => any> },
|
||||
direction: { type: String as PropType<'ltr' | 'rtl'> },
|
||||
|
||||
// MISC
|
||||
tabindex: Number,
|
||||
autofocus: Boolean,
|
||||
notFoundContent: PropTypes.any,
|
||||
placeholder: PropTypes.any,
|
||||
onClear: Function as PropType<() => void>,
|
||||
|
||||
choiceTransitionName: String,
|
||||
|
||||
// >>> Mode
|
||||
mode: String as PropType<Mode>,
|
||||
|
||||
// >>> Status
|
||||
disabled: { type: Boolean, default: undefined },
|
||||
loading: { type: Boolean, default: undefined },
|
||||
|
||||
// >>> Open
|
||||
open: { type: Boolean, default: undefined },
|
||||
defaultOpen: { type: Boolean, default: undefined },
|
||||
onDropdownVisibleChange: { type: Function as PropType<(open: boolean) => void> },
|
||||
|
||||
// >>> Customize Input
|
||||
/** @private Internal usage. Do not use in your production. */
|
||||
getInputElement: { type: Function as PropType<() => any> },
|
||||
/** @private Internal usage. Do not use in your production. */
|
||||
getRawInputElement: { type: Function as PropType<() => any> },
|
||||
|
||||
// >>> Selector
|
||||
maxTagTextLength: Number,
|
||||
maxTagCount: { type: [String, Number] as PropType<number | 'responsive'> },
|
||||
maxTagPlaceholder: PropTypes.any,
|
||||
|
||||
// >>> Search
|
||||
tokenSeparators: { type: Array as PropType<string[]> },
|
||||
|
||||
// >>> Icons
|
||||
allowClear: { type: Boolean, default: undefined },
|
||||
showArrow: { type: Boolean, default: undefined },
|
||||
inputIcon: PropTypes.any,
|
||||
/** Clear all icon */
|
||||
clearIcon: PropTypes.any,
|
||||
/** Selector remove icon */
|
||||
removeIcon: PropTypes.any,
|
||||
|
||||
// >>> Dropdown
|
||||
animation: String,
|
||||
transitionName: String,
|
||||
dropdownStyle: { type: Object as PropType<CSSProperties> },
|
||||
dropdownClassName: String,
|
||||
dropdownMatchSelectWidth: {
|
||||
type: [Boolean, Number] as PropType<boolean | number>,
|
||||
default: undefined,
|
||||
},
|
||||
dropdownRender: { type: Function as PropType<DropdownRender> },
|
||||
dropdownAlign: PropTypes.any,
|
||||
placement: {
|
||||
type: String as PropType<Placement>,
|
||||
},
|
||||
getPopupContainer: { type: Function as PropType<RenderDOMFunc> },
|
||||
|
||||
// >>> Focus
|
||||
showAction: { type: Array as PropType<('focus' | 'click')[]> },
|
||||
onBlur: { type: Function as PropType<(e: FocusEvent) => void> },
|
||||
onFocus: { type: Function as PropType<(e: FocusEvent) => void> },
|
||||
|
||||
// >>> Rest Events
|
||||
onKeyup: Function as PropType<(e: KeyboardEvent) => void>,
|
||||
onKeydown: Function as PropType<(e: KeyboardEvent) => void>,
|
||||
onMousedown: Function as PropType<(e: MouseEvent) => void>,
|
||||
onPopupScroll: Function as PropType<(e: UIEvent) => void>,
|
||||
onInputKeyDown: Function as PropType<(e: KeyboardEvent) => void>,
|
||||
onMouseenter: Function as PropType<(e: MouseEvent) => void>,
|
||||
onMouseleave: Function as PropType<(e: MouseEvent) => void>,
|
||||
onClick: Function as PropType<(e: MouseEvent) => void>,
|
||||
};
|
||||
};
|
||||
const baseSelectProps = () => {
|
||||
return {
|
||||
...baseSelectPrivateProps(),
|
||||
...baseSelectPropsWithoutPrivate(),
|
||||
};
|
||||
};
|
||||
|
||||
export type BaseSelectPrivateProps = Partial<
|
||||
ExtractPropTypes<ReturnType<typeof baseSelectPrivateProps>>
|
||||
>;
|
||||
|
||||
export type BaseSelectProps = Partial<ExtractPropTypes<ReturnType<typeof baseSelectProps>>>;
|
||||
|
||||
export type BaseSelectPropsWithoutPrivate = Omit<BaseSelectProps, keyof BaseSelectPrivateProps>;
|
||||
|
||||
export function isMultiple(mode: Mode) {
|
||||
return mode === 'tags' || mode === 'multiple';
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BaseSelect',
|
||||
inheritAttrs: false,
|
||||
props: initDefaultProps(baseSelectProps(), { showAction: [], notFoundContent: 'Not Found' }),
|
||||
setup(props, { attrs, expose, slots }) {
|
||||
const multiple = computed(() => isMultiple(props.mode));
|
||||
|
||||
const mergedShowSearch = computed(() =>
|
||||
props.showSearch !== undefined
|
||||
? props.showSearch
|
||||
: multiple.value || props.mode === 'combobox',
|
||||
);
|
||||
const mobile = ref(false);
|
||||
onMounted(() => {
|
||||
mobile.value = isMobile();
|
||||
});
|
||||
const legacyTreeSelectContext = useInjectLegacySelectContext();
|
||||
// ============================== Refs ==============================
|
||||
const containerRef = ref<HTMLDivElement>(null);
|
||||
const selectorDomRef = createRef();
|
||||
const triggerRef = ref<RefTriggerProps>(null);
|
||||
const selectorRef = ref<RefSelectorProps>(null);
|
||||
const listRef = ref<RefOptionListProps>(null);
|
||||
|
||||
/** Used for component focused management */
|
||||
const [mockFocused, setMockFocused, cancelSetMockFocused] = useDelayReset();
|
||||
|
||||
const focus = () => {
|
||||
selectorRef.value?.focus();
|
||||
};
|
||||
const blur = () => {
|
||||
selectorRef.value?.blur();
|
||||
};
|
||||
expose({
|
||||
focus,
|
||||
blur,
|
||||
scrollTo: arg => listRef.value?.scrollTo(arg),
|
||||
});
|
||||
|
||||
const mergedSearchValue = computed(() => {
|
||||
if (props.mode !== 'combobox') {
|
||||
return props.searchValue;
|
||||
}
|
||||
|
||||
const val = props.displayValues[0]?.value;
|
||||
|
||||
return typeof val === 'string' || typeof val === 'number' ? String(val) : '';
|
||||
});
|
||||
|
||||
// ============================== Open ==============================
|
||||
const initOpen = props.open !== undefined ? props.open : props.defaultOpen;
|
||||
const innerOpen = ref(initOpen);
|
||||
const mergedOpen = ref(initOpen);
|
||||
const setInnerOpen = (val: boolean) => {
|
||||
innerOpen.value = props.open !== undefined ? props.open : val;
|
||||
mergedOpen.value = innerOpen.value;
|
||||
};
|
||||
watch(
|
||||
() => props.open,
|
||||
() => {
|
||||
setInnerOpen(props.open);
|
||||
},
|
||||
);
|
||||
|
||||
// Not trigger `open` in `combobox` when `notFoundContent` is empty
|
||||
const emptyListContent = computed(() => !props.notFoundContent && props.emptyOptions);
|
||||
|
||||
watchEffect(() => {
|
||||
mergedOpen.value = innerOpen.value;
|
||||
if (
|
||||
props.disabled ||
|
||||
(emptyListContent.value && mergedOpen.value && props.mode === 'combobox')
|
||||
) {
|
||||
mergedOpen.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
const triggerOpen = computed(() => (emptyListContent.value ? false : mergedOpen.value));
|
||||
|
||||
const onToggleOpen = (newOpen?: boolean) => {
|
||||
const nextOpen = newOpen !== undefined ? newOpen : !mergedOpen.value;
|
||||
|
||||
if (innerOpen.value !== nextOpen && !props.disabled) {
|
||||
setInnerOpen(nextOpen);
|
||||
if (props.onDropdownVisibleChange) {
|
||||
props.onDropdownVisibleChange(nextOpen);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const tokenWithEnter = computed(() =>
|
||||
(props.tokenSeparators || []).some(tokenSeparator => ['\n', '\r\n'].includes(tokenSeparator)),
|
||||
);
|
||||
|
||||
const onInternalSearch = (searchText: string, fromTyping: boolean, isCompositing: boolean) => {
|
||||
let ret = true;
|
||||
let newSearchText = searchText;
|
||||
props.onActiveValueChange?.(null);
|
||||
|
||||
// Check if match the `tokenSeparators`
|
||||
const patchLabels: string[] = isCompositing
|
||||
? null
|
||||
: getSeparatedContent(searchText, props.tokenSeparators);
|
||||
|
||||
// Ignore combobox since it's not split-able
|
||||
if (props.mode !== 'combobox' && patchLabels) {
|
||||
newSearchText = '';
|
||||
|
||||
props.onSearchSplit?.(patchLabels);
|
||||
|
||||
// Should close when paste finish
|
||||
onToggleOpen(false);
|
||||
|
||||
// Tell Selector that break next actions
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (props.onSearch && mergedSearchValue.value !== newSearchText) {
|
||||
props.onSearch(newSearchText, {
|
||||
source: fromTyping ? 'typing' : 'effect',
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
// Only triggered when menu is closed & mode is tags
|
||||
// If menu is open, OptionList will take charge
|
||||
// If mode isn't tags, press enter is not meaningful when you can't see any option
|
||||
const onInternalSearchSubmit = (searchText: string) => {
|
||||
// prevent empty tags from appearing when you click the Enter button
|
||||
if (!searchText || !searchText.trim()) {
|
||||
return;
|
||||
}
|
||||
props.onSearch?.(searchText, { source: 'submit' });
|
||||
};
|
||||
|
||||
// Close will clean up single mode search text
|
||||
watch(
|
||||
mergedOpen,
|
||||
() => {
|
||||
if (!mergedOpen.value && !multiple.value && props.mode !== 'combobox') {
|
||||
onInternalSearch('', false, false);
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
// ============================ Disabled ============================
|
||||
// Close dropdown & remove focus state when disabled change
|
||||
watch(
|
||||
() => props.disabled,
|
||||
() => {
|
||||
if (innerOpen.value && !!props.disabled) {
|
||||
setInnerOpen(false);
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
// ============================ Keyboard ============================
|
||||
/**
|
||||
* We record input value here to check if can press to clean up by backspace
|
||||
* - null: Key is not down, this is reset by key up
|
||||
* - true: Search text is empty when first time backspace down
|
||||
* - false: Search text is not empty when first time backspace down
|
||||
*/
|
||||
const [getClearLock, setClearLock] = useLock();
|
||||
|
||||
// KeyDown
|
||||
const onInternalKeyDown: KeyboardEventHandler = (event, ...rest) => {
|
||||
const clearLock = getClearLock();
|
||||
const { which } = event;
|
||||
|
||||
if (which === KeyCode.ENTER) {
|
||||
// Do not submit form when type in the input
|
||||
if (props.mode !== 'combobox') {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
// We only manage open state here, close logic should handle by list component
|
||||
if (!mergedOpen.value) {
|
||||
onToggleOpen(true);
|
||||
}
|
||||
}
|
||||
|
||||
setClearLock(!!mergedSearchValue.value);
|
||||
|
||||
// Remove value by `backspace`
|
||||
if (
|
||||
which === KeyCode.BACKSPACE &&
|
||||
!clearLock &&
|
||||
multiple.value &&
|
||||
!mergedSearchValue.value &&
|
||||
props.displayValues.length
|
||||
) {
|
||||
const cloneDisplayValues = [...props.displayValues];
|
||||
let removedDisplayValue = null;
|
||||
|
||||
for (let i = cloneDisplayValues.length - 1; i >= 0; i -= 1) {
|
||||
const current = cloneDisplayValues[i];
|
||||
|
||||
if (!current.disabled) {
|
||||
cloneDisplayValues.splice(i, 1);
|
||||
removedDisplayValue = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (removedDisplayValue) {
|
||||
props.onDisplayValuesChange(cloneDisplayValues, {
|
||||
type: 'remove',
|
||||
values: [removedDisplayValue],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (mergedOpen.value && listRef.value) {
|
||||
listRef.value.onKeydown(event, ...rest);
|
||||
}
|
||||
|
||||
props.onKeydown?.(event, ...rest);
|
||||
};
|
||||
|
||||
// KeyUp
|
||||
const onInternalKeyUp: KeyboardEventHandler = (event: KeyboardEvent, ...rest) => {
|
||||
if (mergedOpen.value && listRef.value) {
|
||||
listRef.value.onKeyup(event, ...rest);
|
||||
}
|
||||
|
||||
if (props.onKeyup) {
|
||||
props.onKeyup(event, ...rest);
|
||||
}
|
||||
};
|
||||
|
||||
// ============================ Selector ============================
|
||||
const onSelectorRemove = (val: DisplayValueType) => {
|
||||
const newValues = props.displayValues.filter(i => i !== val);
|
||||
|
||||
props.onDisplayValuesChange(newValues, {
|
||||
type: 'remove',
|
||||
values: [val],
|
||||
});
|
||||
};
|
||||
|
||||
// ========================== Focus / Blur ==========================
|
||||
/** Record real focus status */
|
||||
const focusRef = ref(false);
|
||||
|
||||
const onContainerFocus: FocusEventHandler = (...args) => {
|
||||
setMockFocused(true);
|
||||
|
||||
if (!props.disabled) {
|
||||
if (props.onFocus && !focusRef.value) {
|
||||
props.onFocus(...args);
|
||||
}
|
||||
|
||||
// `showAction` should handle `focus` if set
|
||||
if (props.showAction && props.showAction.includes('focus')) {
|
||||
onToggleOpen(true);
|
||||
}
|
||||
}
|
||||
|
||||
focusRef.value = true;
|
||||
};
|
||||
|
||||
const onContainerBlur: FocusEventHandler = (...args) => {
|
||||
setMockFocused(false, () => {
|
||||
focusRef.value = false;
|
||||
onToggleOpen(false);
|
||||
});
|
||||
|
||||
if (props.disabled) {
|
||||
return;
|
||||
}
|
||||
const searchVal = mergedSearchValue.value;
|
||||
if (searchVal) {
|
||||
// `tags` mode should move `searchValue` into values
|
||||
if (props.mode === 'tags') {
|
||||
props.onSearch(searchVal, { source: 'submit' });
|
||||
} else if (props.mode === 'multiple') {
|
||||
// `multiple` mode only clean the search value but not trigger event
|
||||
props.onSearch('', {
|
||||
source: 'blur',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (props.onBlur) {
|
||||
props.onBlur(...args);
|
||||
}
|
||||
};
|
||||
provide('VCSelectContainerEvent', {
|
||||
focus: onContainerFocus,
|
||||
blur: onContainerBlur,
|
||||
});
|
||||
|
||||
// Give focus back of Select
|
||||
const activeTimeoutIds: any[] = [];
|
||||
|
||||
onMounted(() => {
|
||||
activeTimeoutIds.forEach(timeoutId => clearTimeout(timeoutId));
|
||||
activeTimeoutIds.splice(0, activeTimeoutIds.length);
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
activeTimeoutIds.forEach(timeoutId => clearTimeout(timeoutId));
|
||||
activeTimeoutIds.splice(0, activeTimeoutIds.length);
|
||||
});
|
||||
|
||||
const onInternalMouseDown: MouseEventHandler = (event, ...restArgs) => {
|
||||
const { target } = event;
|
||||
const popupElement: HTMLDivElement = triggerRef.value?.getPopupElement();
|
||||
|
||||
// We should give focus back to selector if clicked item is not focusable
|
||||
if (popupElement && popupElement.contains(target as HTMLElement)) {
|
||||
const timeoutId: any = setTimeout(() => {
|
||||
const index = activeTimeoutIds.indexOf(timeoutId);
|
||||
if (index !== -1) {
|
||||
activeTimeoutIds.splice(index, 1);
|
||||
}
|
||||
|
||||
cancelSetMockFocused();
|
||||
|
||||
if (!mobile.value && !popupElement.contains(document.activeElement)) {
|
||||
selectorRef.value?.focus();
|
||||
}
|
||||
});
|
||||
|
||||
activeTimeoutIds.push(timeoutId);
|
||||
}
|
||||
|
||||
props.onMousedown?.(event, ...restArgs);
|
||||
};
|
||||
|
||||
// ============================= Dropdown ==============================
|
||||
const containerWidth = ref<number>(null);
|
||||
const instance = getCurrentInstance();
|
||||
const onPopupMouseEnter = () => {
|
||||
// We need force update here since popup dom is render async
|
||||
instance.update();
|
||||
};
|
||||
onMounted(() => {
|
||||
watch(
|
||||
triggerOpen,
|
||||
() => {
|
||||
if (triggerOpen.value) {
|
||||
const newWidth = Math.ceil(containerRef.value?.offsetWidth);
|
||||
if (containerWidth.value !== newWidth && !Number.isNaN(newWidth)) {
|
||||
containerWidth.value = newWidth;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
});
|
||||
|
||||
// Close when click on non-select element
|
||||
useSelectTriggerControl([containerRef, triggerRef], triggerOpen, onToggleOpen);
|
||||
useProvideBaseSelectProps(
|
||||
toReactive({
|
||||
...toRefs(props),
|
||||
open: mergedOpen,
|
||||
triggerOpen,
|
||||
showSearch: mergedShowSearch,
|
||||
multiple,
|
||||
toggleOpen: onToggleOpen,
|
||||
} as unknown as BaseSelectContextProps),
|
||||
);
|
||||
return () => {
|
||||
const {
|
||||
prefixCls,
|
||||
id,
|
||||
|
||||
open,
|
||||
defaultOpen,
|
||||
|
||||
mode,
|
||||
|
||||
// Search related
|
||||
showSearch,
|
||||
searchValue,
|
||||
onSearch,
|
||||
|
||||
// Icons
|
||||
allowClear,
|
||||
clearIcon,
|
||||
showArrow,
|
||||
inputIcon,
|
||||
|
||||
// Others
|
||||
disabled,
|
||||
loading,
|
||||
getInputElement,
|
||||
getPopupContainer,
|
||||
placement,
|
||||
|
||||
// Dropdown
|
||||
animation,
|
||||
transitionName,
|
||||
dropdownStyle,
|
||||
dropdownClassName,
|
||||
dropdownMatchSelectWidth,
|
||||
dropdownRender,
|
||||
dropdownAlign,
|
||||
showAction,
|
||||
direction,
|
||||
|
||||
// Tags
|
||||
tokenSeparators,
|
||||
tagRender,
|
||||
|
||||
// Events
|
||||
onPopupScroll,
|
||||
onDropdownVisibleChange,
|
||||
onFocus,
|
||||
onBlur,
|
||||
onKeyup,
|
||||
onKeydown,
|
||||
onMousedown,
|
||||
|
||||
onClear,
|
||||
omitDomProps,
|
||||
getRawInputElement,
|
||||
displayValues,
|
||||
onDisplayValuesChange,
|
||||
emptyOptions,
|
||||
activeDescendantId,
|
||||
activeValue,
|
||||
OptionList,
|
||||
|
||||
...restProps
|
||||
} = { ...props, ...attrs } as BaseSelectProps;
|
||||
// ============================= Input ==============================
|
||||
// Only works in `combobox`
|
||||
const customizeInputElement: any =
|
||||
(mode === 'combobox' && getInputElement && getInputElement()) || null;
|
||||
|
||||
// Used for customize replacement for `vc-cascader`
|
||||
const customizeRawInputElement: any =
|
||||
typeof getRawInputElement === 'function' && getRawInputElement();
|
||||
const domProps = {
|
||||
...restProps,
|
||||
} as Omit<keyof typeof restProps, typeof DEFAULT_OMIT_PROPS[number]>;
|
||||
|
||||
// Used for raw custom input trigger
|
||||
let onTriggerVisibleChange: null | ((newOpen: boolean) => void);
|
||||
if (customizeRawInputElement) {
|
||||
onTriggerVisibleChange = (newOpen: boolean) => {
|
||||
onToggleOpen(newOpen);
|
||||
};
|
||||
}
|
||||
|
||||
DEFAULT_OMIT_PROPS.forEach(propName => {
|
||||
delete domProps[propName];
|
||||
});
|
||||
|
||||
omitDomProps?.forEach(propName => {
|
||||
delete domProps[propName];
|
||||
});
|
||||
|
||||
// ============================= Arrow ==============================
|
||||
const mergedShowArrow =
|
||||
showArrow !== undefined ? showArrow : loading || (!multiple.value && mode !== 'combobox');
|
||||
let arrowNode: VNode | JSX.Element;
|
||||
|
||||
if (mergedShowArrow) {
|
||||
arrowNode = (
|
||||
<TransBtn
|
||||
class={classNames(`${prefixCls}-arrow`, {
|
||||
[`${prefixCls}-arrow-loading`]: loading,
|
||||
})}
|
||||
customizeIcon={inputIcon}
|
||||
customizeIconProps={{
|
||||
loading,
|
||||
searchValue: mergedSearchValue.value,
|
||||
open: mergedOpen.value,
|
||||
focused: mockFocused.value,
|
||||
showSearch: mergedShowSearch.value,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// ============================= Clear ==============================
|
||||
let clearNode: VNode | JSX.Element;
|
||||
const onClearMouseDown: MouseEventHandler = () => {
|
||||
onClear?.();
|
||||
|
||||
onDisplayValuesChange([], {
|
||||
type: 'clear',
|
||||
values: displayValues,
|
||||
});
|
||||
onInternalSearch('', false, false);
|
||||
};
|
||||
|
||||
if (!disabled && allowClear && (displayValues.length || mergedSearchValue.value)) {
|
||||
clearNode = (
|
||||
<TransBtn
|
||||
class={`${prefixCls}-clear`}
|
||||
onMousedown={onClearMouseDown}
|
||||
customizeIcon={clearIcon}
|
||||
>
|
||||
×
|
||||
</TransBtn>
|
||||
);
|
||||
}
|
||||
|
||||
// =========================== OptionList ===========================
|
||||
const optionList = (
|
||||
<OptionList
|
||||
ref={listRef}
|
||||
v-slots={{ ...legacyTreeSelectContext.customSlots, option: slots.option }}
|
||||
/>
|
||||
);
|
||||
|
||||
// ============================= Select =============================
|
||||
const mergedClassName = classNames(prefixCls, attrs.class, {
|
||||
[`${prefixCls}-focused`]: mockFocused.value,
|
||||
[`${prefixCls}-multiple`]: multiple.value,
|
||||
[`${prefixCls}-single`]: !multiple.value,
|
||||
[`${prefixCls}-allow-clear`]: allowClear,
|
||||
[`${prefixCls}-show-arrow`]: mergedShowArrow,
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
[`${prefixCls}-loading`]: loading,
|
||||
[`${prefixCls}-open`]: mergedOpen.value,
|
||||
[`${prefixCls}-customize-input`]: customizeInputElement,
|
||||
[`${prefixCls}-show-search`]: mergedShowSearch.value,
|
||||
});
|
||||
|
||||
// >>> Selector
|
||||
const selectorNode = (
|
||||
<SelectTrigger
|
||||
ref={triggerRef}
|
||||
disabled={disabled}
|
||||
prefixCls={prefixCls}
|
||||
visible={triggerOpen.value}
|
||||
popupElement={optionList}
|
||||
containerWidth={containerWidth.value}
|
||||
animation={animation}
|
||||
transitionName={transitionName}
|
||||
dropdownStyle={dropdownStyle}
|
||||
dropdownClassName={dropdownClassName}
|
||||
direction={direction}
|
||||
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
|
||||
dropdownRender={dropdownRender}
|
||||
dropdownAlign={dropdownAlign}
|
||||
placement={placement}
|
||||
getPopupContainer={getPopupContainer}
|
||||
empty={emptyOptions}
|
||||
getTriggerDOMNode={() => selectorDomRef.current}
|
||||
onPopupVisibleChange={onTriggerVisibleChange}
|
||||
onPopupMouseEnter={onPopupMouseEnter}
|
||||
v-slots={{
|
||||
default: () => {
|
||||
return customizeRawInputElement ? (
|
||||
isValidElement(customizeRawInputElement) &&
|
||||
cloneElement(
|
||||
customizeRawInputElement,
|
||||
{
|
||||
ref: selectorDomRef,
|
||||
},
|
||||
false,
|
||||
true,
|
||||
)
|
||||
) : (
|
||||
<Selector
|
||||
{...props}
|
||||
domRef={selectorDomRef}
|
||||
prefixCls={prefixCls}
|
||||
inputElement={customizeInputElement}
|
||||
ref={selectorRef}
|
||||
id={id}
|
||||
showSearch={mergedShowSearch.value}
|
||||
mode={mode}
|
||||
activeDescendantId={activeDescendantId}
|
||||
tagRender={tagRender}
|
||||
values={displayValues}
|
||||
open={mergedOpen.value}
|
||||
onToggleOpen={onToggleOpen}
|
||||
activeValue={activeValue}
|
||||
searchValue={mergedSearchValue.value}
|
||||
onSearch={onInternalSearch}
|
||||
onSearchSubmit={onInternalSearchSubmit}
|
||||
onRemove={onSelectorRemove}
|
||||
tokenWithEnter={tokenWithEnter.value}
|
||||
/>
|
||||
);
|
||||
},
|
||||
}}
|
||||
></SelectTrigger>
|
||||
);
|
||||
// >>> Render
|
||||
let renderNode: VNode | JSX.Element;
|
||||
|
||||
// Render raw
|
||||
if (customizeRawInputElement) {
|
||||
renderNode = selectorNode;
|
||||
} else {
|
||||
renderNode = (
|
||||
<div
|
||||
{...domProps}
|
||||
class={mergedClassName}
|
||||
ref={containerRef}
|
||||
onMousedown={onInternalMouseDown}
|
||||
onKeydown={onInternalKeyDown}
|
||||
onKeyup={onInternalKeyUp}
|
||||
// onFocus={onContainerFocus}
|
||||
// onBlur={onContainerBlur}
|
||||
>
|
||||
{mockFocused.value && !mergedOpen.value && (
|
||||
<span
|
||||
style={{
|
||||
width: 0,
|
||||
height: 0,
|
||||
display: 'flex',
|
||||
overflow: 'hidden',
|
||||
opacity: 0,
|
||||
}}
|
||||
aria-live="polite"
|
||||
>
|
||||
{/* Merge into one string to make screen reader work as expect */}
|
||||
{`${displayValues
|
||||
.map(({ label, value }) =>
|
||||
['number', 'string'].includes(typeof label) ? label : value,
|
||||
)
|
||||
.join(', ')}`}
|
||||
</span>
|
||||
)}
|
||||
{selectorNode}
|
||||
|
||||
{arrowNode}
|
||||
{clearNode}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return renderNode;
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import type { FunctionalComponent } from 'vue';
|
||||
|
||||
import type { OptionGroupData } from './interface';
|
||||
import type { DefaultOptionType } from './Select';
|
||||
|
||||
export type OptGroupProps = Omit<OptionGroupData, 'options'>;
|
||||
export type OptGroupProps = Omit<DefaultOptionType, 'options'>;
|
||||
|
||||
export interface OptionGroupFC extends FunctionalComponent<OptGroupProps> {
|
||||
/** Legacy for check if is a Option Group */
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { FunctionalComponent } from 'vue';
|
||||
|
||||
import type { OptionCoreData } from './interface';
|
||||
import type { DefaultOptionType } from './Select';
|
||||
|
||||
export interface OptionProps extends Omit<OptionCoreData, 'label'> {
|
||||
export interface OptionProps extends Omit<DefaultOptionType, 'label'> {
|
||||
/** Save for customize data */
|
||||
[prop: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,12 @@
|
|||
import TransBtn from './TransBtn';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
|
||||
import KeyCode from '../_util/KeyCode';
|
||||
import classNames from '../_util/classNames';
|
||||
import pickAttrs from '../_util/pickAttrs';
|
||||
import { isValidElement } from '../_util/props-util';
|
||||
import createRef from '../_util/createRef';
|
||||
import type { PropType } from 'vue';
|
||||
import { computed, defineComponent, nextTick, reactive, watch } from 'vue';
|
||||
import List from '../vc-virtual-list';
|
||||
import type {
|
||||
OptionsType as SelectOptionsType,
|
||||
OptionData,
|
||||
RenderNode,
|
||||
OnActiveValue,
|
||||
FieldNames,
|
||||
} from './interface';
|
||||
import type { RawValueType, FlattenOptionsType } from './interface/generator';
|
||||
import { fillFieldNames } from './utils/valueUtil';
|
||||
import useMemo from '../_util/hooks/useMemo';
|
||||
import { isPlatformMac } from './utils/platformUtil';
|
||||
|
||||
|
|
@ -28,78 +18,28 @@ export interface RefOptionListProps {
|
|||
|
||||
import type { EventHandler } from '../_util/EventInterface';
|
||||
import omit from '../_util/omit';
|
||||
export interface OptionListProps<OptionType extends object> {
|
||||
prefixCls: string;
|
||||
id: string;
|
||||
options: OptionType[];
|
||||
fieldNames?: FieldNames;
|
||||
flattenOptions: FlattenOptionsType<OptionType>;
|
||||
height: number;
|
||||
itemHeight: number;
|
||||
values: Set<RawValueType>;
|
||||
multiple: boolean;
|
||||
open: boolean;
|
||||
defaultActiveFirstOption?: boolean;
|
||||
notFoundContent?: any;
|
||||
menuItemSelectedIcon?: RenderNode;
|
||||
childrenAsData: boolean;
|
||||
searchValue: string;
|
||||
virtual: boolean;
|
||||
direction?: 'ltr' | 'rtl';
|
||||
|
||||
onSelect: (value: RawValueType, option: { selected: boolean }) => void;
|
||||
onToggleOpen: (open?: boolean) => void;
|
||||
/** Tell Select that some value is now active to make accessibility work */
|
||||
onActiveValue: OnActiveValue;
|
||||
onScroll: EventHandler;
|
||||
|
||||
/** Tell Select that mouse enter the popup to force re-render */
|
||||
onMouseenter?: EventHandler;
|
||||
}
|
||||
|
||||
const OptionListProps = {
|
||||
prefixCls: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
options: PropTypes.array,
|
||||
fieldNames: PropTypes.object,
|
||||
flattenOptions: PropTypes.array,
|
||||
height: PropTypes.number,
|
||||
itemHeight: PropTypes.number,
|
||||
values: PropTypes.any,
|
||||
multiple: PropTypes.looseBool,
|
||||
open: PropTypes.looseBool,
|
||||
defaultActiveFirstOption: PropTypes.looseBool,
|
||||
notFoundContent: PropTypes.any,
|
||||
menuItemSelectedIcon: PropTypes.any,
|
||||
childrenAsData: PropTypes.looseBool,
|
||||
searchValue: PropTypes.string,
|
||||
virtual: PropTypes.looseBool,
|
||||
direction: PropTypes.string,
|
||||
|
||||
onSelect: PropTypes.func,
|
||||
onToggleOpen: { type: Function as PropType<(open?: boolean) => void> },
|
||||
/** Tell Select that some value is now active to make accessibility work */
|
||||
onActiveValue: PropTypes.func,
|
||||
onScroll: PropTypes.func,
|
||||
|
||||
/** Tell Select that mouse enter the popup to force re-render */
|
||||
onMouseenter: PropTypes.func,
|
||||
};
|
||||
import useBaseProps from './hooks/useBaseProps';
|
||||
import type { RawValueType } from './Select';
|
||||
import useSelectProps from './SelectContext';
|
||||
// export interface OptionListProps<OptionsType extends object[]> {
|
||||
export type OptionListProps = Record<string, never>;
|
||||
|
||||
/**
|
||||
* Using virtual list of option display.
|
||||
* Will fallback to dom if use customize render.
|
||||
*/
|
||||
const OptionList = defineComponent<OptionListProps<SelectOptionsType[number]>, { state?: any }>({
|
||||
const OptionList = defineComponent({
|
||||
name: 'OptionList',
|
||||
inheritAttrs: false,
|
||||
slots: ['option'],
|
||||
setup(props) {
|
||||
const itemPrefixCls = computed(() => `${props.prefixCls}-item`);
|
||||
setup(_, { expose, slots }) {
|
||||
const baseProps = useBaseProps();
|
||||
const props = useSelectProps();
|
||||
const itemPrefixCls = computed(() => `${baseProps.prefixCls}-item`);
|
||||
|
||||
const memoFlattenOptions = useMemo(
|
||||
() => props.flattenOptions,
|
||||
[() => props.open, () => props.flattenOptions],
|
||||
[() => baseProps.open, () => props.flattenOptions],
|
||||
next => next[0],
|
||||
);
|
||||
|
||||
|
|
@ -124,7 +64,7 @@ const OptionList = defineComponent<OptionListProps<SelectOptionsType[number]>, {
|
|||
const current = (index + i * offset + len) % len;
|
||||
|
||||
const { group, data } = memoFlattenOptions.value[current];
|
||||
if (!group && !(data as OptionData).disabled) {
|
||||
if (!group && !data.disabled) {
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
|
@ -152,7 +92,7 @@ const OptionList = defineComponent<OptionListProps<SelectOptionsType[number]>, {
|
|||
// Auto active first item when list length or searchValue changed
|
||||
|
||||
watch(
|
||||
[() => memoFlattenOptions.value.length, () => props.searchValue],
|
||||
[() => memoFlattenOptions.value.length, () => baseProps.searchValue],
|
||||
() => {
|
||||
setActive(props.defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
|
||||
},
|
||||
|
|
@ -161,10 +101,10 @@ const OptionList = defineComponent<OptionListProps<SelectOptionsType[number]>, {
|
|||
// Auto scroll to item position in single mode
|
||||
|
||||
watch(
|
||||
[() => props.open, () => props.searchValue],
|
||||
[() => baseProps.open, () => baseProps.searchValue],
|
||||
() => {
|
||||
if (!props.multiple && props.open && props.values.size === 1) {
|
||||
const value = Array.from(props.values)[0];
|
||||
if (!baseProps.multiple && baseProps.open && props.rawValues.size === 1) {
|
||||
const value = Array.from(props.rawValues)[0];
|
||||
const index = memoFlattenOptions.value.findIndex(({ data }) => data.value === value);
|
||||
if (index !== -1) {
|
||||
setActive(index);
|
||||
|
|
@ -174,7 +114,7 @@ const OptionList = defineComponent<OptionListProps<SelectOptionsType[number]>, {
|
|||
}
|
||||
}
|
||||
// Force trigger scrollbar visible when open
|
||||
if (props.open) {
|
||||
if (baseProps.open) {
|
||||
nextTick(() => {
|
||||
listRef.current?.scrollTo(undefined);
|
||||
});
|
||||
|
|
@ -186,262 +126,253 @@ const OptionList = defineComponent<OptionListProps<SelectOptionsType[number]>, {
|
|||
// ========================== Values ==========================
|
||||
const onSelectValue = (value?: RawValueType) => {
|
||||
if (value !== undefined) {
|
||||
props.onSelect(value, { selected: !props.values.has(value) });
|
||||
props.onSelect(value, { selected: !props.rawValues.has(value) });
|
||||
}
|
||||
|
||||
// Single mode should always close by select
|
||||
if (!props.multiple) {
|
||||
props.onToggleOpen(false);
|
||||
if (!baseProps.multiple) {
|
||||
baseProps.toggleOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
const getLabel = (item: Record<string, any>) => item.label;
|
||||
function renderItem(index: number) {
|
||||
const item = memoFlattenOptions.value[index];
|
||||
if (!item) return null;
|
||||
|
||||
const itemData = (item.data || {}) as OptionData;
|
||||
const { value, label, children } = itemData;
|
||||
const itemData = item.data || {};
|
||||
const { value } = itemData;
|
||||
const { group } = item;
|
||||
const attrs = pickAttrs(itemData, true);
|
||||
const mergedLabel = props.childrenAsData ? children : label;
|
||||
const mergedLabel = getLabel(item);
|
||||
return item ? (
|
||||
<div
|
||||
aria-label={typeof mergedLabel === 'string' ? mergedLabel : undefined}
|
||||
aria-label={typeof mergedLabel === 'string' && !group ? mergedLabel : null}
|
||||
{...attrs}
|
||||
key={index}
|
||||
role="option"
|
||||
id={`${props.id}_list_${index}`}
|
||||
aria-selected={props.values.has(value)}
|
||||
role={group ? 'presentation' : 'option'}
|
||||
id={`${baseProps.id}_list_${index}`}
|
||||
aria-selected={props.rawValues.has(value)}
|
||||
>
|
||||
{value}
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
return {
|
||||
memoFlattenOptions,
|
||||
renderItem,
|
||||
listRef,
|
||||
state,
|
||||
onListMouseDown,
|
||||
itemPrefixCls,
|
||||
setActive,
|
||||
onSelectValue,
|
||||
onKeydown: (event: KeyboardEvent) => {
|
||||
const { which, ctrlKey } = event;
|
||||
switch (which) {
|
||||
// >>> Arrow keys & ctrl + n/p on Mac
|
||||
case KeyCode.N:
|
||||
case KeyCode.P:
|
||||
case KeyCode.UP:
|
||||
case KeyCode.DOWN: {
|
||||
let offset = 0;
|
||||
if (which === KeyCode.UP) {
|
||||
offset = -1;
|
||||
} else if (which === KeyCode.DOWN) {
|
||||
const onKeydown = (event: KeyboardEvent) => {
|
||||
const { which, ctrlKey } = event;
|
||||
switch (which) {
|
||||
// >>> Arrow keys & ctrl + n/p on Mac
|
||||
case KeyCode.N:
|
||||
case KeyCode.P:
|
||||
case KeyCode.UP:
|
||||
case KeyCode.DOWN: {
|
||||
let offset = 0;
|
||||
if (which === KeyCode.UP) {
|
||||
offset = -1;
|
||||
} else if (which === KeyCode.DOWN) {
|
||||
offset = 1;
|
||||
} else if (isPlatformMac() && ctrlKey) {
|
||||
if (which === KeyCode.N) {
|
||||
offset = 1;
|
||||
} else if (isPlatformMac() && ctrlKey) {
|
||||
if (which === KeyCode.N) {
|
||||
offset = 1;
|
||||
} else if (which === KeyCode.P) {
|
||||
offset = -1;
|
||||
}
|
||||
} else if (which === KeyCode.P) {
|
||||
offset = -1;
|
||||
}
|
||||
|
||||
if (offset !== 0) {
|
||||
const nextActiveIndex = getEnabledActiveIndex(state.activeIndex + offset, offset);
|
||||
scrollIntoView(nextActiveIndex);
|
||||
setActive(nextActiveIndex, true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// >>> Select
|
||||
case KeyCode.ENTER: {
|
||||
// value
|
||||
const item = memoFlattenOptions.value[state.activeIndex];
|
||||
if (item && !item.data.disabled) {
|
||||
onSelectValue(item.data.value);
|
||||
} else {
|
||||
onSelectValue(undefined);
|
||||
}
|
||||
|
||||
if (props.open) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
break;
|
||||
if (offset !== 0) {
|
||||
const nextActiveIndex = getEnabledActiveIndex(state.activeIndex + offset, offset);
|
||||
scrollIntoView(nextActiveIndex);
|
||||
setActive(nextActiveIndex, true);
|
||||
}
|
||||
|
||||
// >>> Close
|
||||
case KeyCode.ESC: {
|
||||
props.onToggleOpen(false);
|
||||
if (props.open) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// >>> Select
|
||||
case KeyCode.ENTER: {
|
||||
// value
|
||||
const item = memoFlattenOptions.value[state.activeIndex];
|
||||
if (item && !item.data.disabled) {
|
||||
onSelectValue(item.data.value);
|
||||
} else {
|
||||
onSelectValue(undefined);
|
||||
}
|
||||
|
||||
if (baseProps.open) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// >>> Close
|
||||
case KeyCode.ESC: {
|
||||
baseProps.toggleOpen(false);
|
||||
if (baseProps.open) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
},
|
||||
onKeyup: () => {},
|
||||
|
||||
scrollTo: (index: number) => {
|
||||
scrollIntoView(index);
|
||||
},
|
||||
}
|
||||
};
|
||||
},
|
||||
render() {
|
||||
const {
|
||||
renderItem,
|
||||
listRef,
|
||||
onListMouseDown,
|
||||
itemPrefixCls,
|
||||
setActive,
|
||||
onSelectValue,
|
||||
memoFlattenOptions,
|
||||
$slots,
|
||||
} = this as any;
|
||||
const {
|
||||
id,
|
||||
childrenAsData,
|
||||
values,
|
||||
height,
|
||||
itemHeight,
|
||||
menuItemSelectedIcon,
|
||||
notFoundContent,
|
||||
virtual,
|
||||
fieldNames,
|
||||
onScroll,
|
||||
onMouseenter,
|
||||
} = this.$props;
|
||||
const renderOption = $slots.option;
|
||||
const { activeIndex } = this.state;
|
||||
const omitFieldNameList = Object.values(fillFieldNames(fieldNames));
|
||||
// ========================== Render ==========================
|
||||
if (memoFlattenOptions.length === 0) {
|
||||
const onKeyup = () => {};
|
||||
|
||||
const scrollTo = (index: number) => {
|
||||
scrollIntoView(index);
|
||||
};
|
||||
expose({
|
||||
onKeydown,
|
||||
onKeyup,
|
||||
scrollTo,
|
||||
});
|
||||
return () => {
|
||||
// const {
|
||||
// renderItem,
|
||||
// listRef,
|
||||
// onListMouseDown,
|
||||
// itemPrefixCls,
|
||||
// setActive,
|
||||
// onSelectValue,
|
||||
// memoFlattenOptions,
|
||||
// $slots,
|
||||
// } = this as any;
|
||||
const { id, notFoundContent, onPopupScroll } = baseProps;
|
||||
const { menuItemSelectedIcon, rawValues, fieldNames, virtual, listHeight, listItemHeight } =
|
||||
props;
|
||||
|
||||
const renderOption = slots.option;
|
||||
const { activeIndex } = state;
|
||||
const omitFieldNameList = Object.keys(fieldNames).map(key => fieldNames[key]);
|
||||
// ========================== Render ==========================
|
||||
if (memoFlattenOptions.value.length === 0) {
|
||||
return (
|
||||
<div
|
||||
role="listbox"
|
||||
id={`${id}_list`}
|
||||
class={`${itemPrefixCls.value}-empty`}
|
||||
onMousedown={onListMouseDown}
|
||||
>
|
||||
{notFoundContent}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div
|
||||
role="listbox"
|
||||
id={`${id}_list`}
|
||||
class={`${itemPrefixCls}-empty`}
|
||||
onMousedown={onListMouseDown}
|
||||
>
|
||||
{notFoundContent}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div role="listbox" id={`${id}_list`} style={{ height: 0, width: 0, overflow: 'hidden' }}>
|
||||
{renderItem(activeIndex - 1)}
|
||||
{renderItem(activeIndex)}
|
||||
{renderItem(activeIndex + 1)}
|
||||
</div>
|
||||
<List
|
||||
itemKey="key"
|
||||
ref={listRef}
|
||||
data={memoFlattenOptions}
|
||||
height={height}
|
||||
itemHeight={itemHeight}
|
||||
fullHeight={false}
|
||||
onMousedown={onListMouseDown}
|
||||
onScroll={onScroll}
|
||||
virtual={virtual}
|
||||
onMouseenter={onMouseenter}
|
||||
v-slots={{
|
||||
default: ({ group, groupOption, data, label, value }, itemIndex) => {
|
||||
const { key } = data;
|
||||
// Group
|
||||
if (group) {
|
||||
<>
|
||||
<div role="listbox" id={`${id}_list`} style={{ height: 0, width: 0, overflow: 'hidden' }}>
|
||||
{renderItem(activeIndex - 1)}
|
||||
{renderItem(activeIndex)}
|
||||
{renderItem(activeIndex + 1)}
|
||||
</div>
|
||||
<List
|
||||
itemKey="key"
|
||||
ref={listRef}
|
||||
data={memoFlattenOptions.value}
|
||||
height={listHeight}
|
||||
itemHeight={listItemHeight}
|
||||
fullHeight={false}
|
||||
onMousedown={onListMouseDown}
|
||||
onScroll={onPopupScroll}
|
||||
virtual={virtual}
|
||||
v-slots={{
|
||||
default: (item, itemIndex) => {
|
||||
const { group, groupOption, data, label, value } = item;
|
||||
const { key } = data;
|
||||
// Group
|
||||
if (group) {
|
||||
return (
|
||||
<div class={classNames(itemPrefixCls.value, `${itemPrefixCls.value}-group`)}>
|
||||
{renderOption ? renderOption(data) : label !== undefined ? label : key}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
disabled,
|
||||
title,
|
||||
children,
|
||||
style,
|
||||
class: cls,
|
||||
className,
|
||||
...otherProps
|
||||
} = data;
|
||||
const passedProps = omit(otherProps, omitFieldNameList);
|
||||
// Option
|
||||
const selected = rawValues.has(value);
|
||||
|
||||
const optionPrefixCls = `${itemPrefixCls.value}-option`;
|
||||
const optionClassName = classNames(
|
||||
itemPrefixCls.value,
|
||||
optionPrefixCls,
|
||||
cls,
|
||||
className,
|
||||
{
|
||||
[`${optionPrefixCls}-grouped`]: groupOption,
|
||||
[`${optionPrefixCls}-active`]: activeIndex === itemIndex && !disabled,
|
||||
[`${optionPrefixCls}-disabled`]: disabled,
|
||||
[`${optionPrefixCls}-selected`]: selected,
|
||||
},
|
||||
);
|
||||
|
||||
const mergedLabel = getLabel(item);
|
||||
|
||||
const iconVisible =
|
||||
!menuItemSelectedIcon || typeof menuItemSelectedIcon === 'function' || selected;
|
||||
|
||||
const content = mergedLabel || value;
|
||||
// https://github.com/ant-design/ant-design/issues/26717
|
||||
let optionTitle =
|
||||
typeof content === 'string' || typeof content === 'number'
|
||||
? content.toString()
|
||||
: undefined;
|
||||
if (title !== undefined) {
|
||||
optionTitle = title;
|
||||
}
|
||||
|
||||
return (
|
||||
<div class={classNames(itemPrefixCls, `${itemPrefixCls}-group`)}>
|
||||
{renderOption ? renderOption(data) : label !== undefined ? label : key}
|
||||
<div
|
||||
{...passedProps}
|
||||
aria-selected={selected}
|
||||
class={optionClassName}
|
||||
title={optionTitle}
|
||||
onMousemove={e => {
|
||||
if (otherProps.onMousemove) {
|
||||
otherProps.onMousemove(e);
|
||||
}
|
||||
if (activeIndex === itemIndex || disabled) {
|
||||
return;
|
||||
}
|
||||
setActive(itemIndex);
|
||||
}}
|
||||
onClick={e => {
|
||||
if (!disabled) {
|
||||
onSelectValue(value);
|
||||
}
|
||||
if (otherProps.onClick) {
|
||||
otherProps.onClick(e);
|
||||
}
|
||||
}}
|
||||
style={style}
|
||||
>
|
||||
<div class={`${optionPrefixCls}-content`}>
|
||||
{renderOption ? renderOption(data) : content}
|
||||
</div>
|
||||
{isValidElement(menuItemSelectedIcon) || selected}
|
||||
{iconVisible && (
|
||||
<TransBtn
|
||||
class={`${itemPrefixCls.value}-option-state`}
|
||||
customizeIcon={menuItemSelectedIcon}
|
||||
customizeIconProps={{ isSelected: selected }}
|
||||
>
|
||||
{selected ? '✓' : null}
|
||||
</TransBtn>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
disabled,
|
||||
title,
|
||||
children,
|
||||
style,
|
||||
class: cls,
|
||||
className,
|
||||
...otherProps
|
||||
} = data;
|
||||
const passedProps = omit(otherProps, omitFieldNameList);
|
||||
// Option
|
||||
const selected = values.has(value);
|
||||
|
||||
const optionPrefixCls = `${itemPrefixCls}-option`;
|
||||
const optionClassName = classNames(itemPrefixCls, optionPrefixCls, cls, className, {
|
||||
[`${optionPrefixCls}-grouped`]: groupOption,
|
||||
[`${optionPrefixCls}-active`]: activeIndex === itemIndex && !disabled,
|
||||
[`${optionPrefixCls}-disabled`]: disabled,
|
||||
[`${optionPrefixCls}-selected`]: selected,
|
||||
});
|
||||
|
||||
const mergedLabel = childrenAsData ? children : label;
|
||||
|
||||
const iconVisible =
|
||||
!menuItemSelectedIcon || typeof menuItemSelectedIcon === 'function' || selected;
|
||||
|
||||
const content = mergedLabel || value;
|
||||
// https://github.com/ant-design/ant-design/issues/26717
|
||||
let optionTitle =
|
||||
typeof content === 'string' || typeof content === 'number'
|
||||
? content.toString()
|
||||
: undefined;
|
||||
if (title !== undefined) {
|
||||
optionTitle = title;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
{...passedProps}
|
||||
aria-selected={selected}
|
||||
class={optionClassName}
|
||||
title={optionTitle}
|
||||
onMousemove={e => {
|
||||
if (otherProps.onMousemove) {
|
||||
otherProps.onMousemove(e);
|
||||
}
|
||||
if (activeIndex === itemIndex || disabled) {
|
||||
return;
|
||||
}
|
||||
setActive(itemIndex);
|
||||
}}
|
||||
onClick={e => {
|
||||
if (!disabled) {
|
||||
onSelectValue(value);
|
||||
}
|
||||
if (otherProps.onClick) {
|
||||
otherProps.onClick(e);
|
||||
}
|
||||
}}
|
||||
style={style}
|
||||
>
|
||||
<div class={`${optionPrefixCls}-content`}>
|
||||
{renderOption ? renderOption(data) : content}
|
||||
</div>
|
||||
{isValidElement(menuItemSelectedIcon) || selected}
|
||||
{iconVisible && (
|
||||
<TransBtn
|
||||
class={`${itemPrefixCls}-option-state`}
|
||||
customizeIcon={menuItemSelectedIcon}
|
||||
customizeIconProps={{ isSelected: selected }}
|
||||
>
|
||||
{selected ? '✓' : null}
|
||||
</TransBtn>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
}}
|
||||
></List>
|
||||
</>
|
||||
);
|
||||
},
|
||||
}}
|
||||
></List>
|
||||
</>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
OptionList.props = OptionListProps;
|
||||
|
||||
export default OptionList;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* To match accessibility requirement, we always provide an input in the component.
|
||||
* Other element will not set `tabIndex` to avoid `onBlur` sequence problem.
|
||||
* Other element will not set `tabindex` to avoid `onBlur` sequence problem.
|
||||
* For focused select, we set `aria-live="polite"` to update the accessibility content.
|
||||
*
|
||||
* ref:
|
||||
|
|
@ -29,76 +29,614 @@
|
|||
* - `combobox` mode not support `optionLabelProp`
|
||||
*/
|
||||
|
||||
import type { OptionsType as SelectOptionsType } from './interface';
|
||||
import SelectOptionList from './OptionList';
|
||||
import Option from './Option';
|
||||
import OptGroup from './OptGroup';
|
||||
import { convertChildrenToData as convertSelectChildrenToData } from './utils/legacyUtil';
|
||||
import {
|
||||
getLabeledValue as getSelectLabeledValue,
|
||||
filterOptions as selectDefaultFilterOptions,
|
||||
isValueDisabled as isSelectValueDisabled,
|
||||
findValueOption as findSelectValueOption,
|
||||
flattenOptions,
|
||||
fillOptionsWithMissingValue,
|
||||
} from './utils/valueUtil';
|
||||
import type { SelectProps } from './generate';
|
||||
import generateSelector, { selectBaseProps } from './generate';
|
||||
import type { DefaultValueType } from './interface/generator';
|
||||
import BaseSelect, { baseSelectPropsWithoutPrivate, isMultiple } from './BaseSelect';
|
||||
import type { DisplayValueType, BaseSelectRef, BaseSelectProps } from './BaseSelect';
|
||||
import OptionList from './OptionList';
|
||||
import useOptions from './hooks/useOptions';
|
||||
import type { SelectContextProps } from './SelectContext';
|
||||
import { useProvideSelectProps } from './SelectContext';
|
||||
import useId from './hooks/useId';
|
||||
import { fillFieldNames, flattenOptions, injectPropsWithOption } from './utils/valueUtil';
|
||||
import warningProps from './utils/warningPropsUtil';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { toArray } from './utils/commonUtil';
|
||||
import useFilterOptions from './hooks/useFilterOptions';
|
||||
import useCache from './hooks/useCache';
|
||||
import type { Key, VueNode } from '../_util/type';
|
||||
import { computed, defineComponent, ref, toRef, watchEffect } from 'vue';
|
||||
import type { ExtractPropTypes, PropType } from 'vue';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { initDefaultProps } from '../_util/props-util';
|
||||
import useMergedState from '../_util/hooks/useMergedState';
|
||||
import useState from '../_util/hooks/useState';
|
||||
import { toReactive } from '../_util/toReactive';
|
||||
import omit from '../_util/omit';
|
||||
|
||||
const RefSelect = generateSelector<SelectOptionsType[number]>({
|
||||
prefixCls: 'rc-select',
|
||||
components: {
|
||||
optionList: SelectOptionList as any,
|
||||
},
|
||||
convertChildrenToData: convertSelectChildrenToData,
|
||||
flattenOptions,
|
||||
getLabeledValue: getSelectLabeledValue,
|
||||
filterOptions: selectDefaultFilterOptions,
|
||||
isValueDisabled: isSelectValueDisabled,
|
||||
findValueOption: findSelectValueOption,
|
||||
warningProps,
|
||||
fillOptionsWithMissingValue,
|
||||
});
|
||||
const OMIT_DOM_PROPS = ['inputValue'];
|
||||
|
||||
export type ExportedSelectProps<T extends DefaultValueType = DefaultValueType> = SelectProps<
|
||||
SelectOptionsType[number],
|
||||
T
|
||||
>;
|
||||
export type OnActiveValue = (
|
||||
active: RawValueType,
|
||||
index: number,
|
||||
info?: { source?: 'keyboard' | 'mouse' },
|
||||
) => void;
|
||||
|
||||
export function selectProps<T>() {
|
||||
return selectBaseProps<SelectOptionsType[number], T>();
|
||||
export type OnInternalSelect = (value: RawValueType, info: { selected: boolean }) => void;
|
||||
|
||||
export type RawValueType = string | number;
|
||||
export interface LabelInValueType {
|
||||
label: any;
|
||||
value: RawValueType;
|
||||
/** @deprecated `key` is useless since it should always same as `value` */
|
||||
key?: Key;
|
||||
}
|
||||
|
||||
const Select = defineComponent({
|
||||
export type DraftValueType =
|
||||
| RawValueType
|
||||
| LabelInValueType
|
||||
| DisplayValueType
|
||||
| (RawValueType | LabelInValueType | DisplayValueType)[];
|
||||
|
||||
export type FilterFunc<OptionType> = (inputValue: string, option?: OptionType) => boolean;
|
||||
|
||||
export interface FieldNames {
|
||||
value?: string;
|
||||
label?: string;
|
||||
options?: string;
|
||||
}
|
||||
|
||||
export interface BaseOptionType {
|
||||
disabled?: boolean;
|
||||
[name: string]: any;
|
||||
}
|
||||
|
||||
export interface DefaultOptionType extends BaseOptionType {
|
||||
label?: any;
|
||||
value?: string | number | null;
|
||||
children?: Omit<DefaultOptionType, 'children'>[];
|
||||
}
|
||||
|
||||
export type SelectHandler<ValueType = any, OptionType extends BaseOptionType = DefaultOptionType> =
|
||||
| ((value: RawValueType | LabelInValueType, option: OptionType) => void)
|
||||
| ((value: ValueType, option: OptionType) => void);
|
||||
|
||||
export function selectProps<
|
||||
ValueType = any,
|
||||
OptionType extends BaseOptionType = DefaultOptionType,
|
||||
>() {
|
||||
return {
|
||||
...baseSelectPropsWithoutPrivate(),
|
||||
prefixCls: String,
|
||||
id: String,
|
||||
|
||||
backfill: { type: Boolean, default: undefined },
|
||||
|
||||
// >>> Field Names
|
||||
fieldNames: Object as PropType<FieldNames>,
|
||||
|
||||
// >>> Search
|
||||
/** @deprecated Use `searchValue` instead */
|
||||
inputValue: String,
|
||||
searchValue: String,
|
||||
onSearch: Function as PropType<(value: string) => void>,
|
||||
autoClearSearchValue: { type: Boolean, default: undefined },
|
||||
|
||||
// >>> Select
|
||||
onSelect: Function as PropType<SelectHandler<ValueType, OptionType>>,
|
||||
onDeselect: Function as PropType<SelectHandler<ValueType, OptionType>>,
|
||||
|
||||
// >>> Options
|
||||
/**
|
||||
* In Select, `false` means do nothing.
|
||||
* In TreeSelect, `false` will highlight match item.
|
||||
* It's by design.
|
||||
*/
|
||||
filterOption: {
|
||||
type: [Boolean, Function] as PropType<boolean | FilterFunc<OptionType>>,
|
||||
default: undefined,
|
||||
},
|
||||
filterSort: Function as PropType<(optionA: OptionType, optionB: OptionType) => number>,
|
||||
optionFilterProp: String,
|
||||
optionLabelProp: String,
|
||||
options: Array as PropType<OptionType[]>,
|
||||
defaultActiveFirstOption: { type: Boolean, default: undefined },
|
||||
virtual: { type: Boolean, default: undefined },
|
||||
listHeight: Number,
|
||||
listItemHeight: Number,
|
||||
|
||||
// >>> Icon
|
||||
menuItemSelectedIcon: PropTypes.any,
|
||||
|
||||
mode: String as PropType<'combobox' | 'multiple' | 'tags'>,
|
||||
labelInValue: { type: Boolean, default: undefined },
|
||||
value: PropTypes.any,
|
||||
defaultValue: PropTypes.any,
|
||||
onChange: Function as PropType<(value: ValueType, option: OptionType | OptionType[]) => void>,
|
||||
children: Array as PropType<VueNode[]>,
|
||||
};
|
||||
}
|
||||
|
||||
export type SelectProps = Partial<ExtractPropTypes<ReturnType<typeof selectProps>>>;
|
||||
|
||||
function isRawValue(value: DraftValueType): value is RawValueType {
|
||||
return !value || typeof value !== 'object';
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Select',
|
||||
inheritAttrs: false,
|
||||
Option,
|
||||
OptGroup,
|
||||
props: RefSelect.props,
|
||||
setup(props, { attrs, expose, slots }) {
|
||||
const selectRef = ref();
|
||||
props: initDefaultProps(selectProps(), {
|
||||
prefixCls: 'vc-select',
|
||||
autoClearSearchValue: true,
|
||||
listHeight: 200,
|
||||
listItemHeight: 20,
|
||||
}),
|
||||
setup(props, { expose, attrs, slots }) {
|
||||
const mergedId = useId(toRef(props, 'id'));
|
||||
const multiple = computed(() => isMultiple(props.mode));
|
||||
const childrenAsData = computed(() => !!(!props.options && props.children));
|
||||
|
||||
const mergedFilterOption = computed(() => {
|
||||
if (props.filterOption === undefined && props.mode === 'combobox') {
|
||||
return false;
|
||||
}
|
||||
return props.filterOption;
|
||||
});
|
||||
|
||||
// ========================= FieldNames =========================
|
||||
const mergedFieldNames = computed(() => fillFieldNames(props.fieldNames, childrenAsData.value));
|
||||
|
||||
// =========================== Search ===========================
|
||||
const [mergedSearchValue, setSearchValue] = useMergedState('', {
|
||||
value: computed(() =>
|
||||
props.searchValue !== undefined ? props.searchValue : props.inputValue,
|
||||
),
|
||||
postState: search => search || '',
|
||||
});
|
||||
|
||||
// =========================== Option ===========================
|
||||
const parsedOptions = useOptions(
|
||||
toRef(props, 'options'),
|
||||
toRef(props, 'children'),
|
||||
mergedFieldNames,
|
||||
);
|
||||
const { valueOptions, labelOptions, options: mergedOptions } = parsedOptions;
|
||||
|
||||
// ========================= Wrap Value =========================
|
||||
const convert2LabelValues = (draftValues: DraftValueType) => {
|
||||
// Convert to array
|
||||
const valueList = toArray(draftValues);
|
||||
|
||||
// Convert to labelInValue type
|
||||
return valueList.map(val => {
|
||||
let rawValue: RawValueType;
|
||||
let rawLabel: any;
|
||||
let rawKey: Key;
|
||||
let rawDisabled: boolean | undefined;
|
||||
|
||||
// Fill label & value
|
||||
if (isRawValue(val)) {
|
||||
rawValue = val;
|
||||
} else {
|
||||
rawKey = val.key;
|
||||
rawLabel = val.label;
|
||||
rawValue = val.value ?? rawKey;
|
||||
}
|
||||
|
||||
const option = valueOptions.value.get(rawValue);
|
||||
if (option) {
|
||||
// Fill missing props
|
||||
if (rawLabel === undefined)
|
||||
rawLabel = option?.[props.optionLabelProp || mergedFieldNames.value.label];
|
||||
if (rawKey === undefined) rawKey = option?.key ?? rawValue;
|
||||
rawDisabled = option?.disabled;
|
||||
|
||||
// Warning if label not same as provided
|
||||
// if (process.env.NODE_ENV !== 'production' && !isRawValue(val)) {
|
||||
// const optionLabel = option?.[mergedFieldNames.value.label];
|
||||
// if (optionLabel !== undefined && optionLabel !== rawLabel) {
|
||||
// warning(false, '`label` of `value` is not same as `label` in Select options.');
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
return {
|
||||
label: rawLabel,
|
||||
value: rawValue,
|
||||
key: rawKey,
|
||||
disabled: rawDisabled,
|
||||
option,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// =========================== Values ===========================
|
||||
const [internalValue, setInternalValue] = useMergedState(props.defaultValue, {
|
||||
value: toRef(props, 'value'),
|
||||
});
|
||||
|
||||
// Merged value with LabelValueType
|
||||
const rawLabeledValues = computed(() => {
|
||||
const values = convert2LabelValues(internalValue.value);
|
||||
|
||||
// combobox no need save value when it's empty
|
||||
if (props.mode === 'combobox' && !values[0]?.value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return values;
|
||||
});
|
||||
|
||||
// Fill label with cache to avoid option remove
|
||||
const [mergedValues, getMixedOption] = useCache(rawLabeledValues, valueOptions);
|
||||
|
||||
const displayValues = computed(() => {
|
||||
// `null` need show as placeholder instead
|
||||
// https://github.com/ant-design/ant-design/issues/25057
|
||||
if (!props.mode && mergedValues.value.length === 1) {
|
||||
const firstValue = mergedValues.value[0];
|
||||
if (
|
||||
firstValue.value === null &&
|
||||
(firstValue.label === null || firstValue.label === undefined)
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
return mergedValues.value.map(item => ({
|
||||
...item,
|
||||
label: item.label ?? item.value,
|
||||
}));
|
||||
});
|
||||
|
||||
/** Convert `displayValues` to raw value type set */
|
||||
const rawValues = computed(() => new Set(mergedValues.value.map(val => val.value)));
|
||||
|
||||
watchEffect(
|
||||
() => {
|
||||
if (props.mode === 'combobox') {
|
||||
const strValue = mergedValues.value[0]?.value;
|
||||
|
||||
if (strValue !== undefined && strValue !== null) {
|
||||
setSearchValue(String(strValue));
|
||||
}
|
||||
}
|
||||
},
|
||||
{ flush: 'post' },
|
||||
);
|
||||
|
||||
// ======================= Display Option =======================
|
||||
// Create a placeholder item if not exist in `options`
|
||||
const createTagOption = (val: RawValueType, label?: any) => {
|
||||
const mergedLabel = label ?? val;
|
||||
return {
|
||||
[mergedFieldNames.value.value]: val,
|
||||
[mergedFieldNames.value.label]: mergedLabel,
|
||||
} as DefaultOptionType;
|
||||
};
|
||||
|
||||
// Fill tag as option if mode is `tags`
|
||||
const filledTagOptions = computed(() => {
|
||||
if (props.mode !== 'tags') {
|
||||
return mergedOptions.value;
|
||||
}
|
||||
|
||||
// >>> Tag mode
|
||||
const cloneOptions = [...mergedOptions.value];
|
||||
|
||||
// Check if value exist in options (include new patch item)
|
||||
const existOptions = (val: RawValueType) => valueOptions.value.has(val);
|
||||
|
||||
// Fill current value as option
|
||||
[...mergedValues.value]
|
||||
.sort((a, b) => (a.value < b.value ? -1 : 1))
|
||||
.forEach(item => {
|
||||
const val = item.value;
|
||||
|
||||
if (!existOptions(val)) {
|
||||
cloneOptions.push(createTagOption(val, item.label));
|
||||
}
|
||||
});
|
||||
|
||||
return cloneOptions;
|
||||
});
|
||||
|
||||
const filteredOptions = useFilterOptions(
|
||||
filledTagOptions,
|
||||
mergedFieldNames,
|
||||
mergedSearchValue,
|
||||
mergedFilterOption,
|
||||
toRef(props, 'optionFilterProp'),
|
||||
);
|
||||
|
||||
// Fill options with search value if needed
|
||||
const filledSearchOptions = computed(() => {
|
||||
if (
|
||||
props.mode !== 'tags' ||
|
||||
!mergedSearchValue.value ||
|
||||
filteredOptions.value.some(
|
||||
item => item[props.optionFilterProp || 'value'] === mergedSearchValue.value,
|
||||
)
|
||||
) {
|
||||
return filteredOptions.value;
|
||||
}
|
||||
|
||||
// Fill search value as option
|
||||
return [createTagOption(mergedSearchValue.value), ...filteredOptions.value];
|
||||
});
|
||||
|
||||
const orderedFilteredOptions = computed(() => {
|
||||
if (!props.filterSort) {
|
||||
return filledSearchOptions.value;
|
||||
}
|
||||
|
||||
return [...filledSearchOptions.value].sort((a, b) => props.filterSort(a, b));
|
||||
});
|
||||
|
||||
const displayOptions = computed(() =>
|
||||
flattenOptions(orderedFilteredOptions.value, {
|
||||
fieldNames: mergedFieldNames.value,
|
||||
childrenAsData: childrenAsData.value,
|
||||
}),
|
||||
);
|
||||
|
||||
// =========================== Change ===========================
|
||||
const triggerChange = (values: DraftValueType) => {
|
||||
const labeledValues = convert2LabelValues(values);
|
||||
setInternalValue(labeledValues);
|
||||
|
||||
if (
|
||||
props.onChange &&
|
||||
// Trigger event only when value changed
|
||||
(labeledValues.length !== mergedValues.value.length ||
|
||||
labeledValues.some((newVal, index) => mergedValues.value[index]?.value !== newVal?.value))
|
||||
) {
|
||||
const returnValues = props.labelInValue ? labeledValues : labeledValues.map(v => v.value);
|
||||
const returnOptions = labeledValues.map(v =>
|
||||
injectPropsWithOption(getMixedOption(v.value)),
|
||||
);
|
||||
|
||||
props.onChange(
|
||||
// Value
|
||||
multiple.value ? returnValues : returnValues[0],
|
||||
// Option
|
||||
multiple.value ? returnOptions : returnOptions[0],
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// ======================= Accessibility ========================
|
||||
const [activeValue, setActiveValue] = useState<string>(null);
|
||||
const [accessibilityIndex, setAccessibilityIndex] = useState(0);
|
||||
const mergedDefaultActiveFirstOption = computed(() =>
|
||||
props.defaultActiveFirstOption !== undefined
|
||||
? props.defaultActiveFirstOption
|
||||
: props.mode !== 'combobox',
|
||||
);
|
||||
|
||||
const onActiveValue: OnActiveValue = (active, index, { source = 'keyboard' } = {}) => {
|
||||
setAccessibilityIndex(index);
|
||||
|
||||
if (props.backfill && props.mode === 'combobox' && active !== null && source === 'keyboard') {
|
||||
setActiveValue(String(active));
|
||||
}
|
||||
};
|
||||
|
||||
// ========================= OptionList =========================
|
||||
const triggerSelect = (val: RawValueType, selected: boolean) => {
|
||||
const getSelectEnt = (): [RawValueType | LabelInValueType, DefaultOptionType] => {
|
||||
const option = getMixedOption(val);
|
||||
return [
|
||||
props.labelInValue
|
||||
? {
|
||||
label: option?.[mergedFieldNames.value.label],
|
||||
value: val,
|
||||
key: option.key ?? val,
|
||||
}
|
||||
: val,
|
||||
injectPropsWithOption(option),
|
||||
];
|
||||
};
|
||||
|
||||
if (selected && props.onSelect) {
|
||||
const [wrappedValue, option] = getSelectEnt();
|
||||
props.onSelect(wrappedValue, option);
|
||||
} else if (!selected && props.onDeselect) {
|
||||
const [wrappedValue, option] = getSelectEnt();
|
||||
props.onDeselect(wrappedValue, option);
|
||||
}
|
||||
};
|
||||
|
||||
// Used for OptionList selection
|
||||
const onInternalSelect = (val, info) => {
|
||||
let cloneValues: (RawValueType | DisplayValueType)[];
|
||||
|
||||
// Single mode always trigger select only with option list
|
||||
const mergedSelect = multiple.value ? info.selected : true;
|
||||
|
||||
if (mergedSelect) {
|
||||
cloneValues = multiple.value ? [...mergedValues.value, val] : [val];
|
||||
} else {
|
||||
cloneValues = mergedValues.value.filter(v => v.value !== val);
|
||||
}
|
||||
|
||||
triggerChange(cloneValues);
|
||||
triggerSelect(val, mergedSelect);
|
||||
|
||||
// Clean search value if single or configured
|
||||
if (props.mode === 'combobox') {
|
||||
// setSearchValue(String(val));
|
||||
setActiveValue('');
|
||||
} else if (!multiple.value || props.autoClearSearchValue) {
|
||||
setSearchValue('');
|
||||
setActiveValue('');
|
||||
}
|
||||
};
|
||||
|
||||
// ======================= Display Change =======================
|
||||
// BaseSelect display values change
|
||||
const onDisplayValuesChange: BaseSelectProps['onDisplayValuesChange'] = (nextValues, info) => {
|
||||
triggerChange(nextValues);
|
||||
|
||||
if (info.type === 'remove' || info.type === 'clear') {
|
||||
info.values.forEach(item => {
|
||||
triggerSelect(item.value, false);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// =========================== Search ===========================
|
||||
const onInternalSearch: BaseSelectProps['onSearch'] = (searchText, info) => {
|
||||
setSearchValue(searchText);
|
||||
setActiveValue(null);
|
||||
|
||||
// [Submit] Tag mode should flush input
|
||||
if (info.source === 'submit') {
|
||||
const formatted = (searchText || '').trim();
|
||||
// prevent empty tags from appearing when you click the Enter button
|
||||
if (formatted) {
|
||||
const newRawValues = Array.from(new Set<RawValueType>([...rawValues.value, formatted]));
|
||||
triggerChange(newRawValues);
|
||||
triggerSelect(formatted, true);
|
||||
setSearchValue('');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.source !== 'blur') {
|
||||
if (props.mode === 'combobox') {
|
||||
triggerChange(searchText);
|
||||
}
|
||||
|
||||
props.onSearch?.(searchText);
|
||||
}
|
||||
};
|
||||
|
||||
const onInternalSearchSplit: BaseSelectProps['onSearchSplit'] = words => {
|
||||
let patchValues: RawValueType[] = words;
|
||||
|
||||
if (props.mode !== 'tags') {
|
||||
patchValues = words
|
||||
.map(word => {
|
||||
const opt = labelOptions.value.get(word);
|
||||
return opt?.value;
|
||||
})
|
||||
.filter(val => val !== undefined);
|
||||
}
|
||||
|
||||
const newRawValues = Array.from(new Set<RawValueType>([...rawValues.value, ...patchValues]));
|
||||
triggerChange(newRawValues);
|
||||
newRawValues.forEach(newRawValue => {
|
||||
triggerSelect(newRawValue, true);
|
||||
});
|
||||
};
|
||||
const realVirtual = computed(
|
||||
() => props.virtual !== false && props.dropdownMatchSelectWidth !== false,
|
||||
);
|
||||
useProvideSelectProps(
|
||||
toReactive({
|
||||
...parsedOptions,
|
||||
flattenOptions: displayOptions,
|
||||
onActiveValue,
|
||||
defaultActiveFirstOption: mergedDefaultActiveFirstOption,
|
||||
onSelect: onInternalSelect,
|
||||
menuItemSelectedIcon: toRef(props, 'menuItemSelectedIcon'),
|
||||
rawValues,
|
||||
fieldNames: mergedFieldNames,
|
||||
virtual: realVirtual,
|
||||
listHeight: toRef(props, 'listHeight'),
|
||||
listItemHeight: toRef(props, 'listItemHeight'),
|
||||
childrenAsData,
|
||||
} as unknown as SelectContextProps),
|
||||
);
|
||||
|
||||
// ========================== Warning ===========================
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
watchEffect(
|
||||
() => {
|
||||
warningProps(props);
|
||||
},
|
||||
{ flush: 'post' },
|
||||
);
|
||||
}
|
||||
const selectRef = ref<BaseSelectRef>();
|
||||
expose({
|
||||
focus: () => {
|
||||
focus() {
|
||||
selectRef.value?.focus();
|
||||
},
|
||||
blur: () => {
|
||||
blur() {
|
||||
selectRef.value?.blur();
|
||||
},
|
||||
scrollTo(arg) {
|
||||
selectRef.value?.scrollTo(arg);
|
||||
},
|
||||
} as BaseSelectRef);
|
||||
const pickProps = computed(() => {
|
||||
return omit(props, [
|
||||
'id',
|
||||
'mode',
|
||||
'prefixCls',
|
||||
'backfill',
|
||||
'fieldNames',
|
||||
|
||||
// Search
|
||||
'inputValue',
|
||||
'searchValue',
|
||||
'onSearch',
|
||||
'autoClearSearchValue',
|
||||
|
||||
// Select
|
||||
'onSelect',
|
||||
'onDeselect',
|
||||
'dropdownMatchSelectWidth',
|
||||
|
||||
// Options
|
||||
'filterOption',
|
||||
'filterSort',
|
||||
'optionFilterProp',
|
||||
'optionLabelProp',
|
||||
'options',
|
||||
'children',
|
||||
'defaultActiveFirstOption',
|
||||
'menuItemSelectedIcon',
|
||||
'virtual',
|
||||
'listHeight',
|
||||
'listItemHeight',
|
||||
|
||||
// Value
|
||||
'value',
|
||||
'defaultValue',
|
||||
'labelInValue',
|
||||
'onChange',
|
||||
]);
|
||||
});
|
||||
return () => {
|
||||
return (
|
||||
<RefSelect
|
||||
ref={selectRef}
|
||||
{...(props as any)}
|
||||
<BaseSelect
|
||||
{...pickProps.value}
|
||||
{...attrs}
|
||||
// >>> MISC
|
||||
id={mergedId}
|
||||
prefixCls={props.prefixCls}
|
||||
ref={selectRef}
|
||||
omitDomProps={OMIT_DOM_PROPS}
|
||||
mode={props.mode}
|
||||
// >>> Values
|
||||
displayValues={displayValues.value}
|
||||
onDisplayValuesChange={onDisplayValuesChange}
|
||||
// >>> Search
|
||||
searchValue={mergedSearchValue.value}
|
||||
onSearch={onInternalSearch}
|
||||
onSearchSplit={onInternalSearchSplit}
|
||||
dropdownMatchSelectWidth={props.dropdownMatchSelectWidth}
|
||||
// >>> OptionList
|
||||
OptionList={OptionList}
|
||||
emptyOptions={!displayOptions.value.length}
|
||||
// >>> Accessibility
|
||||
activeValue={activeValue.value}
|
||||
activeDescendantId={`${mergedId}_list_${accessibilityIndex.value}`}
|
||||
v-slots={slots}
|
||||
children={slots.default?.() || []}
|
||||
/>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
export default Select;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* BaseSelect provide some parsed data into context.
|
||||
* You can use this hooks to get them.
|
||||
*/
|
||||
|
||||
import type { InjectionKey } from 'vue';
|
||||
import { inject, provide } from 'vue';
|
||||
import type { RawValueType, RenderNode } from './BaseSelect';
|
||||
import type { FlattenOptionData } from './interface';
|
||||
import type { BaseOptionType, FieldNames, OnActiveValue, OnInternalSelect } from './Select';
|
||||
|
||||
// Use any here since we do not get the type during compilation
|
||||
export interface SelectContextProps {
|
||||
options: BaseOptionType[];
|
||||
flattenOptions: FlattenOptionData<BaseOptionType>[];
|
||||
onActiveValue: OnActiveValue;
|
||||
defaultActiveFirstOption?: boolean;
|
||||
onSelect: OnInternalSelect;
|
||||
menuItemSelectedIcon?: RenderNode;
|
||||
rawValues: Set<RawValueType>;
|
||||
fieldNames?: FieldNames;
|
||||
virtual?: boolean;
|
||||
listHeight?: number;
|
||||
listItemHeight?: number;
|
||||
childrenAsData?: boolean;
|
||||
}
|
||||
|
||||
const SelectContextKey: InjectionKey<SelectContextProps> = Symbol('SelectContextKey');
|
||||
|
||||
export function useProvideSelectProps(props: SelectContextProps) {
|
||||
return provide(SelectContextKey, props);
|
||||
}
|
||||
|
||||
export default function useSelectProps() {
|
||||
return inject(SelectContextKey, {} as SelectContextProps);
|
||||
}
|
||||
|
|
@ -1,19 +1,12 @@
|
|||
import Trigger from '../vc-trigger';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { getSlot } from '../_util/props-util';
|
||||
import classNames from '../_util/classNames';
|
||||
import createRef from '../_util/createRef';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import type { RenderDOMFunc } from './interface';
|
||||
import type { DropdownRender } from './interface/generator';
|
||||
import type { Placement } from './generate';
|
||||
import { computed, ref, defineComponent } from 'vue';
|
||||
import type { VueNode } from '../_util/type';
|
||||
import type { DropdownRender, Placement, RenderDOMFunc } from './BaseSelect';
|
||||
|
||||
const getBuiltInPlacements = (dropdownMatchSelectWidth: number | boolean) => {
|
||||
// Enable horizontal overflow auto-adjustment when a custom dropdown width is provided
|
||||
const adjustX = typeof dropdownMatchSelectWidth !== 'number' ? 0 : 1;
|
||||
|
||||
const getBuiltInPlacements = (adjustX: number) => {
|
||||
return {
|
||||
bottomLeft: {
|
||||
points: ['tl', 'bl'],
|
||||
|
|
@ -49,6 +42,19 @@ const getBuiltInPlacements = (dropdownMatchSelectWidth: number | boolean) => {
|
|||
},
|
||||
};
|
||||
};
|
||||
|
||||
const getAdjustX = (
|
||||
adjustXDependencies: Pick<SelectTriggerProps, 'autoAdjustOverflow' | 'dropdownMatchSelectWidth'>,
|
||||
) => {
|
||||
const { autoAdjustOverflow, dropdownMatchSelectWidth } = adjustXDependencies;
|
||||
if (!!autoAdjustOverflow) return 1;
|
||||
// Enable horizontal overflow auto-adjustment when a custom dropdown width is provided
|
||||
return typeof dropdownMatchSelectWidth !== 'number' ? 0 : 1;
|
||||
};
|
||||
export interface RefTriggerProps {
|
||||
getPopupElement: () => HTMLDivElement;
|
||||
}
|
||||
|
||||
export interface SelectTriggerProps {
|
||||
prefixCls: string;
|
||||
disabled: boolean;
|
||||
|
|
@ -66,103 +72,122 @@ export interface SelectTriggerProps {
|
|||
getPopupContainer?: RenderDOMFunc;
|
||||
dropdownAlign: object;
|
||||
empty: boolean;
|
||||
autoAdjustOverflow?: boolean;
|
||||
getTriggerDOMNode: () => any;
|
||||
onPopupVisibleChange?: (visible: boolean) => void;
|
||||
|
||||
onPopupMouseEnter: () => void;
|
||||
}
|
||||
|
||||
const SelectTrigger = defineComponent<SelectTriggerProps, { popupRef: any }>({
|
||||
name: 'SelectTrigger',
|
||||
inheritAttrs: false,
|
||||
created() {
|
||||
this.popupRef = createRef();
|
||||
},
|
||||
props: {
|
||||
dropdownAlign: PropTypes.object,
|
||||
visible: PropTypes.looseBool,
|
||||
disabled: PropTypes.looseBool,
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownStyle: PropTypes.object,
|
||||
placement: PropTypes.string,
|
||||
empty: PropTypes.looseBool,
|
||||
autoAdjustOverflow: PropTypes.looseBool,
|
||||
prefixCls: PropTypes.string,
|
||||
popupClassName: PropTypes.string,
|
||||
animation: PropTypes.string,
|
||||
transitionName: PropTypes.string,
|
||||
getPopupContainer: PropTypes.func,
|
||||
dropdownRender: PropTypes.func,
|
||||
containerWidth: PropTypes.number,
|
||||
dropdownMatchSelectWidth: PropTypes.oneOfType([Number, Boolean]).def(true),
|
||||
popupElement: PropTypes.any,
|
||||
direction: PropTypes.string,
|
||||
getTriggerDOMNode: PropTypes.func,
|
||||
onPopupVisibleChange: PropTypes.func,
|
||||
onPopupMouseEnter: PropTypes.func,
|
||||
} as any,
|
||||
setup(props, { slots, attrs, expose }) {
|
||||
const builtInPlacements = computed(() => {
|
||||
const { autoAdjustOverflow, dropdownMatchSelectWidth } = props;
|
||||
return getBuiltInPlacements(
|
||||
getAdjustX({
|
||||
autoAdjustOverflow,
|
||||
dropdownMatchSelectWidth,
|
||||
}),
|
||||
);
|
||||
});
|
||||
const popupRef = ref();
|
||||
expose({
|
||||
getPopupElement: () => {
|
||||
return popupRef.value;
|
||||
},
|
||||
});
|
||||
return () => {
|
||||
const { empty = false, ...restProps } = { ...props, ...attrs };
|
||||
const {
|
||||
visible,
|
||||
dropdownAlign,
|
||||
prefixCls,
|
||||
popupElement,
|
||||
dropdownClassName,
|
||||
dropdownStyle,
|
||||
direction = 'ltr',
|
||||
placement,
|
||||
dropdownMatchSelectWidth,
|
||||
containerWidth,
|
||||
dropdownRender,
|
||||
animation,
|
||||
transitionName,
|
||||
getPopupContainer,
|
||||
getTriggerDOMNode,
|
||||
onPopupVisibleChange,
|
||||
onPopupMouseEnter,
|
||||
} = restProps as SelectTriggerProps;
|
||||
const dropdownPrefixCls = `${prefixCls}-dropdown`;
|
||||
|
||||
methods: {
|
||||
getPopupElement() {
|
||||
return this.popupRef.current;
|
||||
},
|
||||
},
|
||||
let popupNode = popupElement;
|
||||
if (dropdownRender) {
|
||||
popupNode = dropdownRender({ menuNode: popupElement, props });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { empty = false, ...props } = { ...this.$props, ...this.$attrs };
|
||||
const {
|
||||
visible,
|
||||
dropdownAlign,
|
||||
prefixCls,
|
||||
popupElement,
|
||||
dropdownClassName,
|
||||
dropdownStyle,
|
||||
direction = 'ltr',
|
||||
placement,
|
||||
dropdownMatchSelectWidth,
|
||||
containerWidth,
|
||||
dropdownRender,
|
||||
animation,
|
||||
transitionName,
|
||||
getPopupContainer,
|
||||
getTriggerDOMNode,
|
||||
} = props as SelectTriggerProps;
|
||||
const dropdownPrefixCls = `${prefixCls}-dropdown`;
|
||||
const mergedTransitionName = animation ? `${dropdownPrefixCls}-${animation}` : transitionName;
|
||||
|
||||
let popupNode = popupElement;
|
||||
if (dropdownRender) {
|
||||
popupNode = dropdownRender({ menuNode: popupElement, props });
|
||||
}
|
||||
const popupStyle = { minWidth: `${containerWidth}px`, ...dropdownStyle };
|
||||
|
||||
const builtInPlacements = getBuiltInPlacements(dropdownMatchSelectWidth);
|
||||
|
||||
const mergedTransitionName = animation ? `${dropdownPrefixCls}-${animation}` : transitionName;
|
||||
|
||||
const popupStyle = { minWidth: `${containerWidth}px`, ...dropdownStyle };
|
||||
|
||||
if (typeof dropdownMatchSelectWidth === 'number') {
|
||||
popupStyle.width = `${dropdownMatchSelectWidth}px`;
|
||||
} else if (dropdownMatchSelectWidth) {
|
||||
popupStyle.width = `${containerWidth}px`;
|
||||
}
|
||||
return (
|
||||
<Trigger
|
||||
{...props}
|
||||
showAction={[]}
|
||||
hideAction={[]}
|
||||
popupPlacement={placement || (direction === 'rtl' ? 'bottomRight' : 'bottomLeft')}
|
||||
builtinPlacements={builtInPlacements}
|
||||
prefixCls={dropdownPrefixCls}
|
||||
popupTransitionName={mergedTransitionName}
|
||||
popup={<div ref={this.popupRef}>{popupNode}</div>}
|
||||
popupAlign={dropdownAlign}
|
||||
popupVisible={visible}
|
||||
getPopupContainer={getPopupContainer}
|
||||
popupClassName={classNames(dropdownClassName, {
|
||||
[`${dropdownPrefixCls}-empty`]: empty,
|
||||
})}
|
||||
popupStyle={popupStyle}
|
||||
getTriggerDOMNode={getTriggerDOMNode}
|
||||
>
|
||||
{getSlot(this)[0]}
|
||||
</Trigger>
|
||||
);
|
||||
if (typeof dropdownMatchSelectWidth === 'number') {
|
||||
popupStyle.width = `${dropdownMatchSelectWidth}px`;
|
||||
} else if (dropdownMatchSelectWidth) {
|
||||
popupStyle.width = `${containerWidth}px`;
|
||||
}
|
||||
return (
|
||||
<Trigger
|
||||
{...props}
|
||||
showAction={onPopupVisibleChange ? ['click'] : []}
|
||||
hideAction={onPopupVisibleChange ? ['click'] : []}
|
||||
popupPlacement={placement || (direction === 'rtl' ? 'bottomRight' : 'bottomLeft')}
|
||||
builtinPlacements={builtInPlacements.value}
|
||||
prefixCls={dropdownPrefixCls}
|
||||
popupTransitionName={mergedTransitionName}
|
||||
popupAlign={dropdownAlign}
|
||||
popupVisible={visible}
|
||||
getPopupContainer={getPopupContainer}
|
||||
popupClassName={classNames(dropdownClassName, {
|
||||
[`${dropdownPrefixCls}-empty`]: empty,
|
||||
})}
|
||||
popupStyle={popupStyle}
|
||||
getTriggerDOMNode={getTriggerDOMNode}
|
||||
onPopupVisibleChange={onPopupVisibleChange}
|
||||
v-slots={{
|
||||
default: slots.default,
|
||||
popup: () => (
|
||||
<div ref={popupRef} onMouseenter={onPopupMouseEnter}>
|
||||
{popupNode}
|
||||
</div>
|
||||
),
|
||||
}}
|
||||
></Trigger>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
SelectTrigger.props = {
|
||||
dropdownAlign: PropTypes.object,
|
||||
visible: PropTypes.looseBool,
|
||||
disabled: PropTypes.looseBool,
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownStyle: PropTypes.object,
|
||||
placement: PropTypes.string,
|
||||
empty: PropTypes.looseBool,
|
||||
prefixCls: PropTypes.string,
|
||||
popupClassName: PropTypes.string,
|
||||
animation: PropTypes.string,
|
||||
transitionName: PropTypes.string,
|
||||
getPopupContainer: PropTypes.func,
|
||||
dropdownRender: PropTypes.func,
|
||||
containerWidth: PropTypes.number,
|
||||
dropdownMatchSelectWidth: PropTypes.oneOfType([Number, Boolean]).def(true),
|
||||
popupElement: PropTypes.any,
|
||||
direction: PropTypes.string,
|
||||
getTriggerDOMNode: PropTypes.func,
|
||||
};
|
||||
|
||||
export default SelectTrigger;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ interface InputProps {
|
|||
autofocus: boolean;
|
||||
autocomplete: string;
|
||||
editable: boolean;
|
||||
accessibilityIndex: number;
|
||||
activeDescendantId?: string;
|
||||
value: string;
|
||||
open: boolean;
|
||||
tabindex: number | string;
|
||||
|
|
@ -45,7 +45,7 @@ const Input = defineComponent({
|
|||
autofocus: PropTypes.looseBool,
|
||||
autocomplete: PropTypes.string,
|
||||
editable: PropTypes.looseBool,
|
||||
accessibilityIndex: PropTypes.number,
|
||||
activeDescendantId: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
open: PropTypes.looseBool,
|
||||
tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
|
|
@ -86,7 +86,7 @@ const Input = defineComponent({
|
|||
autofocus,
|
||||
autocomplete,
|
||||
editable,
|
||||
accessibilityIndex,
|
||||
activeDescendantId,
|
||||
value,
|
||||
onKeydown,
|
||||
onMousedown,
|
||||
|
|
@ -131,7 +131,7 @@ const Input = defineComponent({
|
|||
'aria-owns': `${id}_list`,
|
||||
'aria-autocomplete': 'list',
|
||||
'aria-controls': `${id}_list`,
|
||||
'aria-activedescendant': `${id}_list_${accessibilityIndex}`,
|
||||
'aria-activedescendant': activeDescendantId,
|
||||
...attrs,
|
||||
value: editable ? value : '',
|
||||
readonly: !editable,
|
||||
|
|
@ -178,7 +178,7 @@ const Input = defineComponent({
|
|||
onOriginBlur && onOriginBlur(args[0]);
|
||||
onBlur && onBlur(args[0]);
|
||||
this.VCSelectContainerEvent?.blur(args[0]);
|
||||
}, 200);
|
||||
}, 100);
|
||||
},
|
||||
},
|
||||
inputNode.type === 'textarea' ? {} : { type: 'search' },
|
||||
|
|
|
|||
|
|
@ -1,12 +1,4 @@
|
|||
import TransBtn from '../TransBtn';
|
||||
import type {
|
||||
LabelValueType,
|
||||
RawValueType,
|
||||
CustomTagProps,
|
||||
DefaultValueType,
|
||||
DisplayLabelValueType,
|
||||
} from '../interface/generator';
|
||||
import type { RenderNode } from '../interface';
|
||||
import type { InnerSelectorProps } from './interface';
|
||||
import Input from './Input';
|
||||
import type { Ref, PropType } from 'vue';
|
||||
|
|
@ -16,6 +8,9 @@ import pickAttrs from '../../_util/pickAttrs';
|
|||
import PropTypes from '../../_util/vue-types';
|
||||
import type { VueNode } from '../../_util/type';
|
||||
import Overflow from '../../vc-overflow';
|
||||
import type { DisplayValueType, RenderNode, CustomTagProps, RawValueType } from '../BaseSelect';
|
||||
import type { BaseOptionType } from '../Select';
|
||||
import useInjectLegacySelectContext from '../../vc-tree-select/LegacyContext';
|
||||
|
||||
type SelectorProps = InnerSelectorProps & {
|
||||
// Icon
|
||||
|
|
@ -24,7 +19,7 @@ type SelectorProps = InnerSelectorProps & {
|
|||
// Tags
|
||||
maxTagCount?: number | 'responsive';
|
||||
maxTagTextLength?: number;
|
||||
maxTagPlaceholder?: VueNode | ((omittedValues: LabelValueType[]) => VueNode);
|
||||
maxTagPlaceholder?: VueNode | ((omittedValues: DisplayValueType[]) => VueNode);
|
||||
tokenSeparators?: string[];
|
||||
tagRender?: (props: CustomTagProps) => VueNode;
|
||||
onToggleOpen: any;
|
||||
|
|
@ -33,7 +28,7 @@ type SelectorProps = InnerSelectorProps & {
|
|||
choiceTransitionName?: string;
|
||||
|
||||
// Event
|
||||
onSelect: (value: RawValueType, option: { selected: boolean }) => void;
|
||||
onRemove: (value: DisplayValueType) => void;
|
||||
};
|
||||
|
||||
const props = {
|
||||
|
|
@ -49,7 +44,7 @@ const props = {
|
|||
showSearch: PropTypes.looseBool,
|
||||
autofocus: PropTypes.looseBool,
|
||||
autocomplete: PropTypes.string,
|
||||
accessibilityIndex: PropTypes.number,
|
||||
activeDescendantId: PropTypes.string,
|
||||
tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
|
||||
removeIcon: PropTypes.any,
|
||||
|
|
@ -58,12 +53,12 @@ const props = {
|
|||
maxTagCount: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
maxTagTextLength: PropTypes.number,
|
||||
maxTagPlaceholder: PropTypes.any.def(
|
||||
() => (omittedValues: LabelValueType[]) => `+ ${omittedValues.length} ...`,
|
||||
() => (omittedValues: DisplayValueType[]) => `+ ${omittedValues.length} ...`,
|
||||
),
|
||||
tagRender: PropTypes.func,
|
||||
|
||||
onToggleOpen: { type: Function as PropType<(open?: boolean) => void> },
|
||||
onSelect: PropTypes.func,
|
||||
onRemove: PropTypes.func,
|
||||
onInputChange: PropTypes.func,
|
||||
onInputPaste: PropTypes.func,
|
||||
onInputKeyDown: PropTypes.func,
|
||||
|
|
@ -85,7 +80,7 @@ const SelectSelector = defineComponent<SelectorProps>({
|
|||
const measureRef = ref();
|
||||
const inputWidth = ref(0);
|
||||
const focused = ref(false);
|
||||
|
||||
const legacyTreeSelectContext = useInjectLegacySelectContext();
|
||||
const selectionPrefixCls = computed(() => `${props.prefixCls}-selection`);
|
||||
|
||||
// ===================== Search ======================
|
||||
|
|
@ -111,6 +106,7 @@ const SelectSelector = defineComponent<SelectorProps>({
|
|||
// ===================== Render ======================
|
||||
// >>> Render Selector Node. Includes Item & Rest
|
||||
function defaultRenderSelector(
|
||||
title: VueNode,
|
||||
content: VueNode,
|
||||
itemDisabled: boolean,
|
||||
closable?: boolean,
|
||||
|
|
@ -122,9 +118,7 @@ const SelectSelector = defineComponent<SelectorProps>({
|
|||
[`${selectionPrefixCls.value}-item-disabled`]: itemDisabled,
|
||||
})}
|
||||
title={
|
||||
typeof content === 'string' || typeof content === 'number'
|
||||
? content.toString()
|
||||
: undefined
|
||||
typeof title === 'string' || typeof title === 'number' ? title.toString() : undefined
|
||||
}
|
||||
>
|
||||
<span class={`${selectionPrefixCls.value}-item-content`}>{content}</span>
|
||||
|
|
@ -143,31 +137,38 @@ const SelectSelector = defineComponent<SelectorProps>({
|
|||
}
|
||||
|
||||
function customizeRenderSelector(
|
||||
value: DefaultValueType,
|
||||
value: RawValueType,
|
||||
content: VueNode,
|
||||
itemDisabled: boolean,
|
||||
closable: boolean,
|
||||
onClose: (e: MouseEvent) => void,
|
||||
option: BaseOptionType,
|
||||
) {
|
||||
const onMouseDown = (e: MouseEvent) => {
|
||||
onPreventMouseDown(e);
|
||||
props.onToggleOpen(!open);
|
||||
};
|
||||
|
||||
let originData = option;
|
||||
// For TreeSelect
|
||||
if (legacyTreeSelectContext.keyEntities) {
|
||||
originData = legacyTreeSelectContext.keyEntities[value]?.node || {};
|
||||
}
|
||||
return (
|
||||
<span onMousedown={onMouseDown}>
|
||||
<span key={value} onMousedown={onMouseDown}>
|
||||
{props.tagRender({
|
||||
label: content,
|
||||
value,
|
||||
disabled: itemDisabled,
|
||||
closable,
|
||||
onClose,
|
||||
option: originData,
|
||||
})}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function renderItem({ disabled: itemDisabled, label, value }: DisplayLabelValueType) {
|
||||
function renderItem(valueItem: DisplayValueType) {
|
||||
const { disabled: itemDisabled, label, value, option } = valueItem;
|
||||
const closable = !props.disabled && !itemDisabled;
|
||||
|
||||
let displayLabel = label;
|
||||
|
|
@ -183,24 +184,22 @@ const SelectSelector = defineComponent<SelectorProps>({
|
|||
}
|
||||
const onClose = (event?: MouseEvent) => {
|
||||
if (event) event.stopPropagation();
|
||||
props.onSelect(value, { selected: false });
|
||||
props.onRemove?.(valueItem);
|
||||
};
|
||||
|
||||
return typeof props.tagRender === 'function'
|
||||
? customizeRenderSelector(value, displayLabel, itemDisabled, closable, onClose)
|
||||
: defaultRenderSelector(displayLabel, itemDisabled, closable, onClose);
|
||||
? customizeRenderSelector(value, displayLabel, itemDisabled, closable, onClose, option)
|
||||
: defaultRenderSelector(label, displayLabel, itemDisabled, closable, onClose);
|
||||
}
|
||||
|
||||
function renderRest(omittedValues: DisplayLabelValueType[]) {
|
||||
const {
|
||||
maxTagPlaceholder = (omittedValues: LabelValueType[]) => `+ ${omittedValues.length} ...`,
|
||||
} = props;
|
||||
function renderRest(omittedValues: DisplayValueType[]) {
|
||||
const { maxTagPlaceholder = omittedValues => `+ ${omittedValues.length} ...` } = props;
|
||||
const content =
|
||||
typeof maxTagPlaceholder === 'function'
|
||||
? maxTagPlaceholder(omittedValues)
|
||||
: maxTagPlaceholder;
|
||||
|
||||
return defaultRenderSelector(content, false);
|
||||
return defaultRenderSelector(content, content, false);
|
||||
}
|
||||
|
||||
return () => {
|
||||
|
|
@ -214,7 +213,7 @@ const SelectSelector = defineComponent<SelectorProps>({
|
|||
disabled,
|
||||
autofocus,
|
||||
autocomplete,
|
||||
accessibilityIndex,
|
||||
activeDescendantId,
|
||||
tabindex,
|
||||
onInputChange,
|
||||
onInputPaste,
|
||||
|
|
@ -241,7 +240,7 @@ const SelectSelector = defineComponent<SelectorProps>({
|
|||
autofocus={autofocus}
|
||||
autocomplete={autocomplete}
|
||||
editable={inputEditable.value}
|
||||
accessibilityIndex={accessibilityIndex}
|
||||
activeDescendantId={activeDescendantId}
|
||||
value={inputValue.value}
|
||||
onKeydown={onInputKeyDown}
|
||||
onMousedown={onInputMouseDown}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,12 @@ import Input from './Input';
|
|||
import type { InnerSelectorProps } from './interface';
|
||||
import { Fragment, computed, defineComponent, ref, watch } from 'vue';
|
||||
import PropTypes from '../../_util/vue-types';
|
||||
import { useInjectTreeSelectContext } from '../../vc-tree-select/Context';
|
||||
import type { VueNode } from '../../_util/type';
|
||||
import useInjectLegacySelectContext from '../../vc-tree-select/LegacyContext';
|
||||
|
||||
interface SelectorProps extends InnerSelectorProps {
|
||||
inputElement: VueNode;
|
||||
activeValue: string;
|
||||
backfill?: boolean;
|
||||
}
|
||||
const props = {
|
||||
inputElement: PropTypes.any,
|
||||
|
|
@ -25,7 +24,7 @@ const props = {
|
|||
showSearch: PropTypes.looseBool,
|
||||
autofocus: PropTypes.looseBool,
|
||||
autocomplete: PropTypes.string,
|
||||
accessibilityIndex: PropTypes.number,
|
||||
activeDescendantId: PropTypes.string,
|
||||
tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
activeValue: PropTypes.string,
|
||||
backfill: PropTypes.looseBool,
|
||||
|
|
@ -51,7 +50,7 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
}
|
||||
return inputValue;
|
||||
});
|
||||
const treeSelectContext = useInjectTreeSelectContext();
|
||||
const legacyTreeSelectContext = useInjectLegacySelectContext();
|
||||
watch(
|
||||
[combobox, () => props.activeValue],
|
||||
() => {
|
||||
|
|
@ -64,7 +63,7 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
|
||||
// Not show text when closed expect combobox mode
|
||||
const hasTextInput = computed(() =>
|
||||
props.mode !== 'combobox' && !props.open ? false : !!inputValue.value,
|
||||
props.mode !== 'combobox' && !props.open && !props.showSearch ? false : !!inputValue.value,
|
||||
);
|
||||
|
||||
const title = computed(() => {
|
||||
|
|
@ -74,6 +73,18 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
: undefined;
|
||||
});
|
||||
|
||||
const renderPlaceholder = () => {
|
||||
if (props.values[0]) {
|
||||
return null;
|
||||
}
|
||||
const hiddenStyle = hasTextInput.value ? { visibility: 'hidden' as const } : undefined;
|
||||
return (
|
||||
<span class={`${props.prefixCls}-selection-placeholder`} style={hiddenStyle}>
|
||||
{props.placeholder}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
return () => {
|
||||
const {
|
||||
inputElement,
|
||||
|
|
@ -84,9 +95,8 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
disabled,
|
||||
autofocus,
|
||||
autocomplete,
|
||||
accessibilityIndex,
|
||||
activeDescendantId,
|
||||
open,
|
||||
placeholder,
|
||||
tabindex,
|
||||
onInputKeyDown,
|
||||
onInputMouseDown,
|
||||
|
|
@ -98,13 +108,17 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
const item = values[0];
|
||||
let titleNode = null;
|
||||
// custom tree-select title by slot
|
||||
if (item && treeSelectContext.value.slots) {
|
||||
|
||||
// For TreeSelect
|
||||
if (item && legacyTreeSelectContext.customSlots) {
|
||||
const key = item.key ?? item.value;
|
||||
const originData = legacyTreeSelectContext.keyEntities[key]?.node || {};
|
||||
titleNode =
|
||||
treeSelectContext.value.slots[item?.option?.data?.slots?.title] ||
|
||||
treeSelectContext.value.slots.title ||
|
||||
legacyTreeSelectContext.customSlots[originData.slots?.title] ||
|
||||
legacyTreeSelectContext.customSlots.title ||
|
||||
item.label;
|
||||
if (typeof titleNode === 'function') {
|
||||
titleNode = titleNode(item.option?.data || {});
|
||||
titleNode = titleNode(originData);
|
||||
}
|
||||
// else if (treeSelectContext.value.slots.titleRender) {
|
||||
// // 因历史 title 是覆盖逻辑,新增 titleRender,所有的 title 都走一遍 titleRender
|
||||
|
|
@ -126,7 +140,7 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
autofocus={autofocus}
|
||||
autocomplete={autocomplete}
|
||||
editable={inputEditable.value}
|
||||
accessibilityIndex={accessibilityIndex}
|
||||
activeDescendantId={activeDescendantId}
|
||||
value={inputValue.value}
|
||||
onKeydown={onInputKeyDown}
|
||||
onMousedown={onInputMouseDown}
|
||||
|
|
@ -145,14 +159,12 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
{/* Display value */}
|
||||
{!combobox.value && item && !hasTextInput.value && (
|
||||
<span class={`${prefixCls}-selection-item`} title={title.value}>
|
||||
<Fragment key={item.key || item.value}>{titleNode}</Fragment>
|
||||
<Fragment key={item.key ?? item.value}>{titleNode}</Fragment>
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* Display placeholder */}
|
||||
{!item && !hasTextInput.value && (
|
||||
<span class={`${prefixCls}-selection-placeholder`}>{placeholder}</span>
|
||||
)}
|
||||
{renderPlaceholder()}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
import KeyCode from '../../_util/KeyCode';
|
||||
import MultipleSelector from './MultipleSelector';
|
||||
import SingleSelector from './SingleSelector';
|
||||
import type { LabelValueType, RawValueType, CustomTagProps } from '../interface/generator';
|
||||
import type { RenderNode, Mode } from '../interface';
|
||||
import type { CustomTagProps, DisplayValueType, Mode, RenderNode } from '../BaseSelect';
|
||||
import { isValidateOpenKey } from '../utils/keyUtil';
|
||||
import useLock from '../hooks/useLock';
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
|
@ -20,22 +20,22 @@ import createRef from '../../_util/createRef';
|
|||
import PropTypes from '../../_util/vue-types';
|
||||
import type { VueNode } from '../../_util/type';
|
||||
import type { EventHandler } from '../../_util/EventInterface';
|
||||
import type { ScrollTo } from '../../vc-virtual-list/List';
|
||||
|
||||
export interface SelectorProps {
|
||||
id: string;
|
||||
prefixCls: string;
|
||||
showSearch?: boolean;
|
||||
open: boolean;
|
||||
/** Display in the Selector value, it's not same as `value` prop */
|
||||
values: LabelValueType[];
|
||||
multiple: boolean;
|
||||
values: DisplayValueType[];
|
||||
multiple?: boolean;
|
||||
mode: Mode;
|
||||
searchValue: string;
|
||||
activeValue: string;
|
||||
inputElement: VueNode;
|
||||
|
||||
autofocus?: boolean;
|
||||
accessibilityIndex: number;
|
||||
activeDescendantId?: string;
|
||||
tabindex?: number | string;
|
||||
disabled?: boolean;
|
||||
placeholder?: VueNode;
|
||||
|
|
@ -44,7 +44,7 @@ export interface SelectorProps {
|
|||
// Tags
|
||||
maxTagCount?: number | 'responsive';
|
||||
maxTagTextLength?: number;
|
||||
maxTagPlaceholder?: VueNode | ((omittedValues: LabelValueType[]) => VueNode);
|
||||
maxTagPlaceholder?: VueNode | ((omittedValues: DisplayValueType[]) => VueNode);
|
||||
tagRender?: (props: CustomTagProps) => VueNode;
|
||||
|
||||
/** Check if `tokenSeparators` contains `\n` or `\r\n` */
|
||||
|
|
@ -57,7 +57,7 @@ export interface SelectorProps {
|
|||
/** `onSearch` returns go next step boolean to check if need do toggle open */
|
||||
onSearch: (searchText: string, fromTyping: boolean, isCompositing: boolean) => boolean;
|
||||
onSearchSubmit: (searchText: string) => void;
|
||||
onSelect: (value: RawValueType, option: { selected: boolean }) => void;
|
||||
onRemove: (value: DisplayValueType) => void;
|
||||
onInputKeyDown?: (e: KeyboardEvent) => void;
|
||||
|
||||
/**
|
||||
|
|
@ -66,6 +66,11 @@ export interface SelectorProps {
|
|||
*/
|
||||
domRef: () => HTMLDivElement;
|
||||
}
|
||||
export interface RefSelectorProps {
|
||||
focus: () => void;
|
||||
blur: () => void;
|
||||
scrollTo?: ScrollTo;
|
||||
}
|
||||
|
||||
const Selector = defineComponent<SelectorProps>({
|
||||
name: 'Selector',
|
||||
|
|
@ -84,7 +89,7 @@ const Selector = defineComponent<SelectorProps>({
|
|||
inputElement: PropTypes.any,
|
||||
|
||||
autofocus: PropTypes.looseBool,
|
||||
accessibilityIndex: PropTypes.number,
|
||||
activeDescendantId: PropTypes.string,
|
||||
tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
disabled: PropTypes.looseBool,
|
||||
placeholder: PropTypes.any,
|
||||
|
|
@ -106,7 +111,7 @@ const Selector = defineComponent<SelectorProps>({
|
|||
/** `onSearch` returns go next step boolean to check if need do toggle open */
|
||||
onSearch: PropTypes.func,
|
||||
onSearchSubmit: PropTypes.func,
|
||||
onSelect: PropTypes.func,
|
||||
onRemove: PropTypes.func,
|
||||
onInputKeyDown: { type: Function as PropType<EventHandler> },
|
||||
|
||||
/**
|
||||
|
|
@ -115,7 +120,7 @@ const Selector = defineComponent<SelectorProps>({
|
|||
*/
|
||||
domRef: PropTypes.func,
|
||||
} as any,
|
||||
setup(props) {
|
||||
setup(props, { expose }) {
|
||||
const inputRef = createRef();
|
||||
let compositionStatus = false;
|
||||
|
||||
|
|
@ -139,7 +144,7 @@ const Selector = defineComponent<SelectorProps>({
|
|||
props.onSearchSubmit((event.target as HTMLInputElement).value);
|
||||
}
|
||||
|
||||
if (![KeyCode.SHIFT, KeyCode.TAB, KeyCode.BACKSPACE, KeyCode.ESC].includes(which)) {
|
||||
if (isValidateOpenKey(which)) {
|
||||
props.onToggleOpen(true);
|
||||
}
|
||||
};
|
||||
|
|
@ -227,58 +232,44 @@ const Selector = defineComponent<SelectorProps>({
|
|||
props.onToggleOpen();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
expose({
|
||||
focus: () => {
|
||||
inputRef.current.focus();
|
||||
},
|
||||
blur: () => {
|
||||
inputRef.current.blur();
|
||||
},
|
||||
onMousedown,
|
||||
onClick,
|
||||
onInputPaste,
|
||||
inputRef,
|
||||
onInternalInputKeyDown,
|
||||
onInternalInputMouseDown,
|
||||
onInputChange,
|
||||
onInputCompositionEnd,
|
||||
onInputCompositionStart,
|
||||
});
|
||||
|
||||
return () => {
|
||||
const { prefixCls, domRef, mode } = props as SelectorProps;
|
||||
const sharedProps = {
|
||||
inputRef,
|
||||
onInputKeyDown: onInternalInputKeyDown,
|
||||
onInputMouseDown: onInternalInputMouseDown,
|
||||
onInputChange,
|
||||
onInputPaste,
|
||||
onInputCompositionStart,
|
||||
onInputCompositionEnd,
|
||||
};
|
||||
const selectNode =
|
||||
mode === 'multiple' || mode === 'tags' ? (
|
||||
<MultipleSelector {...props} {...sharedProps} />
|
||||
) : (
|
||||
<SingleSelector {...props} {...sharedProps} />
|
||||
);
|
||||
return (
|
||||
<div
|
||||
ref={domRef}
|
||||
class={`${prefixCls}-selector`}
|
||||
onClick={onClick}
|
||||
onMousedown={onMousedown}
|
||||
>
|
||||
{selectNode}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
render() {
|
||||
const { prefixCls, domRef, multiple } = this.$props as SelectorProps;
|
||||
const {
|
||||
onMousedown,
|
||||
onClick,
|
||||
inputRef,
|
||||
onInputPaste,
|
||||
onInternalInputKeyDown,
|
||||
onInternalInputMouseDown,
|
||||
onInputChange,
|
||||
onInputCompositionStart,
|
||||
onInputCompositionEnd,
|
||||
} = this as any;
|
||||
const sharedProps = {
|
||||
inputRef,
|
||||
onInputKeyDown: onInternalInputKeyDown,
|
||||
onInputMouseDown: onInternalInputMouseDown,
|
||||
onInputChange,
|
||||
onInputPaste,
|
||||
onInputCompositionStart,
|
||||
onInputCompositionEnd,
|
||||
};
|
||||
const selectNode = multiple ? (
|
||||
<MultipleSelector {...this.$props} {...sharedProps} />
|
||||
) : (
|
||||
<SingleSelector {...this.$props} {...sharedProps} />
|
||||
);
|
||||
return (
|
||||
<div ref={domRef} class={`${prefixCls}-selector`} onClick={onClick} onMousedown={onMousedown}>
|
||||
{selectNode}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default Selector;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { RefObject } from '../../_util/createRef';
|
||||
import type { Mode } from '../interface';
|
||||
import type { LabelValueType } from '../interface/generator';
|
||||
|
||||
import type { EventHandler } from '../../_util/EventInterface';
|
||||
import type { VueNode } from '../../_util/type';
|
||||
import type { Mode, DisplayValueType } from '../BaseSelect';
|
||||
|
||||
export interface InnerSelectorProps {
|
||||
prefixCls: string;
|
||||
|
|
@ -13,10 +13,10 @@ export interface InnerSelectorProps {
|
|||
disabled?: boolean;
|
||||
autofocus?: boolean;
|
||||
autocomplete?: string;
|
||||
values: LabelValueType[];
|
||||
values: DisplayValueType[];
|
||||
showSearch?: boolean;
|
||||
searchValue: string;
|
||||
accessibilityIndex: number;
|
||||
activeDescendantId: string;
|
||||
open: boolean;
|
||||
tabindex?: number | string;
|
||||
onInputKeyDown: EventHandler;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import type { FunctionalComponent } from 'vue';
|
||||
import type { VueNode } from '../_util/type';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import type { RenderNode } from './BaseSelect';
|
||||
|
||||
export interface TransBtnProps {
|
||||
class: string;
|
||||
customizeIcon: VueNode | ((props?: any) => VueNode);
|
||||
customizeIcon: RenderNode;
|
||||
customizeIconProps?: any;
|
||||
onMousedown?: (payload: MouseEvent) => void;
|
||||
onClick?: (payload: MouseEvent) => void;
|
||||
|
|
|
|||
|
|
@ -1,345 +0,0 @@
|
|||
@select-prefix: ~'rc-select';
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.search-input-without-border() {
|
||||
.@{select-prefix}-selection-search-input {
|
||||
border: none;
|
||||
outline: none;
|
||||
background: rgba(255, 0, 0, 0.2);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix} {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
width: 100px;
|
||||
position: relative;
|
||||
|
||||
&-disabled {
|
||||
&,
|
||||
& input {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.@{select-prefix}-selector {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
&-show-arrow&-loading {
|
||||
.@{select-prefix}-arrow {
|
||||
&-icon::after {
|
||||
box-sizing: border-box;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 100%;
|
||||
border: 2px solid #999;
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
transform: none;
|
||||
margin-top: 4px;
|
||||
|
||||
animation: rcSelectLoadingIcon 0.5s infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============== Selector ===============
|
||||
.@{select-prefix}-selection-placeholder {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
// ============== Search ===============
|
||||
.@{select-prefix}-selection-search-input {
|
||||
appearance: none;
|
||||
|
||||
&::-webkit-search-cancel-button {
|
||||
display: none;
|
||||
appearance: none;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------- Single ----------------
|
||||
&-single {
|
||||
.@{select-prefix}-selector {
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
.@{select-prefix}-selection-search {
|
||||
width: 100%;
|
||||
|
||||
&-input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix}-selection-item,
|
||||
.@{select-prefix}-selection-placeholder {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 3px;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Not customize
|
||||
&:not(.@{select-prefix}-customize-input) {
|
||||
.@{select-prefix}-selector {
|
||||
padding: 1px;
|
||||
border: 1px solid #000;
|
||||
|
||||
.search-input-without-border();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------- Multiple ---------------
|
||||
&-multiple .@{select-prefix}-selector {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 1px;
|
||||
border: 1px solid #000;
|
||||
|
||||
.@{select-prefix}-selection-item {
|
||||
flex: none;
|
||||
background: #bbb;
|
||||
border-radius: 4px;
|
||||
margin-right: 2px;
|
||||
padding: 0 8px;
|
||||
|
||||
&-disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix}-selection-search {
|
||||
position: relative;
|
||||
|
||||
&-input,
|
||||
&-mirror {
|
||||
padding: 1px;
|
||||
font-family: system-ui;
|
||||
}
|
||||
|
||||
&-mirror {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
white-space: nowrap;
|
||||
position: none;
|
||||
left: 0;
|
||||
top: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.search-input-without-border();
|
||||
}
|
||||
|
||||
// ================ Icons ================
|
||||
&-allow-clear {
|
||||
&.@{select-prefix}-multiple .@{select-prefix}-selector {
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.@{select-prefix}-clear {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-show-arrow {
|
||||
&.@{select-prefix}-multiple .@{select-prefix}-selector {
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.@{select-prefix}-arrow {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 0;
|
||||
|
||||
&-icon::after {
|
||||
content: '';
|
||||
border: 5px solid transparent;
|
||||
width: 0;
|
||||
height: 0;
|
||||
display: inline-block;
|
||||
border-top-color: #999;
|
||||
transform: translateY(5px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =============== Focused ===============
|
||||
&-focused {
|
||||
.@{select-prefix}-selector {
|
||||
border-color: blue !important;
|
||||
}
|
||||
}
|
||||
|
||||
// ============== Dropdown ===============
|
||||
&-dropdown {
|
||||
border: 1px solid green;
|
||||
min-height: 100px;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// =============== Option ================
|
||||
&-item {
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
padding: 4px 16px;
|
||||
|
||||
// >>> Group
|
||||
&-group {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
// >>> Option
|
||||
&-option {
|
||||
position: relative;
|
||||
|
||||
&-grouped {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.@{select-prefix}-item-option-state {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 4px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// ------- Active -------
|
||||
&-active {
|
||||
background: green;
|
||||
}
|
||||
|
||||
// ------ Disabled ------
|
||||
&-disabled {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
// >>> Empty
|
||||
&-empty {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.@{select-prefix}-selection__choice-zoom {
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.@{select-prefix}-selection__choice-zoom-appear {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
|
||||
&&-active {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
.@{select-prefix}-selection__choice-zoom-leave {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
|
||||
&&-active {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.effect() {
|
||||
animation-duration: 0.3s;
|
||||
animation-fill-mode: both;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
.@{select-prefix}-dropdown {
|
||||
&-slide-up-enter,
|
||||
&-slide-up-appear {
|
||||
.effect();
|
||||
opacity: 0;
|
||||
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
&-slide-up-leave {
|
||||
.effect();
|
||||
opacity: 1;
|
||||
animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
&-slide-up-enter&-slide-up-enter-active&-placement-bottomLeft,
|
||||
&-slide-up-appear&-slide-up-appear-active&-placement-bottomLeft {
|
||||
animation-name: rcSelectDropdownSlideUpIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&-slide-up-leave&-slide-up-leave-active&-placement-bottomLeft {
|
||||
animation-name: rcSelectDropdownSlideUpOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&-slide-up-enter&-slide-up-enter-active&-placement-topLeft,
|
||||
&-slide-up-appear&-slide-up-appear-active&-placement-topLeft {
|
||||
animation-name: rcSelectDropdownSlideDownIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&-slide-up-leave&-slide-up-leave-active&-placement-topLeft {
|
||||
animation-name: rcSelectDropdownSlideDownOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rcSelectDropdownSlideUpIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@keyframes rcSelectDropdownSlideUpOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rcSelectLoadingIcon {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
import createRef from '../../_util/createRef';
|
||||
/* eslint-disable no-console */
|
||||
import Select, { Option } from '..';
|
||||
import '../assets/index.less';
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
const Combobox = {
|
||||
data() {
|
||||
this.textareaRef = createRef();
|
||||
|
||||
this.timeoutId;
|
||||
return {
|
||||
disabled: false,
|
||||
value: '',
|
||||
options: [],
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
nextTick(() => {
|
||||
console.log('Ref:', this.textareaRef.current);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
onChange(value, option) {
|
||||
console.log('onChange', value, option);
|
||||
|
||||
this.value = value;
|
||||
},
|
||||
|
||||
onKeyDown(e) {
|
||||
const { value } = this;
|
||||
if (e.keyCode === 13) {
|
||||
console.log('onEnter', value);
|
||||
}
|
||||
},
|
||||
|
||||
onSelect(v, option) {
|
||||
console.log('onSelect', v, option);
|
||||
},
|
||||
|
||||
onSearch(text) {
|
||||
console.log('onSearch:', text);
|
||||
},
|
||||
|
||||
onAsyncChange(value) {
|
||||
window.clearTimeout(this.timeoutId);
|
||||
console.log(value);
|
||||
this.options = [];
|
||||
//const value = String(Math.random());
|
||||
this.timeoutId = window.setTimeout(() => {
|
||||
this.options = [{ value }, { value: `${value}-${value}` }];
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
toggleDisabled() {
|
||||
const { disabled } = this;
|
||||
|
||||
this.disabled = !disabled;
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { value, disabled } = this;
|
||||
return (
|
||||
<div>
|
||||
<h2>combobox</h2>
|
||||
<p>
|
||||
<button type="button" onClick={this.toggleDisabled}>
|
||||
toggle disabled
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
this.value = '';
|
||||
}}
|
||||
>
|
||||
reset
|
||||
</button>
|
||||
</p>
|
||||
<div>
|
||||
<Select
|
||||
disabled={disabled}
|
||||
style={{ width: '500px' }}
|
||||
onChange={this.onChange}
|
||||
onSelect={this.onSelect}
|
||||
onSearch={this.onSearch}
|
||||
onInputKeyDown={this.onKeyDown}
|
||||
notFoundContent=""
|
||||
allowClear
|
||||
placeholder="please select"
|
||||
value={value}
|
||||
mode="combobox"
|
||||
backfill
|
||||
onFocus={() => console.log('focus')}
|
||||
onBlur={() => console.log('blur')}
|
||||
>
|
||||
<Option value="jack">
|
||||
<b style={{ color: 'red' }}>jack</b>
|
||||
</Option>
|
||||
<Option value="lucy">lucy</Option>
|
||||
<Option value="disabled" disabled>
|
||||
disabled
|
||||
</Option>
|
||||
<Option value="yiminghe">yiminghe</Option>
|
||||
<Option value="竹林星光">竹林星光</Option>
|
||||
</Select>
|
||||
|
||||
<h3>Customize Input Element</h3>
|
||||
<Select
|
||||
mode="combobox"
|
||||
style={{ width: '200px' }}
|
||||
getInputElement={() => (
|
||||
<textarea style={{ background: 'red' }} rows={3} ref={this.textareaRef} />
|
||||
)}
|
||||
options={[{ value: 'light' }, { value: 'bamboo' }]}
|
||||
allowClear
|
||||
placeholder="2333"
|
||||
/>
|
||||
|
||||
<h3>Async Input Element</h3>
|
||||
<Select
|
||||
mode="combobox"
|
||||
notFoundContent={null}
|
||||
style={{ width: '200px' }}
|
||||
options={this.options}
|
||||
onChange={this.onAsyncChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default Combobox;
|
||||
/* eslint-enable */
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// input {
|
||||
// // height: 24px;
|
||||
// // line-height: 24px;
|
||||
// border: 1px solid #333;
|
||||
// border-radius: 4px;
|
||||
// }
|
||||
|
||||
// button {
|
||||
// border: 1px solid #333;
|
||||
// }
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
import jsonp from 'jsonp';
|
||||
import querystring from 'querystring';
|
||||
|
||||
let timeout;
|
||||
let currentValue;
|
||||
|
||||
export function fetch(value, callback) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
currentValue = value;
|
||||
|
||||
function fake() {
|
||||
const str = querystring.encode({
|
||||
code: 'utf-8',
|
||||
q: value,
|
||||
});
|
||||
jsonp(`http://suggest.taobao.com/sug?${str}`, (err, d) => {
|
||||
if (currentValue === value) {
|
||||
const { result } = d;
|
||||
const data = [];
|
||||
result.forEach(r => {
|
||||
data.push({
|
||||
value: r[0],
|
||||
text: r[0],
|
||||
});
|
||||
});
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
timeout = setTimeout(fake, 300);
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/* eslint-disable no-console */
|
||||
|
||||
import Select, { Option } from '..';
|
||||
import '../assets/index.less';
|
||||
|
||||
const Controlled = {
|
||||
data: () => ({
|
||||
destroy: false,
|
||||
value: 9,
|
||||
open: true,
|
||||
}),
|
||||
methods: {
|
||||
onChange(e) {
|
||||
let value;
|
||||
if (e && e.target) {
|
||||
({ value } = e.target);
|
||||
} else {
|
||||
value = e;
|
||||
}
|
||||
console.log('onChange', value);
|
||||
this.value = value;
|
||||
},
|
||||
|
||||
onDestroy() {
|
||||
this.destroy = true;
|
||||
},
|
||||
|
||||
onBlur(v) {
|
||||
console.log('onBlur', v);
|
||||
},
|
||||
|
||||
onFocus() {
|
||||
console.log('onFocus');
|
||||
},
|
||||
|
||||
onDropdownVisibleChange(open) {
|
||||
this.open = open;
|
||||
},
|
||||
getPopupContainer(node) {
|
||||
return node.parentNode;
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { open, destroy, value } = this;
|
||||
if (destroy) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div style={{ margin: '20px' }}>
|
||||
<h2>controlled Select</h2>
|
||||
<div style={{ width: '300px' }}>
|
||||
<Select
|
||||
id="my-select"
|
||||
value={value}
|
||||
placeholder="placeholder"
|
||||
listHeight={200}
|
||||
style={{ width: '500px' }}
|
||||
onBlur={this.onBlur}
|
||||
onFocus={this.onFocus}
|
||||
open={open}
|
||||
optionLabelProp="children"
|
||||
optionFilterProp="text"
|
||||
onChange={this.onChange}
|
||||
onDropdownVisibleChange={this.onDropdownVisibleChange}
|
||||
//getPopupContainer={this.getPopupContainer}
|
||||
>
|
||||
<Option value="01" text="jack" title="jack">
|
||||
<b
|
||||
style={{
|
||||
color: 'red',
|
||||
}}
|
||||
>
|
||||
jack
|
||||
</b>
|
||||
</Option>
|
||||
<Option value="11" text="lucy">
|
||||
lucy
|
||||
</Option>
|
||||
<Option value="21" disabled text="disabled">
|
||||
disabled
|
||||
</Option>
|
||||
<Option value="31" text="yiminghe">
|
||||
yiminghe
|
||||
</Option>
|
||||
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(i => (
|
||||
<Option key={i} value={i} text={String(i)}>
|
||||
{i}-text
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default Controlled;
|
||||
/* eslint-enable */
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
/* eslint-disable no-console */
|
||||
|
||||
import Select, { Option } from '..';
|
||||
import '../assets/index.less';
|
||||
|
||||
const children = [];
|
||||
for (let i = 10; i < 36; i += 1) {
|
||||
children.push(
|
||||
<Option
|
||||
key={i.toString(36) + i}
|
||||
disabled={i === 10}
|
||||
title={`中文${i}`}
|
||||
v-slots={{ default: () => `中文${i}` }}
|
||||
></Option>,
|
||||
);
|
||||
}
|
||||
|
||||
const Test = {
|
||||
data: () => ({
|
||||
state: {
|
||||
useAnim: true,
|
||||
showArrow: false,
|
||||
loading: false,
|
||||
value: ['a10'],
|
||||
},
|
||||
}),
|
||||
methods: {
|
||||
setState(state) {
|
||||
Object.assign(this.state, state);
|
||||
},
|
||||
onChange(value, options) {
|
||||
console.log('onChange', value, options);
|
||||
this.setState({
|
||||
value,
|
||||
});
|
||||
},
|
||||
|
||||
onSelect(...args) {
|
||||
console.log(args);
|
||||
},
|
||||
|
||||
onDeselect(...args) {
|
||||
console.log(args);
|
||||
},
|
||||
|
||||
useAnim(e) {
|
||||
this.setState({
|
||||
useAnim: e.target.checked,
|
||||
});
|
||||
},
|
||||
|
||||
showArrow(e) {
|
||||
this.setState({
|
||||
showArrow: e.target.checked,
|
||||
});
|
||||
},
|
||||
|
||||
loading(e) {
|
||||
this.setState({
|
||||
loading: e.target.checked,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { useAnim, showArrow, loading, value } = this.state;
|
||||
return (
|
||||
<div style="margin: 20px">
|
||||
<h2>multiple select(scroll the menu)</h2>
|
||||
|
||||
<p>
|
||||
<label html-for="useAnim">
|
||||
anim
|
||||
<input id="useAnim" checked={useAnim} type="checkbox" onChange={this.useAnim} />
|
||||
</label>
|
||||
<p />
|
||||
<label html-for="showArrow">
|
||||
showArrow
|
||||
<input id="showArrow" checked={showArrow} type="checkbox" onChange={this.showArrow} />
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label html-for="loading">
|
||||
loading
|
||||
<input id="loading" checked={loading} type="checkbox" onChange={this.loading} />
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<div style={{ width: '300px' }}>
|
||||
<Select
|
||||
value={value}
|
||||
animation={useAnim ? 'slide-up' : null}
|
||||
choiceTransitionName="rc-select-selection__choice-zoom"
|
||||
style={{ width: '500px' }}
|
||||
mode="multiple"
|
||||
loading={loading}
|
||||
showArrow={showArrow}
|
||||
allowClear
|
||||
optionFilterProp="children"
|
||||
optionLabelProp="children"
|
||||
onSelect={this.onSelect}
|
||||
onDeselect={this.onDeselect}
|
||||
placeholder="please select"
|
||||
onChange={this.onChange}
|
||||
onFocus={() => console.log('focus')}
|
||||
onBlur={v => console.log('blur', v)}
|
||||
tokenSeparators={[' ', ',']}
|
||||
>
|
||||
{children}
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export default Test;
|
||||
/* eslint-enable */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue