index.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { use } from '../utils';
  2. import { inherit, emit } from '../utils/functional';
  3. import { preventDefault } from '../utils/event';
  4. import Field from '../field';
  5. // Types
  6. import { CreateElement, RenderContext } from 'vue/types';
  7. import { DefaultSlots, ScopedSlot } from '../utils/use/sfc';
  8. const [sfc, bem, t] = use('search');
  9. export type SearchProps = {
  10. shape: string;
  11. value?: string;
  12. label?: string;
  13. background: string;
  14. showAction?: boolean;
  15. };
  16. export type SearchSlots = DefaultSlots & {
  17. label?: ScopedSlot;
  18. action?: ScopedSlot;
  19. 'left-icon'?: ScopedSlot;
  20. };
  21. export type SearchEvents = {
  22. onCancel?(): void;
  23. onInput?(value: string): void;
  24. onSearch?(value: string): void;
  25. onKeypress?(event: KeyboardEvent): void;
  26. };
  27. function Search(
  28. h: CreateElement,
  29. props: SearchProps,
  30. slots: SearchSlots,
  31. ctx: RenderContext<SearchProps>
  32. ) {
  33. const Label = () => {
  34. if (!slots.label && !props.label) {
  35. return null;
  36. }
  37. return <div class={bem('label')}>{slots.label ? slots.label() : props.label}</div>;
  38. };
  39. const Action = () => {
  40. if (!props.showAction) {
  41. return null;
  42. }
  43. const onCancel = () => {
  44. emit(ctx, 'input', '');
  45. emit(ctx, 'cancel');
  46. };
  47. return (
  48. <div class={bem('action')}>
  49. {slots.action ? slots.action() : <div onClick={onCancel}>{t('cancel')}</div>}
  50. </div>
  51. );
  52. };
  53. const fieldData = {
  54. attrs: ctx.data.attrs,
  55. on: {
  56. ...ctx.listeners,
  57. input(value: string) {
  58. emit(ctx, 'input', value);
  59. },
  60. keypress(event: KeyboardEvent) {
  61. // press enter
  62. if (event.keyCode === 13) {
  63. preventDefault(event);
  64. emit(ctx, 'search', props.value);
  65. }
  66. emit(ctx, 'keypress', event);
  67. }
  68. }
  69. };
  70. const inheritData = inherit(ctx);
  71. delete inheritData.attrs;
  72. return (
  73. <div
  74. class={bem({ 'show-action': props.showAction })}
  75. style={{ background: props.background }}
  76. {...inheritData}
  77. >
  78. <div class={bem('content', props.shape)}>
  79. {Label()}
  80. <Field
  81. clearable
  82. type="search"
  83. value={props.value}
  84. border={false}
  85. leftIcon="search"
  86. scopedSlots={{ 'left-icon': slots['left-icon'] }}
  87. {...fieldData}
  88. />
  89. </div>
  90. {Action()}
  91. </div>
  92. );
  93. }
  94. Search.props = {
  95. value: String,
  96. label: String,
  97. showAction: Boolean,
  98. shape: {
  99. type: String,
  100. default: 'square'
  101. },
  102. background: {
  103. type: String,
  104. default: '#fff'
  105. }
  106. };
  107. export default sfc<SearchProps, SearchEvents, SearchSlots>(Search);