mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-30 12:52:43 +08:00
refactor(alert): composition + new theme
This commit is contained in:
parent
66a2fa2353
commit
7f4f28c43c
@ -39,7 +39,11 @@ export default function useTheme (
|
||||
const {
|
||||
mergedUnstableTheme: {
|
||||
common: injectedGlobalCommon,
|
||||
[resolveId]: { injectedCommon, injectedSelf, injectedPeers = {} } = {}
|
||||
[resolveId]: {
|
||||
common: injectedCommon,
|
||||
self: injectedSelf,
|
||||
peers: injectedPeers = {}
|
||||
} = {}
|
||||
} = {},
|
||||
mergedUnstableThemeOverrides: {
|
||||
common: injectedGlobalCommonOverrides,
|
||||
@ -60,13 +64,14 @@ export default function useTheme (
|
||||
injectedCommonOverrides,
|
||||
commonOverrides
|
||||
)
|
||||
const mergedSelf = merge(
|
||||
(self || injectedSelf || defaultTheme.self || {})(mergedCommon),
|
||||
injectedSelfOverrides,
|
||||
selfOverrides
|
||||
)
|
||||
return {
|
||||
common: mergedCommon,
|
||||
self: merge(
|
||||
(self || injectedSelf || defaultTheme.self || {})(mergedCommon),
|
||||
injectedSelfOverrides,
|
||||
selfOverrides
|
||||
),
|
||||
self: mergedSelf,
|
||||
peersTheme: merge(peers, injectedPeers),
|
||||
peersOverride: merge(peersOverrides, injectedPeersOverrides)
|
||||
}
|
||||
|
@ -9,4 +9,5 @@ export {
|
||||
} from './vue'
|
||||
export { warn, warnOnce } from './naive'
|
||||
export { formatLength } from './css'
|
||||
export { createKey } from './cssr'
|
||||
export * from './composable'
|
||||
|
@ -5,12 +5,9 @@
|
||||
class="n-alert"
|
||||
:class="{
|
||||
[`n-alert--${type}-type`]: true,
|
||||
'n-alert--no-icon': showIcon === false,
|
||||
[`n-${mergedTheme}-theme`]: mergedTheme
|
||||
}"
|
||||
:style="{
|
||||
...mergedStyle
|
||||
'n-alert--no-icon': showIcon === false
|
||||
}"
|
||||
:style="cssVars"
|
||||
>
|
||||
<div v-if="closable" class="n-alert__close" @click="handleCloseClick">
|
||||
<n-icon>
|
||||
@ -49,11 +46,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, computed } from 'vue'
|
||||
import { NIcon } from '../../icon'
|
||||
import { NFadeInExpandTransition } from '../../_base'
|
||||
import { configurable, themeable, withCssr } from '../../_mixins'
|
||||
import { warn } from '../../_utils'
|
||||
import styles from './styles'
|
||||
import { useTheme } from '../../_mixins'
|
||||
import { warn, createKey } from '../../_utils'
|
||||
import { alertLight } from '../styles'
|
||||
import style from './styles/index.cssr'
|
||||
|
||||
// icons
|
||||
import {
|
||||
@ -75,8 +74,15 @@ export default {
|
||||
ErrorIcon,
|
||||
CloseIcon
|
||||
},
|
||||
mixins: [configurable, themeable, withCssr(styles)],
|
||||
props: {
|
||||
unstableTheme: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
unstableThemeOverrides: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: undefined
|
||||
@ -116,28 +122,61 @@ export default {
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
visible: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doAfterLeave () {
|
||||
setup (props) {
|
||||
const themeRef = useTheme('Alert', 'Alert', style, alertLight, props)
|
||||
const cssVars = computed(() => {
|
||||
const {
|
||||
common: { cubicBezierEaseInOut },
|
||||
self
|
||||
} = themeRef.value
|
||||
const {
|
||||
fontSize,
|
||||
borderRadius,
|
||||
titleFontWeight,
|
||||
lineHeight,
|
||||
contentTextColor,
|
||||
titleTextColor
|
||||
} = self
|
||||
const { type } = props
|
||||
return {
|
||||
'--bezier': cubicBezierEaseInOut,
|
||||
'--color': self[createKey('color', type)],
|
||||
'--close-color': self[createKey('closeColor', type)],
|
||||
'--close-color-hover': self[createKey('closeColorHover', type)],
|
||||
'--close-color-pressed': self[createKey('closeColorPressed', type)],
|
||||
'--icon-color': self[createKey('iconColor', type)],
|
||||
'--border': self[createKey('border', type)],
|
||||
'--title-text-color': titleTextColor,
|
||||
'--content-text-color': contentTextColor,
|
||||
'--line-height': lineHeight,
|
||||
'--border-radius': borderRadius,
|
||||
'--font-size': fontSize,
|
||||
'--title-font-weight': titleFontWeight
|
||||
}
|
||||
})
|
||||
const visibleRef = ref(true)
|
||||
const doAfterLeave = () => {
|
||||
const {
|
||||
onAfterLeave,
|
||||
onAfterHide // deprecated
|
||||
} = this
|
||||
} = props
|
||||
if (onAfterLeave) onAfterLeave()
|
||||
if (onAfterHide) onAfterHide()
|
||||
},
|
||||
handleCloseClick () {
|
||||
Promise.resolve(this.onClose()).then((result) => {
|
||||
}
|
||||
const handleCloseClick = () => {
|
||||
Promise.resolve(props.onClose()).then((result) => {
|
||||
if (result === false) return
|
||||
this.visible = false
|
||||
visibleRef.value = false
|
||||
})
|
||||
},
|
||||
handleAfterLeave () {
|
||||
this.doAfterLeave()
|
||||
}
|
||||
const handleAfterLeave = () => {
|
||||
doAfterLeave()
|
||||
}
|
||||
return {
|
||||
visible: visibleRef,
|
||||
handleCloseClick,
|
||||
handleAfterLeave,
|
||||
cssVars
|
||||
}
|
||||
}
|
||||
}
|
||||
|
115
src/alert/src/styles/index.cssr.js
Normal file
115
src/alert/src/styles/index.cssr.js
Normal file
@ -0,0 +1,115 @@
|
||||
import { c, cB, cE, cM } from '../../../_utils/cssr'
|
||||
import fadeInHeightExpandTranstion from '../../../_styles/transitions/fade-in-height-expand'
|
||||
|
||||
// vars:
|
||||
// --bezier
|
||||
// --color
|
||||
// --close-color
|
||||
// --close-color-hover
|
||||
// --close-color-pressed
|
||||
// --icon-color
|
||||
// --border
|
||||
// --title-text-color
|
||||
// --content-text-color
|
||||
// --line-height
|
||||
// --border-radius
|
||||
// --font-size
|
||||
// --title-font-weight
|
||||
export default cB('alert', {
|
||||
lineHeight: 'var(--line-height)',
|
||||
borderRadius: 'var(--border-radius)',
|
||||
position: 'relative',
|
||||
transition: 'background-color .3s var(--bezier)',
|
||||
backgroundColor: 'var(--color)',
|
||||
textAlign: 'start'
|
||||
}, [
|
||||
cE('close', {
|
||||
color: 'var(--close-color)'
|
||||
}, [
|
||||
c('&:hover', {
|
||||
color: 'var(--close-color-hover)'
|
||||
}),
|
||||
c('&:active', {
|
||||
color: 'var(--close-color-pressed)'
|
||||
})
|
||||
]),
|
||||
cE('icon', {
|
||||
color: 'var(--icon-color)'
|
||||
}),
|
||||
cB('alert-body', {
|
||||
border: 'var(--border)'
|
||||
}, [
|
||||
cE('title', {
|
||||
color: 'var(--title-text-color)'
|
||||
}),
|
||||
cE('content', {
|
||||
color: 'var(--content-text-color)'
|
||||
})
|
||||
]),
|
||||
fadeInHeightExpandTranstion({
|
||||
originalTransition: 'transform .3s var(--bezier)',
|
||||
enterToProps: {
|
||||
transform: 'scale(1)'
|
||||
},
|
||||
leaveToProps: {
|
||||
transform: 'scale(0.9)'
|
||||
}
|
||||
}),
|
||||
cE('icon', `
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 14px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
`, [
|
||||
cB('icon', {
|
||||
fontSize: '26px'
|
||||
})
|
||||
]),
|
||||
cE('close', `
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
font-size: 14px;
|
||||
top: 14px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
line-height: 0;
|
||||
transition: color .3s var(--bezier);
|
||||
`, [
|
||||
cB('icon', {
|
||||
cursor: 'pointer'
|
||||
})
|
||||
]),
|
||||
cB('alert-body', {
|
||||
borderRadius: 'var(--border-radius)',
|
||||
padding: '15px 15px 15px 47px',
|
||||
transition: 'border-color .3s var(--bezier)'
|
||||
}, [
|
||||
cE('title', {
|
||||
transition: 'color .3s var(--bezier)',
|
||||
fontSize: '16px',
|
||||
lineHeight: '19px',
|
||||
fontWeight: 'var(--title-font-weight)'
|
||||
}, [
|
||||
c('& +', [
|
||||
cE('content', {
|
||||
marginTop: '9px'
|
||||
})
|
||||
])
|
||||
]),
|
||||
cE('content', {
|
||||
transition: 'color .3s var(--bezier)',
|
||||
fontSize: 'var(--font-size)'
|
||||
})
|
||||
]),
|
||||
cE('icon', {
|
||||
transition: 'color .3s var(--bezier)'
|
||||
}),
|
||||
cM('no-icon', [
|
||||
cB('alert-body', {
|
||||
paddingLeft: '19px'
|
||||
})
|
||||
])
|
||||
])
|
@ -1,9 +0,0 @@
|
||||
import themedBaseStyle from './themed-base.cssr.js'
|
||||
|
||||
export default [
|
||||
{
|
||||
key: 'mergedTheme',
|
||||
watch: ['mergedTheme'],
|
||||
CNode: themedBaseStyle
|
||||
}
|
||||
]
|
@ -1,117 +0,0 @@
|
||||
import { c, cTB, cB, cE, cM, createKey } from '../../../_utils/cssr'
|
||||
import fadeInHeightExpandTranstion from '../../../_styles/transitions/fade-in-height-expand'
|
||||
|
||||
export default c([
|
||||
({ props }) => {
|
||||
const {
|
||||
$global: { cubicBezierEaseInOut },
|
||||
$local
|
||||
} = props
|
||||
const { borderRadius, titleFontWeight, lineHeight, fontSize } = $local
|
||||
return cTB('alert', {
|
||||
lineHeight,
|
||||
borderRadius,
|
||||
position: 'relative',
|
||||
transition: `background-color .3s ${cubicBezierEaseInOut}`
|
||||
}, [
|
||||
['default', 'info', 'success', 'warning', 'error'].map(type => cM(type + '-type', {
|
||||
backgroundColor: $local[createKey('color', type)],
|
||||
textAlign: 'start'
|
||||
}, [
|
||||
cE('close', {
|
||||
color: $local[createKey('closeColor', type)]
|
||||
}, [
|
||||
c('&:hover', {
|
||||
color: $local[createKey('closeColorHover', type)]
|
||||
}),
|
||||
c('&:active', {
|
||||
color: $local[createKey('closeColorPressed', type)]
|
||||
})
|
||||
]),
|
||||
cE('icon', {
|
||||
color: $local[createKey('iconColor', type)]
|
||||
}),
|
||||
cB('alert-body', {
|
||||
border: $local[createKey('border', type)]
|
||||
}, [
|
||||
cE('title', {
|
||||
color: $local[createKey('titleTextColor', type)]
|
||||
}),
|
||||
cE('content', {
|
||||
color: $local[createKey('contentTextColor', type)]
|
||||
})
|
||||
])
|
||||
])),
|
||||
fadeInHeightExpandTranstion({
|
||||
originalTransition: `transform .3s ${cubicBezierEaseInOut}`,
|
||||
enterToProps: {
|
||||
transform: 'scale(1)'
|
||||
},
|
||||
leaveToProps: {
|
||||
transform: 'scale(0.9)'
|
||||
}
|
||||
}),
|
||||
cE('icon', {
|
||||
raw: `
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 14px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
`
|
||||
}, [
|
||||
cB('icon', {
|
||||
fontSize: '26px'
|
||||
})
|
||||
]),
|
||||
cE('close', {
|
||||
raw: `
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
font-size: 14px;
|
||||
top: 14px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
line-height: 0;
|
||||
transition: color .3s ${cubicBezierEaseInOut};
|
||||
`
|
||||
}, [
|
||||
cB('icon', {
|
||||
cursor: 'pointer'
|
||||
})
|
||||
]),
|
||||
cB('alert-body', {
|
||||
borderRadius,
|
||||
padding: '15px 15px 15px 47px',
|
||||
transition: `border-color .3s ${cubicBezierEaseInOut}`
|
||||
}, [
|
||||
cE('title', {
|
||||
transition: `color .3s ${cubicBezierEaseInOut}`,
|
||||
fontSize: '16px',
|
||||
lineHeight: '19px',
|
||||
fontWeight: titleFontWeight
|
||||
}, [
|
||||
c('& +', [
|
||||
cE('content', {
|
||||
marginTop: '9px'
|
||||
})
|
||||
])
|
||||
]),
|
||||
cE('content', {
|
||||
transition: `color .3s ${cubicBezierEaseInOut}`,
|
||||
fontSize
|
||||
})
|
||||
]),
|
||||
cE('icon', {
|
||||
transition: `color .3s ${cubicBezierEaseInOut}`
|
||||
}),
|
||||
cM('no-icon', [
|
||||
cB('alert-body', {
|
||||
paddingLeft: '19px'
|
||||
})
|
||||
])
|
||||
])
|
||||
}
|
||||
])
|
@ -1,13 +1,9 @@
|
||||
import create from '../../_styles/utils/create-component-base'
|
||||
import { baseDark } from '../../_styles/base'
|
||||
import { iconDark } from '../../icon/styles'
|
||||
import { changeColor } from 'seemly'
|
||||
import { commonDark } from '../../_styles/new-common'
|
||||
|
||||
export default create({
|
||||
theme: 'dark',
|
||||
name: 'Alert',
|
||||
peer: [baseDark, iconDark],
|
||||
getLocalVars (vars) {
|
||||
export default {
|
||||
common: commonDark,
|
||||
self (vars) {
|
||||
const {
|
||||
lineHeight,
|
||||
borderRadius,
|
||||
@ -76,4 +72,4 @@ export default create({
|
||||
closeColorPressedError: closeColorPressedOverlay
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,13 +1,9 @@
|
||||
import create from '../../_styles/utils/create-component-base'
|
||||
import { baseLight } from '../../_styles/base'
|
||||
import { iconLight } from '../../icon/styles'
|
||||
import { composite, changeColor } from 'seemly'
|
||||
import { changeColor, composite } from 'seemly'
|
||||
import { commonLight } from '../../_styles/new-common'
|
||||
|
||||
export default create({
|
||||
theme: 'light',
|
||||
name: 'Alert',
|
||||
peer: [baseLight, iconLight],
|
||||
getLocalVars (vars) {
|
||||
export default {
|
||||
common: commonLight,
|
||||
self (vars) {
|
||||
const {
|
||||
lineHeight,
|
||||
borderRadius,
|
||||
@ -94,4 +90,4 @@ export default create({
|
||||
closeColorPressedError: closeColorPressed
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ export { baseWaveDark, baseWaveLight } from './_base/wave/styles'
|
||||
// exposed style
|
||||
export { baseDark, baseLight } from './_styles/base'
|
||||
// export { affixDark, affixLight } from './affix/styles'
|
||||
export { alertDark, alertLight } from './alert/styles'
|
||||
// export { alertDark, alertLight } from './alert/styles'
|
||||
export { anchorDark, anchorLight } from './anchor/styles'
|
||||
export { autoCompleteDark, autoCompleteLight } from './auto-complete/styles'
|
||||
export { avatarDark, avatarLight } from './avatar/styles'
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { commonDark } from './_styles/new-common'
|
||||
import { dividerDark } from './divider/styles'
|
||||
import { alertDark } from './alert/styles'
|
||||
import { affixDark } from './affix/styles'
|
||||
|
||||
export const darkTheme = {
|
||||
common: commonDark,
|
||||
Affix: affixDark,
|
||||
Alert: alertDark,
|
||||
Divider: dividerDark
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user