mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-02-17 13:20:52 +08:00
feat(loading-bar): clsPrefix
This commit is contained in:
parent
c67ac4690c
commit
9b12b11a5b
@ -12,7 +12,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, inject } from 'vue'
|
||||
import { onMounted } from 'vue'
|
||||
import { useLoadingBar } from 'naive-ui'
|
||||
import SiteHeader from './SiteHeader.vue'
|
||||
import { loadingBarApiRef } from './routes/router'
|
||||
import { useIsXs } from './utils/composables'
|
||||
@ -23,7 +24,7 @@ export default {
|
||||
SiteHeader
|
||||
},
|
||||
setup () {
|
||||
const loadingBar = inject('loadingBar')
|
||||
const loadingBar = useLoadingBar()
|
||||
const isXsRef = useIsXs()
|
||||
onMounted(() => {
|
||||
loadingBarApiRef.value = loadingBar
|
||||
|
@ -1,3 +1,6 @@
|
||||
/* istanbul ignore file */
|
||||
export { default as NLoadingBarProvider } from './src/LoadingBarProvider'
|
||||
export type {
|
||||
LoadingBarProviderInst,
|
||||
LoadingBarProviderProps
|
||||
} from './src/LoadingBarProvider'
|
||||
export { useLoadingBar } from './src/use-loading-bar'
|
||||
|
@ -10,22 +10,26 @@ import {
|
||||
ref,
|
||||
nextTick
|
||||
} from 'vue'
|
||||
import { ThemePropsReactive, useTheme } from '../../_mixins'
|
||||
import { useTheme } from '../../_mixins'
|
||||
import { loadingBarLight } from '../styles'
|
||||
import type { LoadingBarTheme } from '../styles'
|
||||
import { loadingBarProviderInjectionKey } from './LoadingBarProvider'
|
||||
import style from './styles/index.cssr'
|
||||
|
||||
function createClassName (status: 'error' | 'finishing' | 'starting'): string {
|
||||
return `n-loading-bar n-loading-bar--${status}`
|
||||
function createClassName (
|
||||
status: 'error' | 'finishing' | 'starting',
|
||||
clsPrefix: string
|
||||
): string {
|
||||
return `${clsPrefix}-loading-bar ${clsPrefix}-loading-bar--${status}`
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LoadingBar',
|
||||
setup () {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const loadingBarProps = inject<ThemePropsReactive<LoadingBarTheme>>(
|
||||
'NLoadingBarProps'
|
||||
)!
|
||||
const {
|
||||
props: providerProps,
|
||||
cPrefixRef
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
} = inject(loadingBarProviderInjectionKey)!
|
||||
const loadingBarRef = ref<HTMLElement | null>(null)
|
||||
const enteringRef = ref(false)
|
||||
const loadingRef = ref(false)
|
||||
@ -51,7 +55,7 @@ export default defineComponent({
|
||||
el.style.maxWidth = `${fromProgress}%`
|
||||
el.style.transition = 'none'
|
||||
void el.offsetWidth
|
||||
el.className = createClassName(status)
|
||||
el.className = createClassName(status, cPrefixRef.value)
|
||||
el.style.transition = ''
|
||||
el.style.maxWidth = `${toProgress}%`
|
||||
}
|
||||
@ -62,7 +66,7 @@ export default defineComponent({
|
||||
finishing = true
|
||||
const el = loadingBarRef.value
|
||||
if (!el) return
|
||||
el.className = createClassName('finishing')
|
||||
el.className = createClassName('finishing', cPrefixRef.value)
|
||||
void el.offsetWidth
|
||||
loadingRef.value = false
|
||||
})
|
||||
@ -70,7 +74,7 @@ export default defineComponent({
|
||||
finishing = true
|
||||
const el = loadingBarRef.value
|
||||
if (!el) return
|
||||
el.className = createClassName('finishing')
|
||||
el.className = createClassName('finishing', cPrefixRef.value)
|
||||
el.style.maxWidth = '100%'
|
||||
void el.offsetWidth
|
||||
loadingRef.value = false
|
||||
@ -83,7 +87,7 @@ export default defineComponent({
|
||||
erroring = true
|
||||
const el = loadingBarRef.value
|
||||
if (!el) return
|
||||
el.className = createClassName('error')
|
||||
el.className = createClassName('error', cPrefixRef.value)
|
||||
void el.offsetWidth
|
||||
loadingRef.value = false
|
||||
})
|
||||
@ -91,7 +95,7 @@ export default defineComponent({
|
||||
erroring = true
|
||||
const el = loadingBarRef.value
|
||||
if (!el) return
|
||||
el.className = createClassName('error')
|
||||
el.className = createClassName('error', cPrefixRef.value)
|
||||
el.style.maxWidth = '100%'
|
||||
void el.offsetWidth
|
||||
loadingRef.value = false
|
||||
@ -111,9 +115,11 @@ export default defineComponent({
|
||||
'LoadingBar',
|
||||
style,
|
||||
loadingBarLight,
|
||||
loadingBarProps
|
||||
providerProps,
|
||||
cPrefixRef
|
||||
)
|
||||
return {
|
||||
cPrefix: cPrefixRef,
|
||||
loadingBarRef,
|
||||
loading: loadingRef,
|
||||
entering: enteringRef,
|
||||
@ -136,6 +142,7 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { cPrefix } = this
|
||||
return (
|
||||
<Transition
|
||||
name="n-fade-in-transition"
|
||||
@ -152,10 +159,10 @@ export default defineComponent({
|
||||
{{
|
||||
default: () =>
|
||||
withDirectives(
|
||||
<div class="n-loading-bar-container">
|
||||
<div class={`${cPrefix}-loading-bar-container`}>
|
||||
<div
|
||||
ref="loadingBarRef"
|
||||
class="n-loading-bar"
|
||||
class={`${cPrefix}-loading-bar`}
|
||||
style={this.cssVars as CSSProperties}
|
||||
/>
|
||||
</div>,
|
||||
|
@ -1,84 +0,0 @@
|
||||
import {
|
||||
Fragment,
|
||||
h,
|
||||
ref,
|
||||
Teleport,
|
||||
defineComponent,
|
||||
provide,
|
||||
nextTick,
|
||||
PropType
|
||||
} from 'vue'
|
||||
import { useIsMounted } from 'vooks'
|
||||
import { ThemePropsReactive, useTheme } from '../../_mixins'
|
||||
import type { ThemeProps } from '../../_mixins'
|
||||
import NLoadingBar from './LoadingBar'
|
||||
import type { LoadingBarTheme } from '../styles'
|
||||
import { LoadingBarApiInjection } from './interface'
|
||||
|
||||
interface LoadingBarRef {
|
||||
start: () => void
|
||||
error: () => void
|
||||
finish: () => void
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LoadingBarProvider',
|
||||
props: {
|
||||
...(useTheme.props as ThemeProps<LoadingBarTheme>),
|
||||
to: {
|
||||
type: [String, Object] as PropType<string | HTMLElement>,
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
setup (props, { slots }) {
|
||||
const isMountedRef = useIsMounted()
|
||||
const loadingBarRef = ref<LoadingBarRef | null>(null)
|
||||
const methods = {
|
||||
start () {
|
||||
if (isMountedRef.value) {
|
||||
loadingBarRef.value?.start()
|
||||
} else {
|
||||
void nextTick(() => {
|
||||
loadingBarRef.value?.start()
|
||||
})
|
||||
}
|
||||
},
|
||||
error () {
|
||||
if (isMountedRef.value) {
|
||||
loadingBarRef.value?.error()
|
||||
} else {
|
||||
void nextTick(() => {
|
||||
loadingBarRef.value?.error()
|
||||
})
|
||||
}
|
||||
},
|
||||
finish () {
|
||||
if (isMountedRef.value) {
|
||||
loadingBarRef.value?.finish()
|
||||
} else {
|
||||
void nextTick(() => {
|
||||
loadingBarRef.value?.finish()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
provide<LoadingBarApiInjection>('loadingBar', methods)
|
||||
provide<ThemePropsReactive<LoadingBarTheme>>('NLoadingBarProps', props)
|
||||
return () => {
|
||||
return h(Fragment, null, [
|
||||
h(
|
||||
Teleport,
|
||||
{
|
||||
to: props.to ?? 'body'
|
||||
},
|
||||
[
|
||||
h(NLoadingBar, {
|
||||
ref: loadingBarRef
|
||||
})
|
||||
]
|
||||
),
|
||||
slots.default?.()
|
||||
])
|
||||
}
|
||||
}
|
||||
})
|
111
src/loading-bar/src/LoadingBarProvider.tsx
Normal file
111
src/loading-bar/src/LoadingBarProvider.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
import {
|
||||
Fragment,
|
||||
h,
|
||||
ref,
|
||||
Teleport,
|
||||
defineComponent,
|
||||
provide,
|
||||
nextTick,
|
||||
PropType,
|
||||
ExtractPropTypes,
|
||||
InjectionKey,
|
||||
renderSlot,
|
||||
Ref
|
||||
} from 'vue'
|
||||
import { useIsMounted } from 'vooks'
|
||||
import { useConfig, useTheme } from '../../_mixins'
|
||||
import type { ThemeProps } from '../../_mixins'
|
||||
import NLoadingBar from './LoadingBar'
|
||||
import type { LoadingBarTheme } from '../styles'
|
||||
import type { ExtractPublicPropTypes } from '../../_utils'
|
||||
|
||||
interface LoadingBarInst {
|
||||
start: () => void
|
||||
error: () => void
|
||||
finish: () => void
|
||||
}
|
||||
|
||||
export type LoadingBarProviderInst = LoadingBarInst
|
||||
export type LoadingBarApiInjection = LoadingBarInst
|
||||
|
||||
const loadingBarProps = {
|
||||
...(useTheme.props as ThemeProps<LoadingBarTheme>),
|
||||
to: {
|
||||
type: [String, Object] as PropType<string | HTMLElement>,
|
||||
default: undefined
|
||||
}
|
||||
}
|
||||
|
||||
export type LoadingBarProviderProps = ExtractPublicPropTypes<
|
||||
typeof loadingBarProps
|
||||
>
|
||||
|
||||
export type LoadingBarProviderSetupProps = ExtractPropTypes<
|
||||
typeof loadingBarProps
|
||||
>
|
||||
|
||||
export const loadingBarProviderInjectionKey: InjectionKey<{
|
||||
props: LoadingBarProviderSetupProps
|
||||
cPrefixRef: Ref<string>
|
||||
}> = Symbol('loadingBar')
|
||||
|
||||
export const loadingBarApiInjectionKey: InjectionKey<LoadingBarApiInjection> = Symbol(
|
||||
'loadingBarApi'
|
||||
)
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LoadingBarProvider',
|
||||
props: loadingBarProps,
|
||||
setup (props) {
|
||||
const isMountedRef = useIsMounted()
|
||||
const loadingBarRef = ref<LoadingBarInst | null>(null)
|
||||
const methods: LoadingBarProviderInst = {
|
||||
start () {
|
||||
if (isMountedRef.value) {
|
||||
loadingBarRef.value?.start()
|
||||
} else {
|
||||
void nextTick(() => {
|
||||
loadingBarRef.value?.start()
|
||||
})
|
||||
}
|
||||
},
|
||||
error () {
|
||||
if (isMountedRef.value) {
|
||||
loadingBarRef.value?.error()
|
||||
} else {
|
||||
void nextTick(() => {
|
||||
loadingBarRef.value?.error()
|
||||
})
|
||||
}
|
||||
},
|
||||
finish () {
|
||||
if (isMountedRef.value) {
|
||||
loadingBarRef.value?.finish()
|
||||
} else {
|
||||
void nextTick(() => {
|
||||
loadingBarRef.value?.finish()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
const { mergedClsPrefix } = useConfig(props)
|
||||
provide(loadingBarApiInjectionKey, methods)
|
||||
provide(loadingBarProviderInjectionKey, {
|
||||
props,
|
||||
cPrefixRef: mergedClsPrefix
|
||||
})
|
||||
return Object.assign(methods, {
|
||||
loadingBarRef
|
||||
})
|
||||
},
|
||||
render () {
|
||||
return (
|
||||
<>
|
||||
<Teleport to={this.to ?? 'body'}>
|
||||
<NLoadingBar ref="loadingBarRef" />
|
||||
</Teleport>
|
||||
{renderSlot(this.$slots, 'default')}
|
||||
</>
|
||||
)
|
||||
}
|
||||
})
|
@ -1,5 +0,0 @@
|
||||
export interface LoadingBarApiInjection {
|
||||
start: () => void
|
||||
finish: () => void
|
||||
error: () => void
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { inject } from 'vue'
|
||||
import { LoadingBarApiInjection } from './interface'
|
||||
import { loadingBarApiInjectionKey } from './LoadingBarProvider'
|
||||
import type { LoadingBarApiInjection } from './LoadingBarProvider'
|
||||
|
||||
export function useLoadingBar (): LoadingBarApiInjection | undefined {
|
||||
return inject('loadingBar')
|
||||
return inject(loadingBarApiInjectionKey)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user