Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add count for customize count logic #47

Merged
merged 8 commits into from
Sep 27, 2023
Merged

feat: add count for customize count logic #47

merged 8 commits into from
Sep 27, 2023

Conversation

zombieJ
Copy link
Member

@zombieJ zombieJ commented Sep 27, 2023

ref ant-design/ant-design#37733

贴一下之前同步会讨论的结论:

  • 对于 Input 和 TextArea 将 showCount 的计算逻辑还原给原生的计算逻辑。让 countmaxLength 保持同步。
  • 对于有需要定制化计算逻辑的场景(普遍是中文 or emoji 场景),提供定制接口允许开发者自行定义。

该 PR:

  • 继上述结论,提取 count 接口:
interface CountConfig {
  // 代理 `max` 逻辑,当开发者没有提供裁剪逻辑时参考 InputNumber 提供错误样式。
  max?: number;
  // 计数策略,不提供时以原生 `string.length` 处理。反之可定制自己的逻辑,如 emoji 始终占据一个长度。
  strategy?: (value: string) => number;
  // 同 `showCount`,不再复述
  show?: boolean | ShowCountFormatter;
  // 当超出 `max` 范围时处理逻辑,允许开发者额外定制裁剪逻辑。该方法会略过 `composition` 事件以防止被输入法卡住的情况。
  exceedFormatter?: ExceedFormatter;
}
截屏2023-09-27 14 27 15

exceedFormatter

Kapture 2023-09-27 at 14 29 28

src/hooks/useCount.ts Fixed Show fixed Hide fixed
@codecov
Copy link

codecov bot commented Sep 27, 2023

Codecov Report

Merging #47 (e399b09) into master (aa08e91) will decrease coverage by 3.45%.
The diff coverage is 89.58%.

❗ Current head e399b09 differs from pull request most recent head 5c95ff5. Consider uploading reports for the commit 5c95ff5 to get more accurate results

@@             Coverage Diff             @@
##            master      #47      +/-   ##
===========================================
- Coverage   100.00%   96.55%   -3.45%     
===========================================
  Files            4        5       +1     
  Lines          143      174      +31     
  Branches        55       68      +13     
===========================================
+ Hits           143      168      +25     
- Misses           0        6       +6     
Files Coverage Δ
src/Input.tsx 100.00% <100.00%> (ø)
src/utils/commonUtils.ts 97.14% <ø> (-2.86%) ⬇️
src/hooks/useCount.ts 70.58% <70.58%> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

count={{
show: true,
max: 5,
strategy: (val) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一定要用专业名词吗,可以简单点吗,比如 getCount

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一定要用专业名词吗,可以简单点吗,比如 getCount

其实习惯了就好了 😂

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

词不达意才更麻烦. 词越精确越好, 只不过我们非英语母语而已.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个和 @MadCcc 讨论下来,count 本身就是属性名里面再套一个 count 就重复了。所以复用了 Tree TreeSelect Cascader 的 strategy 的 API 名。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个可以参考 echarts,每个配置都有 formatter 自定义返回,对于图表或者组件,自定义方法的使用场景非常多,api 应该有个规范

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复用没问题,关键复用前第一次这个地方用的合不合适,比如 Table 的 dataIndex 对应的 render,这个就没定义成 strategy

按照 Naming Standard,render 系列命名需要带上 render 或为 xxxRender。其次,在固定规则外,复用现有命名 API,不额外创造。这个是符合我们的命名规范的。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

另外, 自定义计数和 formatter 是没有强相关的。开发者可以配置为 max + strategy 仅做超出警示,而不需要去做裁剪。参考一下这个截图:
截屏2023-09-27 15 00 31

Copy link
Contributor

@crazyair crazyair Sep 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉这个有问题啊,当 {max: 2} 用户只能输入2个字符,当 {max: 2, strategy:()=> 2},用户应该一个字符都不能输入

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

用户自己写了 2 那就认为当前输入的值长度为 2,自然是可以继续输入的。因为永远都不会超出长度。可以看一下 ant-design/ant-design#37733 过一下为什么要交给用户处理的上下文。

count={{
show: true,
max: 5,
exceedFormatter: (val, { max }) => {
Copy link
Contributor

@crazyair crazyair Sep 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exceed 只体现了超出,没说明超出哪个,api 应该加上 max

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个感觉没必要,exceed 本来就是超出,能超出的自然只有 max

Copy link
Contributor

@crazyair crazyair Sep 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个strategy会写到文档里,或者还会增加一个 demo,用户能认知strategy 可以解决什么问题,在这基础上,如果 api 名称为 getMax: (value) => number 则是 max 的自定义方法,一举两得。

如果要通过自定义方法的返回控制用户是否可以继续输入,或者右侧显示 1/2内容,都可以收成一个方法

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// 当超出 max 范围时处理逻辑,允许开发者额外定制裁剪逻辑。该方法会略过 composition 事件以防止被输入法卡住的情况。
exceedFormatter?: ExceedFormatter;

最早就是一个,后来发现有输入法收不起来,所以拆了一个裁剪方法。

composition 阶段,用户输入超出长度是正常的。裁剪只有在 composition 结束时才能处理。比如 你好 限制 2,在输入 nihao 的时候长度是 5 ,你不能拦住它输入。输入完后才能裁剪。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clone 本地测试了了下,体验来说没问题

Comment on lines +96 to 105
if (
!compositionRef.current &&
countConfig.exceedFormatter &&
countConfig.max &&
countConfig.strategy(currentValue) > countConfig.max
) {
cutValue = countConfig.exceedFormatter(currentValue, {
max: countConfig.max,
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这部分没有抽离到 useCount 吗

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useCount 里是合成 countConfig 的,它本身不处理 change 逻辑~

@zombieJ zombieJ merged commit f135900 into master Sep 27, 2023
7 checks passed
@delete-merged-branch delete-merged-branch bot deleted the len branch September 27, 2023 07:10
prefixCls="rc-input"
defaultValue="🔥"
count={{
show: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个不应该默认是 true 吗,因为外层 count={{}} 是真值

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不是的,原本是 showCount 默认为真。现在改名叫 count 是做计数使用。可以配置 strategy + max 仅做限制而不展示数字。

import Input from '../src';

const getSegments = (val: string) => [
...new (Intl as any).Segmenter().segment(val),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Segmenter 这个可以改 tsconfig "lib": ["dom", "es2017", "es2022"]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

学到了 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants