Skip to content

Commit

Permalink
feat(float-button): new component (tusen-ai#5627)
Browse files Browse the repository at this point in the history
* feat: create template

* feat: add demo

* feat: change to css

* feat: add style

* feat: add demo

* feat: add demo

* feat: add group

* feat: add docs

* feat: add log

* fix: style error

* feat: add docs
  • Loading branch information
jahnli authored Jan 29, 2024
1 parent 2bf5229 commit da39759
Show file tree
Hide file tree
Showing 32 changed files with 1,041 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- `n-split` adds `size` prop and `on-update:size` prop.
- `n-split` adds `watch-props` prop, closes [#5526](https://github.com/tusen-ai/naive-ui/issues/5526).
- `n-drawer` adds `borderRadius` theme variable.
- adds `n-float-button` component.

### i18n

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- `n-split` 新增 `size` 和 `on-update:size` 属性
- `n-split` 新增 `watch-props` 属性,关闭 [#5526](https://github.com/tusen-ai/naive-ui/issues/5526)
- `n-drawer` 新增 `borderRadius` 主题变量
- 新增 `n-float-button` 组件

### i18n

Expand Down
10 changes: 10 additions & 0 deletions demo/routes/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,11 @@ export const enComponentRoutes = [
{
path: 'split',
component: () => import('../../src/split/demos/enUS/index.demo-entry.md')
},
{
path: 'float-button',
component: () =>
import('../../src/float-button/demos/enUS/index.demo-entry.md')
}
]

Expand Down Expand Up @@ -945,6 +950,11 @@ export const zhComponentRoutes = [
{
path: 'split',
component: () => import('../../src/split/demos/zhCN/index.demo-entry.md')
},
{
path: 'float-button',
component: () =>
import('../../src/float-button/demos/zhCN/index.demo-entry.md')
}
]

Expand Down
7 changes: 7 additions & 0 deletions demo/store/menu-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,13 @@ export function createComponentMenuOptions ({ lang, theme, mode }) {
zh: '水印',
enSuffix: true,
path: '/watermark'
},
{
en: 'Float Button',
zh: '浮动按钮',
enSuffix: true,
path: '/float-button',
isNew: true
}
]
}),
Expand Down
2 changes: 2 additions & 0 deletions src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export * from './ellipsis'
export * from './empty'
export * from './flex'
export * from './form'
export * from './float-button'
export * from './float-button-group'
export * from './global-style'
export * from './gradient-text'
export * from './grid'
Expand Down
4 changes: 4 additions & 0 deletions src/config-provider/src/internal-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import type { EllipsisTheme } from '../../ellipsis/styles'
import type { EmptyTheme } from '../../empty/styles'
import type { EquationTheme } from '../../equation/styles'
import type { FormTheme } from '../../form/styles'
import type { FloatButtonTheme } from '../../float-button/styles'
import type { GradientTextTheme } from '../../gradient-text/styles'
import type { IconTheme } from '../../icon/styles'
import type { IconWrapperTheme } from '../../icon-wrapper/styles'
Expand Down Expand Up @@ -100,6 +101,7 @@ import type { RowTheme } from '../../legacy-grid/styles'
import type { Katex } from './katex'
import type { SplitTheme } from '../../split/styles'
import type { FlexTheme } from '../../flex/styles'
import type { FloatButtonGroupTheme } from '../../float-button-group/styles'

export interface GlobalThemeWithoutCommon {
Alert?: AlertTheme
Expand Down Expand Up @@ -136,6 +138,8 @@ export interface GlobalThemeWithoutCommon {
Equation?: EquationTheme
Flex?: FlexTheme
Form?: FormTheme
FloatButton?: FloatButtonTheme
FloatButtonGroup?: FloatButtonGroupTheme
GradientText?: GradientTextTheme
Icon?: IconTheme
IconWrapper?: IconWrapperTheme
Expand Down
5 changes: 5 additions & 0 deletions src/float-button-group/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export {
default as NFloatButtonGroup,
floatButtonGroupProps
} from './src/FloatButtonGroup'
export type { FloatButtonGroupProps } from './src/FloatButtonGroup'
124 changes: 124 additions & 0 deletions src/float-button-group/src/FloatButtonGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import {
h,
type PropType,
defineComponent,
computed,
type CSSProperties
} from 'vue'
import type { Size } from '../../button/src/interface'
import { type ThemeProps, useConfig, useTheme } from '../../_mixins'
import type { ExtractPublicPropTypes } from '../../_utils'
import style from './styles/index.cssr'
import floatButtonGroupLight, {
type FloatButtonGroupTheme
} from '../styles/light'

export interface ButtonGroupInjection {
size?: Size | undefined
}

export const floatButtonGroupProps = {
...(useTheme.props as ThemeProps<FloatButtonGroupTheme>),
width: {
type: [Number, String] as PropType<string | number>,
default: 'auto'
},
height: {
type: [Number, String] as PropType<string | number>,
default: 'auto'
},
left: {
type: [Number, String] as PropType<string | number>,
default: undefined
},
right: {
type: [Number, String] as PropType<string | number>,
default: 40
},
top: {
type: [Number, String] as PropType<string | number>,
default: undefined
},
bottom: {
type: [Number, String] as PropType<string | number>,
default: 40
},
radius: {
type: [Number, String] as PropType<string | number>,
default: 22
},
backgroundColor: String,
vertical: Boolean
} as const

export type FloatButtonGroupProps = ExtractPublicPropTypes<
typeof floatButtonGroupProps
>

export default defineComponent({
name: 'FloatButtonGroup',
props: floatButtonGroupProps,
setup (props) {
const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props)

const themeRef = useTheme(
'FloatButtonGroup',
'-float-button-group',
style,
floatButtonGroupLight,
props,
mergedClsPrefixRef
)

const cssVarsRef = computed(() => {
const {
self: { color, textColor, boxShadow, boxShadowHover, boxShadowPressed },
common: { cubicBezierEaseInOut }
} = themeRef.value
return {
'--n-bezier': cubicBezierEaseInOut,
'--n-box-shadow': boxShadow,
'--n-box-shadow-hover': boxShadowHover,
'--n-box-shadow-pressed': boxShadowPressed,
'--n-color': color,
'--n-text-color': textColor,
left: formatNumber(props.left),
right: formatNumber(props.right),
top: formatNumber(props.top),
bottom: formatNumber(props.bottom),
width: formatNumber(props.width),
height: formatNumber(props.height),
borderRadius: formatNumber(props.radius),
backgroundColor: props.backgroundColor
}
})

const formatNumber = (
value: number | string | undefined
): string | undefined => {
if (typeof value === 'number') return `${value}px`
return value
}

return {
cssVars: inlineThemeDisabled ? undefined : cssVarsRef,
mergedClsPrefix: mergedClsPrefixRef,
formatNumber
}
},
render () {
const { mergedClsPrefix, cssVars } = this
return (
<div
class={[
`${mergedClsPrefix}-float-button-group`,
this.vertical && `${mergedClsPrefix}-float-button-group--vertical`
]}
style={cssVars as CSSProperties}
role="group"
>
{this.$slots}
</div>
)
}
})
24 changes: 24 additions & 0 deletions src/float-button-group/src/styles/index.cssr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { cB, cM, cNotM } from '../../../_utils/cssr/index'

export default cB('float-button-group', `
position: fixed;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: var(--n-text-color);
transition:
color .3s var(--n-bezier),
box-shadow .3s var(--n-bezier),
background-color .3s var(--n-bezier);
`, [
cNotM('vertical', {
flexDirection: 'row'
}, [

]),
cM('vertical', {
flexDirection: 'column'
}, [
])
])
19 changes: 19 additions & 0 deletions src/float-button-group/styles/dark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { commonDark } from '../../_styles/common'
import type { FloatButtonGroupTheme } from './light'

const floatButtonGroupDark: FloatButtonGroupTheme = {
name: 'FloatButtonGroup',
common: commonDark,
self (vars) {
const { popoverColor, textColor2 } = vars
return {
color: popoverColor,
textColor: textColor2,
boxShadow: '0 2px 8px 0px rgba(0, 0, 0, .12)',
boxShadowHover: '0 2px 12px 0px rgba(0, 0, 0, .18)',
boxShadowPressed: '0 2px 12px 0px rgba(0, 0, 0, .18)'
}
}
}

export default floatButtonGroupDark
3 changes: 3 additions & 0 deletions src/float-button-group/styles/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as floatButtonGroupDark } from './dark'
export { default as floatButtonGroupLight } from './light'
export type { FloatButtonGroupTheme } from './light'
25 changes: 25 additions & 0 deletions src/float-button-group/styles/light.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { type Theme } from '../../_mixins'
import { type ThemeCommonVars } from '../../config-provider'
import { commonLight } from '../../styles'

const self = (vars: ThemeCommonVars) => {
const { popoverColor, textColor2 } = vars
return {
color: popoverColor,
textColor: textColor2,
boxShadow: '0 2px 8px 0px rgba(0, 0, 0, .12)',
boxShadowHover: '0 2px 12px 0px rgba(0, 0, 0, .18)',
boxShadowPressed: '0 2px 12px 0px rgba(0, 0, 0, .18)'
}
}

export type FloatButtonGroupThemeVars = ReturnType<typeof self>

const themeLight: Theme<'FloatButtonGroup', FloatButtonGroupThemeVars> = {
name: 'FloatButtonGroup',
common: commonLight,
self
}

export default themeLight
export type FloatButtonGroupTheme = typeof themeLight
64 changes: 64 additions & 0 deletions src/float-button/demos/enUS/badge.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<markdown>
# Badge

You can put a hover button with the number of badges on any element.

</markdown>

<template>
<div style="height: 200px; transform: translate(0)">
<n-float-button :right="0" :bottom="0">
<n-badge :value="9" :offset="[6, -8]">
<n-icon :size="22" color="grey">
<alarm-outline-icon />
</n-icon>
</n-badge>
</n-float-button>
<n-float-button :right="70" :bottom="0">
<n-badge :value="100" :max="99" :offset="[6, -8]">
<n-icon :size="22" color="grey">
<alarm-outline-icon />
</n-icon>
</n-badge>
</n-float-button>
<n-float-button :right="142" :bottom="0">
<n-badge dot :offset="[4, -4]">
<n-icon :size="22" color="grey">
<alarm-outline-icon />
</n-icon>
</n-badge>
</n-float-button>
<n-float-button :right="142" :bottom="0">
<n-badge dot :offset="[4, -4]">
<n-icon :size="22" color="grey">
<alarm-outline-icon />
</n-icon>
</n-badge>
</n-float-button>
<n-float-button :right="0" :bottom="60">
<n-badge value="New" :offset="[10, -10]">
<n-icon :size="22" color="grey">
<alarm-outline-icon />
</n-icon>
</n-badge>
</n-float-button>
<n-float-button :right="70" :bottom="60">
<n-badge :value="9" :offset="[6, -8]" color="grey">
<n-icon :size="22" color="grey">
<alarm-outline-icon />
</n-icon>
</n-badge>
</n-float-button>
</div>
</template>

<script lang="ts">
import { AlarmOutline as AlarmOutlineIcon } from '@vicons/ionicons5'
import { defineComponent } from 'vue'
export default defineComponent({
components: {
AlarmOutlineIcon
}
})
</script>
39 changes: 39 additions & 0 deletions src/float-button/demos/enUS/basic.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<markdown>
# Basic
</markdown>

<template>
<div style="height: 200px; transform: translate(0)">
<n-float-button :right="0" :bottom="0">
<n-icon :size="24">
<cash-icon />
</n-icon>
</n-float-button>
<n-float-button :left="0" :bottom="0">
<n-icon :size="24">
<cash-icon />
</n-icon>
</n-float-button>
<n-float-button :right="0" :top="0">
<n-icon :size="24">
<cash-icon />
</n-icon>
</n-float-button>
<n-float-button :left="0" :top="0">
<n-icon :size="24">
<cash-icon />
</n-icon>
</n-float-button>
</div>
</template>

<script lang="ts">
import { CashOutline as CashIcon } from '@vicons/ionicons5'
import { defineComponent } from 'vue'
export default defineComponent({
components: {
CashIcon
}
})
</script>
Loading

0 comments on commit da39759

Please sign in to comment.