hooks icon indicating copy to clipboard operation
hooks copied to clipboard

RFC: useOrder

Open MrHeer opened this issue 3 years ago • 4 comments

用来对数组进行排序,并且维护多个字段的排序状态。同时还提供一个切换排序状态函数。

API

export const ORDER_KIND = ['asc', 'desc', undefined] as const;

export type OrderKind = typeof ORDER_KIND[number];

export type Orders<T> = Partial<Record<keyof T, OrderKind>>;

export interface OrderResult<T> {
  orders: Orders<T>;
  nextOrder: (key: keyof T) => void;
  orderedData: Array<T>;
}

interface Props<T> {
  /**
   * @description specify the order state
   */
  orders?: Orders<T>;

  /**
   * @description default order state
   *
   */
  defaultOrders?: Orders<T>;

  /**
   * @description a callback on orders change
   */
  onOrdersChange?: (orders: Orders<T>) => void;

  /**
   * @description specify a orderKind to decide the order while call next order
   *
   * @default 'asc', 'desc', undefined
   */
  orderKind?: Array<OrderKind>;

  /**
   * @description the data for order;
   */
  data?: Array<T>;

  /**
   * @description a callback to order data
   *
   * @default _.orderBy
   */
  orderBy?: (data: Array<T>, orders: Orders<T>) => Array<T>;
}

function useOrder<T>(props: Props<T>): OrderResult<T>;

Demo

import React from 'react';

import { Button, DownOutlined, Space, UpOutlined } from '@supermarket/components';
import { useOrder } from '@supermarket/hooks';

function getIconByOrder(order?: 'asc' | 'desc') {
  switch (order) {
    case 'asc':
      return <UpOutlined />;
    case 'desc':
      return <DownOutlined />;
    default:
      return null;
  }
}

const DEFAULT_ORDERS: Record<string, 'asc' | 'desc' | undefined> = { name: 'asc', age: 'desc' };

export default () => {
  const { orders, nextOrder } = useOrder({
    defaultOrders: DEFAULT_ORDERS,
  });
  return (
    <Space>
      <Button
        style={{ width: 80 }}
        type="text"
        iconRight
        icon={getIconByOrder(orders?.name)}
        onClick={() => nextOrder('name')}
      >
        姓名
      </Button>
      <Button
        style={{ width: 80 }}
        type="text"
        iconRight
        icon={getIconByOrder(orders?.age)}
        onClick={() => nextOrder('age')}
      >
        年龄
      </Button>
    </Space>
  );
};

Screenshot

2022-06-21 09 45 13 2022-06-21 09 45 39

MrHeer avatar Jun 17 '21 10:06 MrHeer

能描述下具体解决了什么问题么。

类似:https://github.com/alibaba/hooks/issues/758

brickspert avatar Jun 17 '21 11:06 brickspert

@brickspert 我追加了描述。主要是为了维护多个字段的排序状态。返回一个函数可以方便切换某个字段的排序状态。顺便可以对传入的数据进行排序

MrHeer avatar Jun 17 '21 14:06 MrHeer

@MrHeer 能 参考 #758 完整的提一下 你的 RFC 吗,你现在这个太不完善了,不好评估

crazylxr avatar Jun 20 '22 04:06 crazylxr

@crazylxr 我加了一个例子,还有两个截图

MrHeer avatar Jun 21 '22 01:06 MrHeer

目前来说不是特别常用,先 close 了,后面看看其他人的反馈

crazylxr avatar Apr 21 '24 08:04 crazylxr