From ea6491783dcc79e610534632a05b2894ded97494 Mon Sep 17 00:00:00 2001 From: doom-9 <429664046@qq.com> Date: Thu, 17 Jun 2021 17:42:23 +0800 Subject: [PATCH 01/10] feat:n-input Support hidden password --- CHANGELOG.zh-CN.md | 4 ++ src/_internal/eye/index.ts | 1 + src/_internal/eye/src/Eye.tsx | 70 +++++++++++++++++++ src/_internal/eye/src/styles/index.cssr.ts | 58 +++++++++++++++ src/_internal/icons/Eye.tsx | 12 ++++ src/_internal/icons/EyeInvisible.tsx | 16 +++++ src/_internal/icons/index.ts | 2 + src/_internal/index.ts | 1 + src/config-provider/src/internal-interface.ts | 2 + src/input/src/Input.tsx | 23 ++++-- 10 files changed, 185 insertions(+), 4 deletions(-) create mode 100644 src/_internal/eye/index.ts create mode 100644 src/_internal/eye/src/Eye.tsx create mode 100644 src/_internal/eye/src/styles/index.cssr.ts create mode 100644 src/_internal/icons/Eye.tsx create mode 100644 src/_internal/icons/EyeInvisible.tsx diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 92a71597d81..bb75a75fb5d 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -2,6 +2,10 @@ ## 2.12.0 (2020-06-16) +### Feats + +- `n-input` 的 password 属性支持查看隐藏特性 + ### Breaking Changes - 移除了 `n-a` 的 `to` 属性。现在如果你需要把 `n-a` 用作 router-link,你可以参考文档网站。 diff --git a/src/_internal/eye/index.ts b/src/_internal/eye/index.ts new file mode 100644 index 00000000000..fc3190e24af --- /dev/null +++ b/src/_internal/eye/index.ts @@ -0,0 +1 @@ +export { default } from './src/Eye' diff --git a/src/_internal/eye/src/Eye.tsx b/src/_internal/eye/src/Eye.tsx new file mode 100644 index 00000000000..23a501a0e5e --- /dev/null +++ b/src/_internal/eye/src/Eye.tsx @@ -0,0 +1,70 @@ +import { h, defineComponent, PropType, toRef, ref } from 'vue' +import { useStyle, useConfig } from '../../../_mixins' +import { EyeIcon, EyeInvisibleIcon } from '../../icons' +import NBaseIcon from '../../icon' +import NIconSwitchTransition from '../../icon-switch-transition' +import style from './styles/index.cssr' + +export default defineComponent({ + name: 'BaseClear', + props: { + clsPrefix: { + type: String, + required: true + }, + onClick: { + type: Function as PropType<() => void>, + required: true + } + }, + setup (props) { + useStyle('BaseClear', style, toRef(props, 'clsPrefix')) + const { NConfigProvider } = useConfig() + const showPassWord = ref(false) + return { + NConfigProvider, + handleMouseDown (e: MouseEvent) { + e.preventDefault() + }, + showPassWord, + handleShowPassWord () { + showPassWord.value = !showPassWord.value + } + } + }, + render () { + const { clsPrefix, showPassWord, handleShowPassWord, onClick } = this + return ( +
+ + {{ + default: () => { + return ( + { + handleShowPassWord() + onClick() + }} + onMousedown={this.handleMouseDown} + > + {{ + default: () => { + if (showPassWord) { + return + } else { + return + } + } + }} + + ) + } + }} + +
+ ) + } +}) diff --git a/src/_internal/eye/src/styles/index.cssr.ts b/src/_internal/eye/src/styles/index.cssr.ts new file mode 100644 index 00000000000..26a791caf48 --- /dev/null +++ b/src/_internal/eye/src/styles/index.cssr.ts @@ -0,0 +1,58 @@ +import { cB, c, cE } from '../../../../_utils/cssr' +import createIconSwitchTransition from '../../../../_styles/transitions/icon-switch.cssr' + +// vars: +// --bezier +// --clear-color +// --clear-size +// --clear-color-hover +// --clear-color-pressed +export default cB( + 'base-clear', + { + flexShrink: 0, + height: '1em', + width: '1em', + position: 'relative' + }, + [ + c('>', [ + cE( + 'clear', + { + fontSize: 'var(--size)', + cursor: 'pointer', + color: 'var(--clear-color)', + transition: 'color .3s var(--bezier)' + }, + [ + c('&:hover', { + color: 'var(--clear-color-hover)!important' + }), + c('&:active', { + color: 'var(--clear-color-pressed)!important' + }) + ] + ), + cE('placeholder', { + display: 'flex' + }), + cE( + 'clear, placeholder', + { + position: 'absolute', + left: '50%', + top: '50%', + transform: 'translateX(-50%) translateY(-50%)' + }, + [ + createIconSwitchTransition({ + originalTransform: 'translateX(-50%) translateY(-50%)', + left: '50%', + top: '50%' + }) + ] + ) + ]) + ] +) diff --git a/src/_internal/icons/Eye.tsx b/src/_internal/icons/Eye.tsx new file mode 100644 index 00000000000..9501be4640c --- /dev/null +++ b/src/_internal/icons/Eye.tsx @@ -0,0 +1,12 @@ +import { h } from 'vue' +import { replaceable } from './replaceable' + +export default replaceable( + 'eye', + + + +) diff --git a/src/_internal/icons/EyeInvisible.tsx b/src/_internal/icons/EyeInvisible.tsx new file mode 100644 index 00000000000..8b91fb2f882 --- /dev/null +++ b/src/_internal/icons/EyeInvisible.tsx @@ -0,0 +1,16 @@ +import { h } from 'vue' +import { replaceable } from './replaceable' + +export default replaceable( + 'eyeinvisible', + + + + +) diff --git a/src/_internal/icons/index.ts b/src/_internal/icons/index.ts index 167dc47a591..baecf9a6358 100644 --- a/src/_internal/icons/index.ts +++ b/src/_internal/icons/index.ts @@ -11,6 +11,8 @@ export { default as TrashIcon } from './Trash' export { default as DownloadIcon } from './Download' export { default as EmptyIcon } from './Empty' export { default as ErrorIcon } from './Error' +export { default as EyeIcon } from './Eye' +export { default as EyeInvisibleIcon } from './EyeInvisible' export { default as FastBackwardIcon } from './FastBackward' export { default as FastForwardIcon } from './FastForward' export { default as FilterIcon } from './Filter' diff --git a/src/_internal/index.ts b/src/_internal/index.ts index 32bba5dc707..981713d9c5a 100644 --- a/src/_internal/index.ts +++ b/src/_internal/index.ts @@ -13,3 +13,4 @@ export { default as NInternalSelection } from './selection' export type { InternalSelectionInst } from './selection' export { default as NBaseSlotMachine } from './slot-machine' export { default as NBaseClear } from './clear' +export { default as NBaseEye } from './eye' diff --git a/src/config-provider/src/internal-interface.ts b/src/config-provider/src/internal-interface.ts index b9a1eb8c642..5235964c253 100644 --- a/src/config-provider/src/internal-interface.ts +++ b/src/config-provider/src/internal-interface.ts @@ -188,6 +188,8 @@ export interface GlobalIconConfig { date?: () => VNodeChild download?: () => VNodeChild error?: () => VNodeChild + eye?: () => VNodeChild + eyeinvisible?: () => VNodeChild info?: () => VNodeChild retry?: () => VNodeChild success?: () => VNodeChild diff --git a/src/input/src/Input.tsx b/src/input/src/Input.tsx index 8a216ba6a65..fc5a2746c65 100644 --- a/src/input/src/Input.tsx +++ b/src/input/src/Input.tsx @@ -18,7 +18,7 @@ import { import { useMergedState } from 'vooks' import { toRgbString, getAlphaString, getPadding } from 'seemly' import { VResizeObserver } from 'vueuc' -import { NBaseClear } from '../../_internal' +import { NBaseClear, NBaseEye } from '../../_internal' import { useTheme, useLocale, useFormItem, useConfig } from '../../_mixins' import type { ThemeProps } from '../../_mixins' import { call, createKey, ExtractPublicPropTypes } from '../../_utils' @@ -160,6 +160,7 @@ export default defineComponent({ const hoverRef = ref(false) const isComposingRef = ref(false) const activatedRef = ref(false) + const isShowPwd = ref(false) let syncSource: string | null = null // placeholder const mergedPlaceholderRef = computed<[string, string] | [string]>(() => { @@ -582,6 +583,9 @@ export default defineComponent({ function handleTextAreaMirrorResize (): void { updateTextAreaStyle() } + function handleShowPwd (): void { + isShowPwd.value = !isShowPwd.value + } let stopWatchMergedValue: WatchStopHandle | null = null watchEffect(() => { @@ -641,6 +645,7 @@ export default defineComponent({ textDecorationStyle: textDecorationStyleRef, mergedClsPrefix: mergedClsPrefixRef, mergedBordered: mergedBorderedRef, + isShowPwd, // methods handleCompositionStart, handleCompositionEnd, @@ -657,6 +662,7 @@ export default defineComponent({ handleClear, handleWrapperKeyDown, handleTextAreaMirrorResize, + handleShowPwd, mergedTheme: themeRef, cssVars: computed(() => { const { value: size } = mergedSizeRef @@ -759,7 +765,7 @@ export default defineComponent({ } }, render () { - const { mergedClsPrefix } = this + const { mergedClsPrefix, isShowPwd } = this return (
)} {!this.pair && - (this.$slots.suffix || this.clearable || this.showCount) ? ( + (this.$slots.suffix || + this.clearable || + this.showCount || + this.type === 'password') ? (
{[ renderSlot(this.$slots, 'suffix'), @@ -907,6 +916,12 @@ export default defineComponent({ ) : null, this.showCount && this.type !== 'textarea' ? ( + ) : null, + this.type === 'password' ? ( + ) : null ]}
From 06277776933ed4e68b32d2651014458aca2e50f6 Mon Sep 17 00:00:00 2001 From: doom-9 <429664046@qq.com> Date: Fri, 18 Jun 2021 09:53:50 +0800 Subject: [PATCH 02/10] feat(form): support require-mark-placement(#171) --- CHANGELOG.zh-CN.md | 4 ++ src/form/demos/zhCN/index.demo-entry.md | 2 + src/form/src/Form.tsx | 4 ++ src/form/src/FormItem.tsx | 54 ++++++++++++++++++------- src/form/src/utils.ts | 9 +++++ 5 files changed, 58 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index efb7c649aa2..bf0535aa2e8 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -4,6 +4,10 @@ ### Feats +- `n-form`,`n-form-item` 支持 require-mark-placement 属性,关闭 [#171](https://github.com/TuSimple/naive-ui/issues/171) + +### Feats + - `n-dropdown` 支持 class 属性,关闭 [#180](https://github.com/TuSimple/naive-ui/issues/180) ## 2.12.0 (2020-06-16) diff --git a/src/form/demos/zhCN/index.demo-entry.md b/src/form/demos/zhCN/index.demo-entry.md index 0058c28c0e0..1b9bc03f2ed 100644 --- a/src/form/demos/zhCN/index.demo-entry.md +++ b/src/form/demos/zhCN/index.demo-entry.md @@ -32,6 +32,7 @@ validator-debug | rules | `type FormRules = { [itemValidatePath: string]: FormItemRule \| Array \| FormRules }` | `{}` | 验证表项的规则 | | show-feedback | `boolean` | `true` | | | show-require-mark | `boolean` | `true` | 是否展示必填的星号 | +| require-mark-placement | `'start' \| 'end' ` | `end` | 必填的星号所在位置 | | size | `'small' \| 'medium' \| 'large'` | `'medium'` | | #### FormItemRule Type @@ -61,6 +62,7 @@ validator-debug | rule-path | `string` | `undefined` | 从外层表单的 `rules` 对象获取规则的路径。如果没有设定,使用表项的 `path` 代替 | | show-feedback | `boolean` | `true` | | | show-require-mark | `boolean` | `true` | 是否展示必填的星号。如果没有被设定,使用外层 `n-form` 的 `show-require-mark` | +| require-mark-placement | `'start' \| 'end' ` | `end` | 必填的星号所在位置。如果没有被设定,使用外层 `n-form` 的 `require-mark-placement` | | size | `'small' \| 'medium' \| 'large'` | `'medium'` | | | validation-status | `'error' \| 'success' \| 'warning'` | `undefined` | 表单的验证状态。不设为 `undefined`时,会覆盖规则验证的结果 | diff --git a/src/form/src/Form.tsx b/src/form/src/Form.tsx index 0884822d321..61429f8a7dd 100644 --- a/src/form/src/Form.tsx +++ b/src/form/src/Form.tsx @@ -43,6 +43,10 @@ const formProps = { type: Boolean as PropType, default: undefined }, + requireMarkPlacement: { + type: String as PropType<'start' | 'end'>, + default: 'end' + }, showFeedback: { type: Boolean, default: true diff --git a/src/form/src/FormItem.tsx b/src/form/src/FormItem.tsx index 6fc914c1b8a..76f19831df1 100644 --- a/src/form/src/FormItem.tsx +++ b/src/form/src/FormItem.tsx @@ -69,6 +69,10 @@ export const formItemProps = { type: Boolean as PropType, default: undefined }, + requireMarkPlacement: { + type: String as PropType<'start' | 'end'>, + default: undefined + }, showFeedback: { type: Boolean as PropType, default: undefined @@ -386,6 +390,8 @@ export default defineComponent({ }, render () { const { $slots, mergedClsPrefix } = this + console.log(this.mergedrequireMarkPlacement) + return (
{this.label || $slots.label ? ( - + this.mergedrequireMarkPlacement === 'end' ? ( + + ) : ( + + ) ) : null}
{ + const { requireMarkPlacement } = props + if (requireMarkPlacement !== undefined) return requireMarkPlacement + if (NForm?.requireMarkPlacement !== undefined) { + return NForm.requireMarkPlacement + } + return undefined + }) const validationErroredRef = ref(false) const mergedValidationStatusRef = computed(() => { const { validationStatus } = props @@ -81,6 +89,7 @@ export function formItemMisc (props: FormItemSetupProps) { mergedLabelPlacement: mergedLabelPlacementRef, mergedLabelAlign: mergedLabelAlignRef, mergedShowRequireMark: mergedShowRequireMarkRef, + mergedrequireMarkPlacement: mergedrequireMarkPlacementRef, mergedValidationStatus: mergedValidationStatusRef, mergedShowFeedback: mergedShowFeedbackRef } From f9729c8c6550acb2643e496ebba9e76b8ab0c435 Mon Sep 17 00:00:00 2001 From: doom-9 <429664046@qq.com> Date: Fri, 18 Jun 2021 10:16:13 +0800 Subject: [PATCH 03/10] Revert "feat(form): support require-mark-placement(#171)" This reverts commit 06277776933ed4e68b32d2651014458aca2e50f6. --- CHANGELOG.zh-CN.md | 4 -- src/form/demos/zhCN/index.demo-entry.md | 2 - src/form/src/Form.tsx | 4 -- src/form/src/FormItem.tsx | 54 +++++++------------------ src/form/src/utils.ts | 9 ----- 5 files changed, 15 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index bf0535aa2e8..efb7c649aa2 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -4,10 +4,6 @@ ### Feats -- `n-form`,`n-form-item` 支持 require-mark-placement 属性,关闭 [#171](https://github.com/TuSimple/naive-ui/issues/171) - -### Feats - - `n-dropdown` 支持 class 属性,关闭 [#180](https://github.com/TuSimple/naive-ui/issues/180) ## 2.12.0 (2020-06-16) diff --git a/src/form/demos/zhCN/index.demo-entry.md b/src/form/demos/zhCN/index.demo-entry.md index 1b9bc03f2ed..0058c28c0e0 100644 --- a/src/form/demos/zhCN/index.demo-entry.md +++ b/src/form/demos/zhCN/index.demo-entry.md @@ -32,7 +32,6 @@ validator-debug | rules | `type FormRules = { [itemValidatePath: string]: FormItemRule \| Array \| FormRules }` | `{}` | 验证表项的规则 | | show-feedback | `boolean` | `true` | | | show-require-mark | `boolean` | `true` | 是否展示必填的星号 | -| require-mark-placement | `'start' \| 'end' ` | `end` | 必填的星号所在位置 | | size | `'small' \| 'medium' \| 'large'` | `'medium'` | | #### FormItemRule Type @@ -62,7 +61,6 @@ validator-debug | rule-path | `string` | `undefined` | 从外层表单的 `rules` 对象获取规则的路径。如果没有设定,使用表项的 `path` 代替 | | show-feedback | `boolean` | `true` | | | show-require-mark | `boolean` | `true` | 是否展示必填的星号。如果没有被设定,使用外层 `n-form` 的 `show-require-mark` | -| require-mark-placement | `'start' \| 'end' ` | `end` | 必填的星号所在位置。如果没有被设定,使用外层 `n-form` 的 `require-mark-placement` | | size | `'small' \| 'medium' \| 'large'` | `'medium'` | | | validation-status | `'error' \| 'success' \| 'warning'` | `undefined` | 表单的验证状态。不设为 `undefined`时,会覆盖规则验证的结果 | diff --git a/src/form/src/Form.tsx b/src/form/src/Form.tsx index 61429f8a7dd..0884822d321 100644 --- a/src/form/src/Form.tsx +++ b/src/form/src/Form.tsx @@ -43,10 +43,6 @@ const formProps = { type: Boolean as PropType, default: undefined }, - requireMarkPlacement: { - type: String as PropType<'start' | 'end'>, - default: 'end' - }, showFeedback: { type: Boolean, default: true diff --git a/src/form/src/FormItem.tsx b/src/form/src/FormItem.tsx index 76f19831df1..6fc914c1b8a 100644 --- a/src/form/src/FormItem.tsx +++ b/src/form/src/FormItem.tsx @@ -69,10 +69,6 @@ export const formItemProps = { type: Boolean as PropType, default: undefined }, - requireMarkPlacement: { - type: String as PropType<'start' | 'end'>, - default: undefined - }, showFeedback: { type: Boolean as PropType, default: undefined @@ -390,8 +386,6 @@ export default defineComponent({ }, render () { const { $slots, mergedClsPrefix } = this - console.log(this.mergedrequireMarkPlacement) - return (
{this.label || $slots.label ? ( - this.mergedrequireMarkPlacement === 'end' ? ( - - ) : ( - - ) + ) : null}
{ - const { requireMarkPlacement } = props - if (requireMarkPlacement !== undefined) return requireMarkPlacement - if (NForm?.requireMarkPlacement !== undefined) { - return NForm.requireMarkPlacement - } - return undefined - }) const validationErroredRef = ref(false) const mergedValidationStatusRef = computed(() => { const { validationStatus } = props @@ -89,7 +81,6 @@ export function formItemMisc (props: FormItemSetupProps) { mergedLabelPlacement: mergedLabelPlacementRef, mergedLabelAlign: mergedLabelAlignRef, mergedShowRequireMark: mergedShowRequireMarkRef, - mergedrequireMarkPlacement: mergedrequireMarkPlacementRef, mergedValidationStatus: mergedValidationStatusRef, mergedShowFeedback: mergedShowFeedbackRef } From aa410275676d3229326e7bac49d025fb1538a320 Mon Sep 17 00:00:00 2001 From: doom-9 <429664046@qq.com> Date: Fri, 18 Jun 2021 16:07:40 +0800 Subject: [PATCH 04/10] Revert "feat:n-input Support hidden password" This reverts commit ea6491783dcc79e610534632a05b2894ded97494. --- CHANGELOG.zh-CN.md | 4 -- src/_internal/eye/index.ts | 1 - src/_internal/eye/src/Eye.tsx | 70 ------------------- src/_internal/eye/src/styles/index.cssr.ts | 58 --------------- src/_internal/icons/Eye.tsx | 12 ---- src/_internal/icons/EyeInvisible.tsx | 16 ----- src/_internal/icons/index.ts | 2 - src/_internal/index.ts | 1 - src/config-provider/src/internal-interface.ts | 2 - src/input/src/Input.tsx | 23 ++---- 10 files changed, 4 insertions(+), 185 deletions(-) delete mode 100644 src/_internal/eye/index.ts delete mode 100644 src/_internal/eye/src/Eye.tsx delete mode 100644 src/_internal/eye/src/styles/index.cssr.ts delete mode 100644 src/_internal/icons/Eye.tsx delete mode 100644 src/_internal/icons/EyeInvisible.tsx diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 5a6a1afd570..09044bf03fc 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -13,10 +13,6 @@ ## 2.12.0 (2020-06-16) -### Feats - -- `n-input` 的 password 属性支持查看隐藏特性 - ### Breaking Changes - 移除了 `n-a` 的 `to` 属性。现在如果你需要把 `n-a` 用作 router-link,你可以参考文档网站 diff --git a/src/_internal/eye/index.ts b/src/_internal/eye/index.ts deleted file mode 100644 index fc3190e24af..00000000000 --- a/src/_internal/eye/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './src/Eye' diff --git a/src/_internal/eye/src/Eye.tsx b/src/_internal/eye/src/Eye.tsx deleted file mode 100644 index 23a501a0e5e..00000000000 --- a/src/_internal/eye/src/Eye.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { h, defineComponent, PropType, toRef, ref } from 'vue' -import { useStyle, useConfig } from '../../../_mixins' -import { EyeIcon, EyeInvisibleIcon } from '../../icons' -import NBaseIcon from '../../icon' -import NIconSwitchTransition from '../../icon-switch-transition' -import style from './styles/index.cssr' - -export default defineComponent({ - name: 'BaseClear', - props: { - clsPrefix: { - type: String, - required: true - }, - onClick: { - type: Function as PropType<() => void>, - required: true - } - }, - setup (props) { - useStyle('BaseClear', style, toRef(props, 'clsPrefix')) - const { NConfigProvider } = useConfig() - const showPassWord = ref(false) - return { - NConfigProvider, - handleMouseDown (e: MouseEvent) { - e.preventDefault() - }, - showPassWord, - handleShowPassWord () { - showPassWord.value = !showPassWord.value - } - } - }, - render () { - const { clsPrefix, showPassWord, handleShowPassWord, onClick } = this - return ( -
- - {{ - default: () => { - return ( - { - handleShowPassWord() - onClick() - }} - onMousedown={this.handleMouseDown} - > - {{ - default: () => { - if (showPassWord) { - return - } else { - return - } - } - }} - - ) - } - }} - -
- ) - } -}) diff --git a/src/_internal/eye/src/styles/index.cssr.ts b/src/_internal/eye/src/styles/index.cssr.ts deleted file mode 100644 index 26a791caf48..00000000000 --- a/src/_internal/eye/src/styles/index.cssr.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { cB, c, cE } from '../../../../_utils/cssr' -import createIconSwitchTransition from '../../../../_styles/transitions/icon-switch.cssr' - -// vars: -// --bezier -// --clear-color -// --clear-size -// --clear-color-hover -// --clear-color-pressed -export default cB( - 'base-clear', - { - flexShrink: 0, - height: '1em', - width: '1em', - position: 'relative' - }, - [ - c('>', [ - cE( - 'clear', - { - fontSize: 'var(--size)', - cursor: 'pointer', - color: 'var(--clear-color)', - transition: 'color .3s var(--bezier)' - }, - [ - c('&:hover', { - color: 'var(--clear-color-hover)!important' - }), - c('&:active', { - color: 'var(--clear-color-pressed)!important' - }) - ] - ), - cE('placeholder', { - display: 'flex' - }), - cE( - 'clear, placeholder', - { - position: 'absolute', - left: '50%', - top: '50%', - transform: 'translateX(-50%) translateY(-50%)' - }, - [ - createIconSwitchTransition({ - originalTransform: 'translateX(-50%) translateY(-50%)', - left: '50%', - top: '50%' - }) - ] - ) - ]) - ] -) diff --git a/src/_internal/icons/Eye.tsx b/src/_internal/icons/Eye.tsx deleted file mode 100644 index 9501be4640c..00000000000 --- a/src/_internal/icons/Eye.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { h } from 'vue' -import { replaceable } from './replaceable' - -export default replaceable( - 'eye', - - - -) diff --git a/src/_internal/icons/EyeInvisible.tsx b/src/_internal/icons/EyeInvisible.tsx deleted file mode 100644 index 8b91fb2f882..00000000000 --- a/src/_internal/icons/EyeInvisible.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { h } from 'vue' -import { replaceable } from './replaceable' - -export default replaceable( - 'eyeinvisible', - - - - -) diff --git a/src/_internal/icons/index.ts b/src/_internal/icons/index.ts index baecf9a6358..167dc47a591 100644 --- a/src/_internal/icons/index.ts +++ b/src/_internal/icons/index.ts @@ -11,8 +11,6 @@ export { default as TrashIcon } from './Trash' export { default as DownloadIcon } from './Download' export { default as EmptyIcon } from './Empty' export { default as ErrorIcon } from './Error' -export { default as EyeIcon } from './Eye' -export { default as EyeInvisibleIcon } from './EyeInvisible' export { default as FastBackwardIcon } from './FastBackward' export { default as FastForwardIcon } from './FastForward' export { default as FilterIcon } from './Filter' diff --git a/src/_internal/index.ts b/src/_internal/index.ts index 981713d9c5a..32bba5dc707 100644 --- a/src/_internal/index.ts +++ b/src/_internal/index.ts @@ -13,4 +13,3 @@ export { default as NInternalSelection } from './selection' export type { InternalSelectionInst } from './selection' export { default as NBaseSlotMachine } from './slot-machine' export { default as NBaseClear } from './clear' -export { default as NBaseEye } from './eye' diff --git a/src/config-provider/src/internal-interface.ts b/src/config-provider/src/internal-interface.ts index 5235964c253..b9a1eb8c642 100644 --- a/src/config-provider/src/internal-interface.ts +++ b/src/config-provider/src/internal-interface.ts @@ -188,8 +188,6 @@ export interface GlobalIconConfig { date?: () => VNodeChild download?: () => VNodeChild error?: () => VNodeChild - eye?: () => VNodeChild - eyeinvisible?: () => VNodeChild info?: () => VNodeChild retry?: () => VNodeChild success?: () => VNodeChild diff --git a/src/input/src/Input.tsx b/src/input/src/Input.tsx index fc5a2746c65..8a216ba6a65 100644 --- a/src/input/src/Input.tsx +++ b/src/input/src/Input.tsx @@ -18,7 +18,7 @@ import { import { useMergedState } from 'vooks' import { toRgbString, getAlphaString, getPadding } from 'seemly' import { VResizeObserver } from 'vueuc' -import { NBaseClear, NBaseEye } from '../../_internal' +import { NBaseClear } from '../../_internal' import { useTheme, useLocale, useFormItem, useConfig } from '../../_mixins' import type { ThemeProps } from '../../_mixins' import { call, createKey, ExtractPublicPropTypes } from '../../_utils' @@ -160,7 +160,6 @@ export default defineComponent({ const hoverRef = ref(false) const isComposingRef = ref(false) const activatedRef = ref(false) - const isShowPwd = ref(false) let syncSource: string | null = null // placeholder const mergedPlaceholderRef = computed<[string, string] | [string]>(() => { @@ -583,9 +582,6 @@ export default defineComponent({ function handleTextAreaMirrorResize (): void { updateTextAreaStyle() } - function handleShowPwd (): void { - isShowPwd.value = !isShowPwd.value - } let stopWatchMergedValue: WatchStopHandle | null = null watchEffect(() => { @@ -645,7 +641,6 @@ export default defineComponent({ textDecorationStyle: textDecorationStyleRef, mergedClsPrefix: mergedClsPrefixRef, mergedBordered: mergedBorderedRef, - isShowPwd, // methods handleCompositionStart, handleCompositionEnd, @@ -662,7 +657,6 @@ export default defineComponent({ handleClear, handleWrapperKeyDown, handleTextAreaMirrorResize, - handleShowPwd, mergedTheme: themeRef, cssVars: computed(() => { const { value: size } = mergedSizeRef @@ -765,7 +759,7 @@ export default defineComponent({ } }, render () { - const { mergedClsPrefix, isShowPwd } = this + const { mergedClsPrefix } = this return (
)} {!this.pair && - (this.$slots.suffix || - this.clearable || - this.showCount || - this.type === 'password') ? ( + (this.$slots.suffix || this.clearable || this.showCount) ? (
{[ renderSlot(this.$slots, 'suffix'), @@ -916,12 +907,6 @@ export default defineComponent({ ) : null, this.showCount && this.type !== 'textarea' ? ( - ) : null, - this.type === 'password' ? ( - ) : null ]}
From b67ea38e60f34bf9a859086d2187bd31bac54a7e Mon Sep 17 00:00:00 2001 From: doom-9 <429664046@qq.com> Date: Fri, 2 Jul 2021 10:08:43 +0800 Subject: [PATCH 05/10] feat:(image): add test --- src/image/tests/Image.spec.tsx | 63 ++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/image/tests/Image.spec.tsx diff --git a/src/image/tests/Image.spec.tsx b/src/image/tests/Image.spec.tsx new file mode 100644 index 00000000000..1345214734e --- /dev/null +++ b/src/image/tests/Image.spec.tsx @@ -0,0 +1,63 @@ +import { mount } from '@vue/test-utils' +import { NImage } from '../index' +import ImagePreview from '../src/ImagePreview' + +describe('n-image', () => { + it('should work with import on demand', () => { + mount(NImage) + }) + + it('should work with `alt` prop', async () => { + const wrapper = mount(NImage) + + await wrapper.setProps({ alt: 'This is just a picture' }) + + expect(wrapper.find('img').attributes('alt')).toBe('This is just a picture') + }) + + it('should work with `width` prop', async () => { + const wrapper = mount(NImage) + + await wrapper.setProps({ width: '200' }) + + expect(wrapper.find('img').attributes('width')).toBe('200') + + await wrapper.setProps({ width: 200 }) + + expect(wrapper.find('img').attributes('width')).toBe('200') + }) + + it('should work with `height` prop', async () => { + const wrapper = mount(NImage) + + await wrapper.setProps({ height: '300' }) + + expect(wrapper.find('img').attributes('height')).toBe('300') + + await wrapper.setProps({ height: 300 }) + + expect(wrapper.find('img').attributes('height')).toBe('300') + }) + + it('should work with `src` prop', async () => { + const wrapper = mount(NImage) + + await wrapper.setProps({ + src: 'https://www.naiveui.com/assets/naivelogo.93278402.svg' + }) + + expect(wrapper.find('img').attributes('src')).toBe( + 'https://www.naiveui.com/assets/naivelogo.93278402.svg' + ) + }) + + it('should work with `showToolbar` prop', async () => { + const wrapper = mount(NImage) + + await wrapper.setProps({ + showToolbar: true + }) + + expect(wrapper.findComponent(ImagePreview).props('showToolbar')).toBe(true) + }) +}) From a10c17e77ccbdbd9fa786f03b00a9b7010186e50 Mon Sep 17 00:00:00 2001 From: doom-9 <429664046@qq.com> Date: Fri, 2 Jul 2021 10:11:06 +0800 Subject: [PATCH 06/10] feat:(image): add test --- src/image/tests/Image.spec.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/image/tests/Image.spec.tsx b/src/image/tests/Image.spec.tsx index 1345214734e..578e3e18afc 100644 --- a/src/image/tests/Image.spec.tsx +++ b/src/image/tests/Image.spec.tsx @@ -13,6 +13,9 @@ describe('n-image', () => { await wrapper.setProps({ alt: 'This is just a picture' }) expect(wrapper.find('img').attributes('alt')).toBe('This is just a picture') + expect(wrapper.find('img').attributes('aria-label')).toBe( + 'This is just a picture' + ) }) it('should work with `width` prop', async () => { From b93c886019f55745a65d1d296214346e391334f5 Mon Sep 17 00:00:00 2001 From: doom-9 <429664046@qq.com> Date: Fri, 2 Jul 2021 17:56:30 +0800 Subject: [PATCH 07/10] WIP --- src/image/src/Image.tsx | 48 +++++++++++++++++++++++++--------- src/image/tests/Image.spec.tsx | 20 +++++++++++--- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/image/src/Image.tsx b/src/image/src/Image.tsx index 56e9d34dcdf..6d576420dc4 100644 --- a/src/image/src/Image.tsx +++ b/src/image/src/Image.tsx @@ -1,4 +1,12 @@ -import { defineComponent, h, inject, ref, PropType } from 'vue' +import { + computed, + defineComponent, + h, + inject, + ref, + PropType, + ImgHTMLAttributes +} from 'vue' import NImagePreview from './ImagePreview' import type { ImagePreviewInst } from './ImagePreview' import { imageGroupInjectionKey } from './ImageGroup' @@ -7,8 +15,9 @@ import { useConfig } from '../../_mixins' const imageProps = { alt: String, - width: [String, Number] as PropType, height: [String, Number] as PropType, + imgProps: Object as PropType, + width: [String, Number] as PropType, src: String, showToolbar: { type: Boolean, default: true } } @@ -20,14 +29,24 @@ export default defineComponent({ props: imageProps, setup (props) { const imageRef = ref(null) + const imgPropsRef = props.imgProps || {} const previewInstRef = ref(null) const imageGroupHandle = inject(imageGroupInjectionKey, null) const { mergedClsPrefixRef } = imageGroupHandle || useConfig(props) return { mergedClsPrefix: mergedClsPrefixRef, + mergedWidth: computed(() => + props.width ? props.width : imgPropsRef.width + ), + mergedHeight: computed(() => + props.height ? props.height : imgPropsRef.height + ), + mergedSrc: computed(() => (props.src ? props.src : imgPropsRef.src)), + mergedAlt: computed(() => (props.alt ? props.alt : imgPropsRef.alt)), groupId: imageGroupHandle?.groupId, previewInstRef, imageRef, + imgProps: imgPropsRef, handleClick: () => { if (imageGroupHandle) { imageGroupHandle.setPreviewSrc(props.src) @@ -44,17 +63,19 @@ export default defineComponent({ } }, render () { - const { mergedClsPrefix } = this + const { mergedClsPrefix, imgProps } = this + return this.groupId ? (
{this.alt}
@@ -70,11 +91,12 @@ export default defineComponent({
{this.alt}
diff --git a/src/image/tests/Image.spec.tsx b/src/image/tests/Image.spec.tsx index 578e3e18afc..c1bdfe621d4 100644 --- a/src/image/tests/Image.spec.tsx +++ b/src/image/tests/Image.spec.tsx @@ -1,6 +1,5 @@ import { mount } from '@vue/test-utils' import { NImage } from '../index' -import ImagePreview from '../src/ImagePreview' describe('n-image', () => { it('should work with import on demand', () => { @@ -55,12 +54,27 @@ describe('n-image', () => { }) it('should work with `showToolbar` prop', async () => { - const wrapper = mount(NImage) + const wrapper = mount(NImage, { + attachTo: document.body + }) await wrapper.setProps({ showToolbar: true }) - expect(wrapper.findComponent(ImagePreview).props('showToolbar')).toBe(true) + await wrapper.find('img').trigger('click') + + console.log(document.querySelector('n-image-preview-toolbar')) + + // await wrapper + // .findComponent(ImagePreview) + // .findComponent(LazyTeleport) + // .setProps({ + // disabled: true + // }) + + // expect( + // wrapper.findComponent(ImagePreview).findComponent(LazyTeleport).html() + // ).toBe(true) }) }) From 0c2f8a3a4874bdee269f29324b9a458dfcaa024e Mon Sep 17 00:00:00 2001 From: doom-9 <429664046@qq.com> Date: Fri, 2 Jul 2021 18:04:48 +0800 Subject: [PATCH 08/10] WIP --- src/image/tests/Image.spec.tsx | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/image/tests/Image.spec.tsx b/src/image/tests/Image.spec.tsx index c1bdfe621d4..095b71ff7d9 100644 --- a/src/image/tests/Image.spec.tsx +++ b/src/image/tests/Image.spec.tsx @@ -54,27 +54,14 @@ describe('n-image', () => { }) it('should work with `showToolbar` prop', async () => { - const wrapper = mount(NImage, { - attachTo: document.body - }) + const wrapper = mount(NImage) await wrapper.setProps({ showToolbar: true }) - await wrapper.find('img').trigger('click') - - console.log(document.querySelector('n-image-preview-toolbar')) - - // await wrapper - // .findComponent(ImagePreview) - // .findComponent(LazyTeleport) - // .setProps({ - // disabled: true - // }) + // await wrapper.find('img').trigger('click') - // expect( - // wrapper.findComponent(ImagePreview).findComponent(LazyTeleport).html() - // ).toBe(true) + expect(!!document.querySelector('.n-image-preview-toolbar')).toBe(true) }) }) From 295cc2cb31ad32f2fe5a1bdfcceccd9176e40ee8 Mon Sep 17 00:00:00 2001 From: doom-9 <65016011+doom-9@users.noreply.github.com> Date: Fri, 2 Jul 2021 22:59:30 +0800 Subject: [PATCH 09/10] feat(image): add imgProps prop and add test --- CHANGELOG.en-US.md | 1 + CHANGELOG.zh-CN.md | 1 + src/image/src/Image.tsx | 53 +++++++++++++--------------------- src/image/tests/Image.spec.tsx | 4 +-- 4 files changed, 24 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 4a312530206..1a3dc1a1909 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -5,6 +5,7 @@ ### Feats - `n-loading-bar` export `LoadingBarApi` type +- `n-image` add `imgProps` prop ## 2.15.2 (2021-07-02) diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 0f1150d98dc..dc4e496f60b 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -5,6 +5,7 @@ ### Feats - `n-loading-bar` 导出 `LoadingBarApi` 类型 +- `n-image` 增加 `imgProps` 属性 ## 2.15.2 (2021-07-02) diff --git a/src/image/src/Image.tsx b/src/image/src/Image.tsx index 6d576420dc4..c32c453e525 100644 --- a/src/image/src/Image.tsx +++ b/src/image/src/Image.tsx @@ -1,11 +1,11 @@ import { - computed, defineComponent, h, inject, ref, PropType, - ImgHTMLAttributes + ImgHTMLAttributes, + toRef } from 'vue' import NImagePreview from './ImagePreview' import type { ImagePreviewInst } from './ImagePreview' @@ -29,20 +29,12 @@ export default defineComponent({ props: imageProps, setup (props) { const imageRef = ref(null) - const imgPropsRef = props.imgProps || {} + const imgPropsRef = toRef(props, 'imgProps') const previewInstRef = ref(null) const imageGroupHandle = inject(imageGroupInjectionKey, null) const { mergedClsPrefixRef } = imageGroupHandle || useConfig(props) return { mergedClsPrefix: mergedClsPrefixRef, - mergedWidth: computed(() => - props.width ? props.width : imgPropsRef.width - ), - mergedHeight: computed(() => - props.height ? props.height : imgPropsRef.height - ), - mergedSrc: computed(() => (props.src ? props.src : imgPropsRef.src)), - mergedAlt: computed(() => (props.alt ? props.alt : imgPropsRef.alt)), groupId: imageGroupHandle?.groupId, previewInstRef, imageRef, @@ -63,21 +55,25 @@ export default defineComponent({ } }, render () { - const { mergedClsPrefix, imgProps } = this + const { mergedClsPrefix, imgProps = {} } = this + + const imgNode = ( + {this.alt + ) return this.groupId ? (
- {this.mergedAlt} + {imgNode}
) : ( { return (
- {this.mergedAlt} + {imgNode}
) } diff --git a/src/image/tests/Image.spec.tsx b/src/image/tests/Image.spec.tsx index 095b71ff7d9..9173f109c35 100644 --- a/src/image/tests/Image.spec.tsx +++ b/src/image/tests/Image.spec.tsx @@ -60,8 +60,8 @@ describe('n-image', () => { showToolbar: true }) - // await wrapper.find('img').trigger('click') + await wrapper.find('img').trigger('click') - expect(!!document.querySelector('.n-image-preview-toolbar')).toBe(true) + expect(document.querySelector('.n-image-preview-toolbar')).not.toEqual(null) }) }) From 559d220b958c8c2088d5ae082b7f4f7c1c5c6ed0 Mon Sep 17 00:00:00 2001 From: doom-9 <65016011+doom-9@users.noreply.github.com> Date: Sat, 3 Jul 2021 09:08:27 +0800 Subject: [PATCH 10/10] feat(image): add imgProps type --- src/image/src/Image.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/image/src/Image.tsx b/src/image/src/Image.tsx index c32c453e525..9927d853a3a 100644 --- a/src/image/src/Image.tsx +++ b/src/image/src/Image.tsx @@ -1,22 +1,26 @@ -import { - defineComponent, - h, - inject, - ref, - PropType, - ImgHTMLAttributes, - toRef -} from 'vue' +import { defineComponent, h, inject, ref, PropType, toRef } from 'vue' import NImagePreview from './ImagePreview' import type { ImagePreviewInst } from './ImagePreview' import { imageGroupInjectionKey } from './ImageGroup' import { ExtractPublicPropTypes } from '../../_utils' import { useConfig } from '../../_mixins' +interface imgProps { + alt?: string + crossorigin?: 'anonymous' | 'use-credentials' | '' + decoding?: 'async' | 'auto' | 'sync' + height?: number + sizes?: string + src?: string + srcset?: string + usemap?: string + width?: number +} + const imageProps = { alt: String, height: [String, Number] as PropType, - imgProps: Object as PropType, + imgProps: Object as PropType, width: [String, Number] as PropType, src: String, showToolbar: { type: Boolean, default: true }