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(button): add shine effect #6683

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- `n-modal` adds `draggable` prop, closes [#6525](https://github.com/tusen-ai/naive-ui/issues/6525), [#5792](https://github.com/tusen-ai/naive-ui/issues/5792), [#5711](https://github.com/tusen-ai/naive-ui/issues/5711), [#5501](https://github.com/tusen-ai/naive-ui/issues/5501) and [#2152](https://github.com/tusen-ai/naive-ui/issues/2152).
- `useDialog` supports `draggable` option.
- `useModal` supports `draggable` option.
- `n-button` adds `shine` prop.

### Fixes

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- `n-modal` 新增 `draggable` 属性,关闭 [#6525](https://github.com/tusen-ai/naive-ui/issues/6525),[#5792](https://github.com/tusen-ai/naive-ui/issues/5792),[#5711](https://github.com/tusen-ai/naive-ui/issues/5711),[#5501](https://github.com/tusen-ai/naive-ui/issues/5501),[#2152](https://github.com/tusen-ai/naive-ui/issues/2152)
- `useDialog` 支持 `draggable` 参数
- `useModal` 支持 `draggable` 参数
- `n-button` 新增 `shine` 属性

### Fixes

Expand Down
2 changes: 2 additions & 0 deletions src/button/demos/enUS/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ events.vue
shape.vue
ghost.vue
loading.vue
shine.vue
color.vue
group.vue
icon-button.vue
Expand Down Expand Up @@ -50,6 +51,7 @@ popover.vue
| secondary | `boolean` | `false` | Whether the button is secondary button. | |
| size | `'tiny' \| 'small' \| 'medium' \| 'large'` | `'medium'` | Button size. | |
| strong | `boolean` | `false` | Whether to use strong text in the button. | |
| shine | `boolean` | `false` | Enable shine effect in the button. | |
| tertiary | `boolean` | `false` | Whether the button is tertiary button. | |
| text | `boolean` | `false` | Whether to display as a text button. | |
| text-color | `string` | `undefined` | Button text color (support `#FFF`, `#FFFFFF`, `yellow`,`rgb(0, 0, 0)` formatted colors). | |
Expand Down
35 changes: 35 additions & 0 deletions src/button/demos/enUS/shine.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<markdown>
# Shine effect

The button have a shining effect.
</markdown>

<template>
<div>
<n-button type="primary" size="large" shine>
Did I get your attention?
</n-button>
<p>
This effect is essential for
<n-text code>
CTA
</n-text> (call-to-action) elements that aim to drive
user engagement.
</p>
<n-h4>More examples</n-h4>
<n-space>
<n-button type="success" shine block>
Success
</n-button>
<n-button type="info" shine block>
Info
</n-button>
<n-button type="warning" block shine>
Warning
</n-button>
<n-button type="error" block shine>
Error
</n-button>
</n-space>
</div>
</template>
1 change: 1 addition & 0 deletions src/button/demos/zhCN/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ debug.vue
| size | `'tiny' \| 'small' \| 'medium' \| 'large'` | `'medium'` | 按钮的尺寸 | |
| secondary | `boolean` | `false` | 是否是次要按钮 | |
| strong | `boolean` | `false` | 按钮文字是否加粗 | |
| shine | `boolean` | `false` | Enable shine effect in the button. | |
| tertiary | `boolean` | `false` | 是否是三级按钮 | |
| text | `boolean` | `false` | 是否显示为文本按钮 | |
| text-color | `string` | `undefined` | 按钮文字颜色(支持形如 `#FFF`, `#FFFFFF`, `yellow`,`rgb(0, 0, 0)` 的颜色) | |
Expand Down
35 changes: 35 additions & 0 deletions src/button/demos/zhCN/shine.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<markdown>
# Shine effect

The button have a shining effect.
</markdown>

<template>
<div>
<n-button type="primary" size="large" shine>
Did I get your attention?
</n-button>
<p>
This effect is essential for
<n-text code>
CTA
</n-text> (call-to-action) elements that aim to drive
user engagement.
</p>
<n-h4>More examples</n-h4>
<n-space>
<n-button type="success" shine block>
Success
</n-button>
<n-button type="info" shine block>
Info
</n-button>
<n-button type="warning" block shine>
Warning
</n-button>
<n-button type="error" block shine>
Error
</n-button>
</n-space>
</div>
</template>
28 changes: 24 additions & 4 deletions src/button/src/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const buttonProps = {
secondary: Boolean,
tertiary: Boolean,
quaternary: Boolean,
shine: Boolean,
strong: Boolean,
focusable: {
type: Boolean,
Expand Down Expand Up @@ -459,6 +460,7 @@ const Button = defineComponent({
[createKey('iconSize', size)]: iconSize,
[createKey('borderRadius', size)]: borderRadius,
[createKey('iconMargin', size)]: iconMargin,
shineOpacity,
waveOpacity
} = self
const sizeProps = {
Expand Down Expand Up @@ -486,6 +488,7 @@ const Button = defineComponent({
'--n-ripple-duration': rippleDuration,
'--n-opacity-disabled': opacityDisabled,
'--n-wave-opacity': waveOpacity,
'--n-shine-opacity': shineOpacity,
...fontProps,
...colorProps,
...borderProps,
Expand All @@ -509,6 +512,7 @@ const Button = defineComponent({
secondary,
tertiary,
quaternary,
shine,
strong
} = props
if (dashed)
Expand All @@ -529,13 +533,15 @@ const Button = defineComponent({
hash += 'h'
if (strong)
hash += 'i'
if (shine)
hash += 'j'
if (color)
hash += `j${color2Class(color)}`
hash += `k${color2Class(color)}`
if (textColor)
hash += `k${color2Class(textColor)}`
hash += `l${color2Class(textColor)}`
const { value: size } = mergedSizeRef
hash += `l${size[0]}`
hash += `m${type[0]}`
hash += `m${size[0]}`
hash += `n${type[0]}`
return hash
}),
cssVarsRef,
Expand Down Expand Up @@ -595,6 +601,7 @@ const Button = defineComponent({
`${mergedClsPrefix}-button--${this.mergedSize}-type`,
this.rtlEnabled && `${mergedClsPrefix}-button--rtl`,
this.disabled && `${mergedClsPrefix}-button--disabled`,
this.shine && `${mergedClsPrefix}-button--shine`,
this.block && `${mergedClsPrefix}-button--block`,
this.enterPressed && `${mergedClsPrefix}-button--pressed`,
!this.text && this.dashed && `${mergedClsPrefix}-button--dashed`,
Expand Down Expand Up @@ -664,6 +671,19 @@ const Button = defineComponent({
style={this.customColorCssVars as CSSProperties}
/>
) : null}
{this.shine ? (
<div
aria-hidden
class={`${mergedClsPrefix}-button__shine`}
style={this.customColorCssVars as CSSProperties}
>
<div
aria-hidden
class={`${mergedClsPrefix}-button__shine-effect`}
style={this.customColorCssVars as CSSProperties}
/>
</div>
) : null}
{this.showBorder ? (
<div
aria-hidden
Expand Down
33 changes: 33 additions & 0 deletions src/button/src/styles/index.cssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { c, cB, cE, cM, cNotM } from '../../../_utils/cssr'
// --n-icon-size
// --n-icon-margin
// --n-wave-opacity
// --n-shine-opacity
// --n-font-weight
//
// private-vars:
Expand Down Expand Up @@ -183,6 +184,28 @@ export default c([
borderColor: '#0000',
zIndex: 1
}),
cE('shine', {
position: 'absolute',
top: '0',
right: '0',
bottom: '0',
left: '0',
overflow: 'hidden',
}),
cE('shine-effect', {
content: '',
position: 'absolute',
top: '0',
width: '100%',
height: '100%',
animation: 'shine 4s ease-out infinite',
background: `linear-gradient(
120deg,
transparent,
rgba(255, 255, 255, var(--n-shine-opacity)),
transparent
)`,
}),
cE('icon', `
margin: var(--n-icon-margin);
margin-left: 0;
Expand Down Expand Up @@ -238,6 +261,16 @@ export default c([
opacity: 'var(--n-opacity-disabled)'
})
]),
c('@keyframes shine', {
from: {
transform: 'translateX(-105%)',
transitionProperty: 'transform',
},
'15%, 100%': {
transform: 'translateX(105%)',
transitionProperty: 'transform'
},
}),
c('@keyframes button-wave-spread', {
from: {
boxShadow: '0 0 0.5px 0 var(--n-ripple-color)'
Expand Down
1 change: 1 addition & 0 deletions src/button/styles/dark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const buttonDark: ButtonTheme = {
self(vars) {
const commonSelf = self(vars)
commonSelf.waveOpacity = '0.8'
commonSelf.shineOpacity = '0.45'
commonSelf.colorOpacitySecondary = '0.16'
commonSelf.colorOpacitySecondaryHover = '0.2'
commonSelf.colorOpacitySecondaryPressed = '0.12'
Expand Down
1 change: 1 addition & 0 deletions src/button/styles/light.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ export function self(vars: ThemeCommonVars) {
borderDisabledError: `1px solid ${errorColor}`,
rippleColorError: errorColor,
waveOpacity: '0.6',
shineOpacity: '0.26',
fontWeight,
fontWeightStrong
}
Expand Down
Loading