diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 3625680f6..9f46d44dd 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -5,6 +5,7 @@ ### Breaking Changes - `n-date-picker`'s `clearable` will control visibility of clear button is no `action` is set, closes [#1196](https://github.com/TuSimple/naive-ui/issues/1196). +- `n-button`'s `native-focus-behavior` prop default value is changed to 'not on Safari'. ### Fixes @@ -23,6 +24,7 @@ - Fix `n-input`'s separator may have line wrap. - Fix all components' `user-select` style prop's effect on Safari. - Fix `n-data-table` will prevent page scroll in virtual scroll mode. +- Fix `n-button` doesn't have pressed effect on Firefox. ### Feats diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index a9f3341c7..029f37141 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -5,6 +5,7 @@ ### Breaking Changes - `n-date-picker` 的 `clearable` 属性在 `action` 属性没有设置时,会控面板清空按钮的显隐,关闭 [#1196](https://github.com/TuSimple/naive-ui/issues/1196) +- `n-button` 的 `native-focus-behavior` 属性默认值改为“不是 Safari” ### Fixes @@ -23,6 +24,7 @@ - 修复 `n-input` 的分割符可能折行 - 修复所有组件的 `user-select` 样式属性在 Safari 的效果 - 修复 `n-data-table` 在虚拟滚动模式下会阻止页面滚动 +- 修复 `n-button` 在 Firefox 下没有按下的效果 ### Feats diff --git a/src/_mixins/use-rtl.ts b/src/_mixins/use-rtl.ts index fb2091af9..5019b3175 100644 --- a/src/_mixins/use-rtl.ts +++ b/src/_mixins/use-rtl.ts @@ -7,7 +7,7 @@ import { } from '../config-provider/src/internal-interface' import { cssrAnchorMetaName } from './common' -export default function useRtl ( +export function useRtl ( mountId: string, rtlStateRef: Ref | undefined, clsPrefixRef: Ref diff --git a/src/_utils/env/browser.ts b/src/_utils/env/browser.ts new file mode 100644 index 000000000..6fb88f967 --- /dev/null +++ b/src/_utils/env/browser.ts @@ -0,0 +1,5 @@ +import { isBrowser } from './is-browser' +export const isChrome = isBrowser && 'chrome' in window +export const isFirefox = isBrowser && navigator.userAgent.includes('Firefox') +export const isSafari = + isBrowser && navigator.userAgent.includes('Safari') && !isChrome diff --git a/src/alert/src/Alert.tsx b/src/alert/src/Alert.tsx index 18fc77434..b3861d6ee 100644 --- a/src/alert/src/Alert.tsx +++ b/src/alert/src/Alert.tsx @@ -16,7 +16,7 @@ import { ErrorIcon } from '../../_internal/icons' import { NFadeInExpandTransition, NBaseClose, NBaseIcon } from '../../_internal' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { useConfig, useTheme, useThemeClass } from '../../_mixins' import type { ThemeProps } from '../../_mixins' import { diff --git a/src/avatar-group/src/AvatarGroup.tsx b/src/avatar-group/src/AvatarGroup.tsx index 090cd1d0b..17f8b0bd2 100644 --- a/src/avatar-group/src/AvatarGroup.tsx +++ b/src/avatar-group/src/AvatarGroup.tsx @@ -13,7 +13,7 @@ import { useConfig, useTheme } from '../../_mixins' import type { ThemeProps } from '../../_mixins' import type { ExtractPublicPropTypes } from '../../_utils' import style from './styles/avatar-group.cssr' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { avatarGroupLight, AvatarGroupTheme } from '../styles' export interface AvatarGroupInjection { diff --git a/src/badge/src/Badge.tsx b/src/badge/src/Badge.tsx index dc0ad5789..e3b2cc4cb 100644 --- a/src/badge/src/Badge.tsx +++ b/src/badge/src/Badge.tsx @@ -22,7 +22,7 @@ import type { ExtractPublicPropTypes } from '../../_utils' import { badgeLight } from '../styles' import type { BadgeTheme } from '../styles' import style from './styles/index.cssr' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' export const badgeProps = { ...(useTheme.props as ThemeProps), diff --git a/src/button-group/src/ButtonGroup.tsx b/src/button-group/src/ButtonGroup.tsx index 3037ea165..672b89768 100644 --- a/src/button-group/src/ButtonGroup.tsx +++ b/src/button-group/src/ButtonGroup.tsx @@ -1,6 +1,6 @@ import { h, PropType, defineComponent, provide } from 'vue' import type { Size } from '../../button/src/interface' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { useConfig, useStyle } from '../../_mixins' import type { ExtractPublicPropTypes } from '../../_utils' import { buttonGroupInjectionKey } from './context' diff --git a/src/button/demos/enUS/index.demo-entry.md b/src/button/demos/enUS/index.demo-entry.md index 7065abea0..48ef9b266 100644 --- a/src/button/demos/enUS/index.demo-entry.md +++ b/src/button/demos/enUS/index.demo-entry.md @@ -40,7 +40,7 @@ popover.vue | disabled | `boolean` | `false` | Whether the button is disabled. | | | focusable | `boolean` | `true` | Whether the button is focusable. | | | ghost | `boolean` | `false` | Whether the button is ghost. | | -| native-focus-behavior | `boolean` | `false` | Whether to follow button's native focus behavior. Since safari's button can't be focused by click, naive-ui uses some tricks to make it focusable on safari. If you don't need the behavior or need the button to be draggable, you can enable the prop. | 2.28.3 | +| native-focus-behavior | `boolean` | Browser is not Safari | Whether to follow button's native focus behavior. Since safari's button can't be focused by click, naive-ui uses some tricks to make it focusable on safari. If you don't need the behavior or need the button to be draggable, you can enable the prop. | 2.28.3 | | icon-placement | `'left' \| 'right'` | `'left'` | The position of the icon in the button. | | | keyboard | `boolean` | `true` | Whether is supports keyboard operation. | | | quaternary | `boolean` | `false` | Whether the button is quaternary button. | | diff --git a/src/button/demos/zhCN/index.demo-entry.md b/src/button/demos/zhCN/index.demo-entry.md index 72eacb8cb..80eec6b57 100644 --- a/src/button/demos/zhCN/index.demo-entry.md +++ b/src/button/demos/zhCN/index.demo-entry.md @@ -42,7 +42,7 @@ debug.vue | disabled | `boolean` | `false` | 按钮是否禁用 | | | focusable | `boolean` | `true` | 按钮是否可以被聚焦 | | | ghost | `boolean` | `false` | 按钮是否透明 | | -| native-focus-behavior | `boolean` | `false` | 按钮是否遵循原生的 focus 行为。Safari 原生的 button 无法通过点击被聚焦,所以默认情况下 naive-ui 做了一些处理使它可以被聚焦,如果你不需要这种行为,或者发现你需要让按钮可被拖动,可以开启这个属性 | 2.28.3 | +| native-focus-behavior | `boolean` | 浏览器不是 Safari | 按钮是否遵循原生的 focus 行为。Safari 原生的 button 无法通过点击被聚焦,所以默认情况下 naive-ui 做了一些处理使它可以被聚焦,如果你不需要这种行为,或者发现你需要让按钮可被拖动,可以开启这个属性 | 2.28.3 | | icon-placement | `'left' \| 'right'` | `'left'` | 按钮中图标的位置 | | | keyboard | `boolean` | `true` | 是否支持键盘操作 | | | loading | `boolean` | `false` | 按钮是否显示加载状态 | | diff --git a/src/button/src/Button.tsx b/src/button/src/Button.tsx index b4bf450d3..091d1ea2f 100644 --- a/src/button/src/Button.tsx +++ b/src/button/src/Button.tsx @@ -13,6 +13,9 @@ import { import { useMemo } from 'vooks' import { changeColor } from 'seemly' import { createHoverColor, createPressedColor } from '../../_utils/color/index' +import { buttonGroupInjectionKey } from '../../button-group/src/context' +import { useRtl } from '../../_mixins/use-rtl' +import { isSafari } from '../../_utils/env/browser' import { useConfig, useFormItem, useTheme, useThemeClass } from '../../_mixins' import type { ThemeProps } from '../../_mixins' import { @@ -33,10 +36,8 @@ import { import type { ExtractPublicPropTypes, MaybeArray } from '../../_utils' import { buttonLight } from '../styles' import type { ButtonTheme } from '../styles' -import { buttonGroupInjectionKey } from '../../button-group/src/context' import type { Type, Size } from './interface' import style from './styles/index.cssr' -import useRtl from '../../_mixins/use-rtl' export const buttonProps = { ...(useTheme.props as ThemeProps), @@ -84,7 +85,10 @@ export const buttonProps = { default: true }, onClick: [Function, Array] as PropType void>>, - nativeFocusBehavior: Boolean + nativeFocusBehavior: { + Boolean, + default: !isSafari + } } as const export type ButtonProps = ExtractPublicPropTypes diff --git a/src/card/src/Card.tsx b/src/card/src/Card.tsx index 011dd0898..5eb4047b7 100644 --- a/src/card/src/Card.tsx +++ b/src/card/src/Card.tsx @@ -1,6 +1,6 @@ import { h, defineComponent, computed, PropType, CSSProperties } from 'vue' import { getPadding } from 'seemly' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { useConfig, useTheme, useThemeClass } from '../../_mixins' import type { ThemeProps } from '../../_mixins' import { call, createKey, keysOf, resolveWrappedSlot } from '../../_utils' diff --git a/src/checkbox/src/Checkbox.tsx b/src/checkbox/src/Checkbox.tsx index a42941759..eb7f93b1d 100644 --- a/src/checkbox/src/Checkbox.tsx +++ b/src/checkbox/src/Checkbox.tsx @@ -33,7 +33,7 @@ import type { CheckboxInst } from './interface' import style from './styles/index.cssr' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' export const checkboxProps = { ...(useTheme.props as ThemeProps), diff --git a/src/collapse-transition/src/CollapseTransition.tsx b/src/collapse-transition/src/CollapseTransition.tsx index a2eb7cb9a..2b37a0abd 100644 --- a/src/collapse-transition/src/CollapseTransition.tsx +++ b/src/collapse-transition/src/CollapseTransition.tsx @@ -7,7 +7,7 @@ import { watchEffect } from 'vue' import { useConfig, useTheme, useThemeClass } from '../../_mixins' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import type { ThemeProps } from '../../_mixins' import type { ExtractPublicPropTypes } from '../../_utils' import { warnOnce } from '../../_utils' diff --git a/src/collapse/src/Collapse.tsx b/src/collapse/src/Collapse.tsx index 61331c1ef..ba33f167a 100644 --- a/src/collapse/src/Collapse.tsx +++ b/src/collapse/src/Collapse.tsx @@ -22,7 +22,7 @@ import { import type { MaybeArray } from '../../_utils' import { collapseLight, CollapseTheme } from '../styles' import style from './styles/index.cssr' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { OnItemHeaderClick, OnUpdateExpandedNames, diff --git a/src/collapse/src/CollapseItem.tsx b/src/collapse/src/CollapseItem.tsx index 519ba2317..f7aebd4b5 100644 --- a/src/collapse/src/CollapseItem.tsx +++ b/src/collapse/src/CollapseItem.tsx @@ -9,7 +9,7 @@ import { NBaseIcon } from '../../_internal' import { ExtractPublicPropTypes, throwError } from '../../_utils' import { collapseInjectionKey } from './Collapse' import NCollapseItemContent from './CollapseItemContent' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { useConfig } from '../../_mixins' export const collapseItemProps = { diff --git a/src/dynamic-input/src/DynamicInput.tsx b/src/dynamic-input/src/DynamicInput.tsx index bf9024e1f..4eb961573 100644 --- a/src/dynamic-input/src/DynamicInput.tsx +++ b/src/dynamic-input/src/DynamicInput.tsx @@ -36,7 +36,7 @@ import NDynamicInputPairPreset from './PairPreset' import { dynamicInputInjectionKey } from './interface' import type { OnUpdateValue } from './interface' import style from './styles/index.cssr' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' const globalDataKeyMap = new WeakMap() diff --git a/src/input-number/src/InputNumber.tsx b/src/input-number/src/InputNumber.tsx index 03fe8593f..32feb0136 100644 --- a/src/input-number/src/InputNumber.tsx +++ b/src/input-number/src/InputNumber.tsx @@ -33,7 +33,7 @@ import type { InputNumberTheme } from '../styles' import { parse, validator, format, parseNumber, isWipValue } from './utils' import type { OnUpdateValue, InputNumberInst } from './interface' import style from './styles/input-number.cssr' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' const HOLDING_CHANGE_THRESHOLD = 800 const HOLDING_CHANGE_INTERVAL = 100 diff --git a/src/input/src/Input.tsx b/src/input/src/Input.tsx index 8096e2efb..c222915e7 100644 --- a/src/input/src/Input.tsx +++ b/src/input/src/Input.tsx @@ -24,7 +24,7 @@ import { VResizeObserver } from 'vueuc' import { off, on } from 'evtd' import type { FormValidationStatus } from '../../form/src/interface' import { EyeIcon, EyeOffIcon } from '../../_internal/icons' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { NBaseClear, NBaseIcon, diff --git a/src/notification/src/Notification.tsx b/src/notification/src/Notification.tsx index 349baab6e..22ee2e69f 100644 --- a/src/notification/src/Notification.tsx +++ b/src/notification/src/Notification.tsx @@ -14,7 +14,7 @@ import { WarningIcon, ErrorIcon } from '../../_internal/icons' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { createKey, keysOf, render } from '../../_utils' import { NBaseIcon, NBaseClose } from '../../_internal' import { useConfig, useThemeClass } from '../../_mixins' diff --git a/src/page-header/src/PageHeader.tsx b/src/page-header/src/PageHeader.tsx index fc0629fdb..13df62b4e 100644 --- a/src/page-header/src/PageHeader.tsx +++ b/src/page-header/src/PageHeader.tsx @@ -8,7 +8,7 @@ import style from './styles/index.cssr' import { ArrowBackIcon } from '../../_internal/icons' import { NBaseIcon } from '../../_internal' import type { ExtractPublicPropTypes } from '../../_utils' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' export const pageHeaderProps = { ...(useTheme.props as ThemeProps), diff --git a/src/pagination/src/Pagination.tsx b/src/pagination/src/Pagination.tsx index f4ff01415..07aeee2fe 100644 --- a/src/pagination/src/Pagination.tsx +++ b/src/pagination/src/Pagination.tsx @@ -50,7 +50,7 @@ import { RenderSuffix, Size } from './interface' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' export const paginationProps = { ...(useTheme.props as ThemeProps), diff --git a/src/radio/src/Radio.tsx b/src/radio/src/Radio.tsx index f5ec8460f..3053da34a 100644 --- a/src/radio/src/Radio.tsx +++ b/src/radio/src/Radio.tsx @@ -6,7 +6,7 @@ import type { ExtractPublicPropTypes } from '../../_utils' import { radioLight, RadioTheme } from '../styles' import useRadio from './use-radio' import style from './styles/radio.cssr' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' export const radioProps = useRadio.props export type RadioProps = ExtractPublicPropTypes diff --git a/src/radio/src/RadioGroup.tsx b/src/radio/src/RadioGroup.tsx index d4929227f..8c155ac7e 100644 --- a/src/radio/src/RadioGroup.tsx +++ b/src/radio/src/RadioGroup.tsx @@ -21,7 +21,7 @@ import type { RadioProps } from './use-radio' import { radioGroupInjectionKey } from './use-radio' import style from './styles/radio-group.cssr' import { OnUpdateValue, OnUpdateValueImpl } from './interface' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' function mapSlot ( defaultSlot: VNode[], diff --git a/src/space/src/Space.tsx b/src/space/src/Space.tsx index da8865d60..ff063c88d 100644 --- a/src/space/src/Space.tsx +++ b/src/space/src/Space.tsx @@ -6,7 +6,7 @@ import { useConfig, useTheme } from '../../_mixins' import type { ThemeProps } from '../../_mixins' import { spaceLight } from '../styles' import type { SpaceTheme } from '../styles' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { ensureSupportFlexGap } from './utils' type Align = diff --git a/src/table/src/Table.tsx b/src/table/src/Table.tsx index c5ec8abd6..3d83795c6 100644 --- a/src/table/src/Table.tsx +++ b/src/table/src/Table.tsx @@ -1,6 +1,6 @@ import { defineComponent, computed, h, PropType, CSSProperties } from 'vue' import { useConfig, useTheme, useThemeClass } from '../../_mixins' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import type { ThemeProps } from '../../_mixins' import { createKey } from '../../_utils' import type { ExtractPublicPropTypes } from '../../_utils' diff --git a/src/tag/src/Tag.tsx b/src/tag/src/Tag.tsx index 35f66680e..95b2401ee 100644 --- a/src/tag/src/Tag.tsx +++ b/src/tag/src/Tag.tsx @@ -9,7 +9,7 @@ import { provide, toRef } from 'vue' -import useRtl from '../../_mixins/use-rtl' +import { useRtl } from '../../_mixins/use-rtl' import { NBaseClose } from '../../_internal/close' import { useConfig, useThemeClass, useTheme } from '../../_mixins' import type { ThemeProps } from '../../_mixins'