Skip to content

Commit

Permalink
feat(button): add shine effect
Browse files Browse the repository at this point in the history
  • Loading branch information
azabroflovski committed Jan 5, 2025
1 parent 1e116fc commit dd10736
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 4 deletions.
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 to 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>
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

0 comments on commit dd10736

Please sign in to comment.