refactor(pagination): ts

This commit is contained in:
07akioni 2021-01-21 00:50:05 +08:00
parent 825f85e33d
commit fb9211efd7
15 changed files with 629 additions and 553 deletions

View File

@ -1,4 +1,5 @@
/* istanbul ignore file */
export { default as NInput } from './src/Input'
export type { InputRef } from './src/Input'
export { default as NInputGroup } from './src/InputGroup'
export { default as NInputGroupLabel } from './src/InputGroupLabel'

View File

@ -23,6 +23,11 @@ import { inputLight } from '../styles'
import type { InputTheme } from '../styles'
import style from './styles/input.cssr'
export interface InputRef {
blur: () => void
focus: () => void
}
export default defineComponent({
name: 'Input',
props: {

View File

@ -1 +0,0 @@
export { default as NPagination } from './src/Pagination.vue'

1
src/pagination/index.ts Normal file
View File

@ -0,0 +1 @@
export { default as NPagination } from './src/Pagination'

View File

@ -0,0 +1,504 @@
import {
h,
nextTick,
computed,
ref,
toRef,
watch,
defineComponent,
PropType,
CSSProperties
} from 'vue'
import { useCompitable, useMergedState } from 'vooks'
import { NSelect } from '../../select'
import { InputRef, NInput } from '../../input'
import { NBaseIcon } from '../../_base'
import {
FastForwardIcon,
FastBackwardIcon,
BackwardIcon,
ForwardIcon,
MoreIcon
} from '../../_base/icons'
import { useLocale, useTheme } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import { paginationLight, PaginationTheme } from '../styles'
import { pageItems } from './utils'
import type { PageItem } from './utils'
import style from './styles/index.cssr'
export default defineComponent({
name: 'Pagination',
props: {
...(useTheme.props as ThemeProps<PaginationTheme>),
page: {
type: Number,
required: undefined
},
defaultPage: {
type: Number,
default: 1
},
pageCount: {
type: Number,
validator: (value: any) => {
return Number.isInteger(value) && value > 0
},
default: undefined
},
defaultPageCount: {
type: Number,
validator: (value: any) => {
return Number.isInteger(value) && value > 0
},
default: 1
},
showSizePicker: {
type: Boolean,
default: false
},
pageSize: {
type: Number,
default: undefined
},
defaultPageSize: {
type: Number,
default: null
},
pageSizes: {
type: Array as PropType<number[]>,
default: () => []
},
showQuickJumper: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
pageSlot: {
type: Number,
default: 9
},
// eslint-disable-next-line vue/prop-name-casing
'onUpdate:page': {
type: Function,
default: undefined
},
// eslint-disable-next-line vue/prop-name-casing
'onUpdate:pageSize': {
type: Function,
default: undefined
},
// deprecated
onPageSizeChange: {
type: Function,
default: undefined
},
onChange: {
type: Function,
default: undefined
},
total: {
type: Number,
validator: (value: any) => {
return Number.isInteger(value) && value > 0
},
default: undefined
}
},
setup (props) {
const themeRef = useTheme(
'Pagination',
'Pagination',
style,
paginationLight,
props
)
const { locale } = useLocale('Pagination')
const selfRef = ref<HTMLElement | null>(null)
const jumperRef = ref<InputRef | null>(null)
const compitablePageCountRef = useCompitable(props, ['total', 'pageCount'])
const jumperValueRef = ref('')
const uncontrolledPageRef = ref(props.defaultPage)
const uncontrolledPageSizeRef = ref(props.defaultPageSize)
const mergedPageRef = useMergedState(
toRef(props, 'page'),
uncontrolledPageRef
)
const mergedPageSizeRef = useMergedState(
toRef(props, 'pageSize'),
uncontrolledPageSizeRef
)
const showFastForwardRef = ref(false)
const showFastBackwardRef = ref(false)
const transitionDisabledRef = ref(false)
const pageSizeOptionsRef = computed(() => {
const suffix = locale.value.selectionSuffix
return props.pageSizes.map((size) => ({
label: `${size} / ${suffix}`,
value: size
}))
})
// unstable feature
const inputSizeRef = computed<'small'>(() => {
// const { unstableConfig } = this.$naive
// const size = unstableConfig?.Pagination?.inputSize
// if (size) {
// return size
// }
return 'small'
})
const disableTransitionOneTick = (): void => {
transitionDisabledRef.value = true
void nextTick(() => {
void selfRef.value?.offsetWidth
transitionDisabledRef.value = false
})
}
watch(mergedPageRef, disableTransitionOneTick)
function doUpdatePage (page: number): void {
if (page === mergedPageRef.value) return
const { 'onUpdate:page': onUpdatePage, onChange } = props
if (onUpdatePage) onUpdatePage(page)
// deprecated
if (onChange) onChange(page)
}
function doUpdatePageSize (pageSize: number): void {
if (pageSize === mergedPageSizeRef.value) return
const { 'onUpdate:pageSize': onUpdatePageSize, onPageSizeChange } = props
if (onUpdatePageSize) onUpdatePageSize(pageSize)
// deprecated
if (onPageSizeChange) onPageSizeChange(pageSize)
}
function forward (): void {
if (props.disabled) return
const page = Math.min(
mergedPageRef.value + 1,
compitablePageCountRef.value
)
doUpdatePage(page)
}
function backward (): void {
if (props.disabled) return
const page = Math.max(mergedPageRef.value - 1, 1)
doUpdatePage(page)
}
function fastForward (): void {
if (props.disabled) return
const page = Math.min(
mergedPageRef.value + (props.pageSlot - 4),
compitablePageCountRef.value
)
doUpdatePage(page)
}
function fastBackward (): void {
if (props.disabled) return
const page = Math.max(mergedPageRef.value - (props.pageSlot - 4), 1)
doUpdatePage(page)
}
function handleSizePickerChange (value: number): void {
doUpdatePageSize(value)
}
function handleQuickJumperKeyUp (e: KeyboardEvent): void {
if (e.code === 'Enter') {
const page = parseInt(jumperValueRef.value)
if (
!Number.isNaN(page) &&
page >= 1 &&
page <= compitablePageCountRef.value
) {
doUpdatePage(page)
jumperValueRef.value = ''
jumperRef.value?.blur()
}
}
}
function handlePageItemClick (pageItem: PageItem): void {
if (props.disabled) return
switch (pageItem.type) {
case 'page':
doUpdatePage(pageItem.label)
break
case 'fastBackward':
fastBackward()
break
case 'fastForward':
fastForward()
break
}
}
function handlePageItemMouseEnter (pageItem: PageItem): void {
if (props.disabled) return
switch (pageItem.type) {
default:
return
case 'fastBackward':
showFastBackwardRef.value = true
break
case 'fastForward':
showFastForwardRef.value = true
break
}
disableTransitionOneTick()
}
function handlePageItemMouseLeave (pageItem: PageItem): void {
if (props.disabled) return
switch (pageItem.type) {
default:
return
case 'fastBackward':
showFastBackwardRef.value = false
break
case 'fastForward':
showFastForwardRef.value = false
break
}
disableTransitionOneTick()
}
function handleJumperInput (value: string): void {
jumperValueRef.value = value
}
return {
locale,
selfRef,
jumperRef,
mergedPage: mergedPageRef,
showFastBackward: showFastBackwardRef,
showFastForward: showFastForwardRef,
compitablePageCount: compitablePageCountRef,
pageItems: computed(() =>
pageItems(
mergedPageRef.value,
compitablePageCountRef.value,
props.pageSlot
)
),
jumperValue: jumperValueRef,
pageSizeOptions: pageSizeOptionsRef,
inputSize: inputSizeRef,
transitionDisabled: transitionDisabledRef,
mergedTheme: themeRef,
handleJumperInput,
handleBackwardClick: backward,
handleForwardClick: forward,
handlePageItemClick,
handleSizePickerChange,
handleQuickJumperKeyUp,
handlePageItemMouseEnter,
handlePageItemMouseLeave,
cssVars: computed(() => {
const {
self: {
itemSize,
itemPadding,
itemMargin,
inputWidth,
selectWidth,
inputMargin,
selectMargin,
buttonBorder,
buttonBorderHover,
buttonBorderPressed,
buttonIconColor,
buttonIconColorHover,
buttonIconColorPressed,
buttonIconSize,
itemTextColor,
itemTextColorHover,
itemTextColorPressed,
itemTextColorActive,
itemTextColorDisabled,
itemColor,
itemColorHover,
itemColorPressed,
itemColorActive,
itemColorDisabled,
itemBorder,
itemBorderHover,
itemBorderPressed,
itemBorderActive,
itemBorderDisabled,
itemBorderRadius,
itemFontSize,
jumperFontSize,
jumperTextColor,
jumperTextColorDisabled
},
common: { cubicBezierEaseInOut }
} = themeRef.value
return {
'--item-font-size': itemFontSize,
'--select-width': selectWidth,
'--select-margin': selectMargin,
'--input-width': inputWidth,
'--input-margin': inputMargin,
'--item-size': itemSize,
'--item-text-color': itemTextColor,
'--item-text-color-disabled': itemTextColorDisabled,
'--item-text-color-hover': itemTextColorHover,
'--item-text-color-active': itemTextColorActive,
'--item-text-color-pressed': itemTextColorPressed,
'--item-color': itemColor,
'--item-color-hover': itemColorHover,
'--item-color-disabled': itemColorDisabled,
'--item-color-active': itemColorActive,
'--item-color-pressed': itemColorPressed,
'--item-border': itemBorder,
'--item-border-hover': itemBorderHover,
'--item-border-disabled': itemBorderDisabled,
'--item-border-active': itemBorderActive,
'--item-border-pressed': itemBorderPressed,
'--item-padding': itemPadding,
'--item-border-radius': itemBorderRadius,
'--bezier': cubicBezierEaseInOut,
'--jumper-font-size': jumperFontSize,
'--jumper-text-color': jumperTextColor,
'--jumper-text-color-disabled': jumperTextColorDisabled,
'--item-margin': itemMargin,
'--buttoNBaseIcon-size': buttonIconSize,
'--buttoNBaseIcon-color': buttonIconColor,
'--buttoNBaseIcon-color-hover': buttonIconColorHover,
'--buttoNBaseIcon-color-pressed': buttonIconColorPressed,
'--button-border': buttonBorder,
'--button-border-hover': buttonBorderHover,
'--button-border-pressed': buttonBorderPressed
}
})
}
},
render () {
const {
transitionDisabled,
disabled,
cssVars,
mergedPage,
compitablePageCount,
pageItems,
showFastBackward,
showFastForward,
showSizePicker,
showQuickJumper,
mergedTheme,
locale,
inputSize,
pageSize,
pageSizeOptions,
jumperValue,
handleJumperInput,
handleSizePickerChange,
handleBackwardClick,
handlePageItemClick,
handlePageItemMouseEnter,
handlePageItemMouseLeave,
handleForwardClick,
handleQuickJumperKeyUp
} = this
return (
<div
ref="selfRef"
class={[
'n-pagination',
{
'n-pagination--transition-disabled': transitionDisabled,
'n-pagination--disabled': disabled
}
]}
style={cssVars as CSSProperties}
>
<div
class={[
'n-pagination-item n-pagination-item--button',
{
'n-pagination-item--disabled':
mergedPage <= 1 || mergedPage > compitablePageCount || disabled
}
]}
onClick={handleBackwardClick}
>
<NBaseIcon>{{ default: () => <BackwardIcon /> }}</NBaseIcon>
</div>
{pageItems.map((pageItem, index) => {
return (
<div
key={index}
class={[
'n-pagination-item',
{
'n-pagination-item--active': pageItem.active,
'n-pagination-item--disabled': disabled
}
]}
onClick={() => handlePageItemClick(pageItem)}
onMouseenter={() => handlePageItemMouseEnter(pageItem)}
onMouseleave={() => handlePageItemMouseLeave(pageItem)}
>
{pageItem.type === 'page' ? pageItem.label : null}
{pageItem.type === 'fastBackward' ? (
showFastBackward ? (
<NBaseIcon>
{{ default: () => <FastBackwardIcon /> }}
</NBaseIcon>
) : (
<NBaseIcon>{{ default: () => <MoreIcon /> }}</NBaseIcon>
)
) : null}
{pageItem.type === 'fastForward' ? (
showFastForward ? (
<NBaseIcon>
{{ default: () => <FastForwardIcon /> }}
</NBaseIcon>
) : (
<NBaseIcon>{{ default: () => <MoreIcon /> }}</NBaseIcon>
)
) : null}
</div>
)
})}
<div
class={[
'n-pagination-item n-pagination-item--button',
{
'n-pagination-item--disabled':
mergedPage < 1 || mergedPage >= compitablePageCount || disabled
}
]}
onClick={handleForwardClick}
>
<NBaseIcon>{{ default: () => <ForwardIcon /> }}</NBaseIcon>
</div>
{showSizePicker ? (
<NSelect
size={inputSize}
placeholder=""
options={pageSizeOptions}
value={pageSize}
disabled={disabled}
unstableTheme={mergedTheme.peers.Select}
unstableThemeOverrides={mergedTheme.overrides.Select}
onUpdateValue={handleSizePickerChange as any}
/>
) : null}
{showQuickJumper ? (
<div class="n-pagination-quick-jumper">
{locale.goto}
<NInput
ref="jumperRef"
value={jumperValue}
onInput={handleJumperInput}
size={inputSize}
placeholder=""
disabled={disabled}
unstableTheme={mergedTheme.peers.Input}
unstableThemeOverrides={mergedTheme.overrides.Input}
onKeyup={handleQuickJumperKeyUp}
/>
</div>
) : null}
</div>
)
}
})

View File

@ -1,465 +0,0 @@
<template>
<div
ref="selfRef"
class="n-pagination"
:class="{
'n-pagination--transition-disabled': transitionDisabled,
'n-pagination--disabled': disabled
}"
:style="cssVars"
>
<div
class="n-pagination-item n-pagination-item--button"
:class="{
'n-pagination-item--disabled':
page <= 1 || page > compitablePageCount || disabled
}"
@click="handleBackwardClick"
>
<n-base-icon>
<backward-icon />
</n-base-icon>
</div>
<div
v-for="(pageItem, index) in pageItems"
:key="index"
class="n-pagination-item"
:class="{
'n-pagination-item--active': pageItem.active,
'n-pagination-item--disabled': disabled
}"
@click="handlePageItemClick(pageItem)"
@mouseenter="handlePageItemMouseEnter(pageItem)"
@mouseleave="handlePageItemMouseLeave(pageItem)"
>
<template v-if="pageItem.type === 'page'">
{{ pageItem.label }}
</template>
<template v-if="pageItem.type === 'fastBackward'">
<n-base-icon v-if="showFastBackward">
<fast-backward-icon />
</n-base-icon>
<n-base-icon v-else>
<more-icon />
</n-base-icon>
</template>
<template v-if="pageItem.type === 'fastForward'">
<n-base-icon v-if="showFastForward">
<fast-forward-icon />
</n-base-icon>
<n-base-icon v-else>
<more-icon />
</n-base-icon>
</template>
</div>
<div
class="n-pagination-item n-pagination-item--button"
:class="{
'n-pagination-item--disabled':
page < 1 || page >= compitablePageCount || disabled
}"
@click="handleForwardClick"
>
<n-base-icon>
<forward-icon />
</n-base-icon>
</div>
<n-select
v-if="showSizePicker"
:size="inputSize"
placeholder=""
:options="pageSizeOptions"
:value="pageSize"
:disabled="disabled"
:unstable-theme="mergedTheme.peers.Select"
:unstable-theme-overrides="mergedTheme.overrides.Select"
@update:value="handleSizePickerChange"
/>
<div v-if="showQuickJumper" class="n-pagination-quick-jumper">
{{ locale.goto }}
<n-input
v-model:value="jumperValue"
:size="inputSize"
placeholder=""
:disabled="disabled"
:unstable-theme="mergedTheme.peers.Input"
:unstable-theme-overrides="mergedTheme.overrides.Input"
@keyup="handleQuickJumperKeyUp"
/>
</div>
</div>
</template>
<script>
import { nextTick, computed, ref, toRef, watch } from 'vue'
import { useCompitable, useMergedState } from 'vooks'
import { NSelect } from '../../select'
import { NInput } from '../../input'
import { NBaseIcon } from '../../_base'
import {
FastForwardIcon,
FastBackwardIcon,
BackwardIcon,
ForwardIcon,
MoreIcon
} from '../../_base/icons'
import { useLocale, useTheme } from '../../_mixins'
import { paginationLight } from '../styles'
import { pageItems } from './utils'
import style from './styles/index.cssr.js'
function useMethods (
props,
{
showFastForwardRef,
showFastBackwardRef,
mergedPageRef,
mergedPageSizeRef,
compitablePageCountRef,
jumperValueRef,
disableTransitionOneTick
}
) {
function doUpdatePage (page) {
if (page === mergedPageRef.value) return
const { 'onUpdate:page': onUpdatePage, onChange } = props
if (onUpdatePage) onUpdatePage(page)
// deprecated
if (onChange) onChange(page)
}
function doUpdatePageSize (pageSize) {
if (pageSize === mergedPageSizeRef.value) return
const { 'onUpdate:pageSize': onUpdatePageSize, onPageSizeChange } = this
if (onUpdatePageSize) onUpdatePageSize(pageSize)
// deprecated
if (onPageSizeChange) onPageSizeChange(pageSize)
}
function forward () {
if (props.disabled) return
const page = Math.min(mergedPageRef.value + 1, compitablePageCountRef.value)
doUpdatePage(page)
}
function backward () {
if (props.disabled) return
const page = Math.max(mergedPageRef.value - 1, 1)
doUpdatePage(page)
}
function fastForward () {
if (props.disabled) return
const page = Math.min(
mergedPageRef.value + (props.pageSlot - 4),
compitablePageCountRef.value
)
doUpdatePage(page)
}
function fastBackward () {
if (props.disabled) return
const page = Math.max(mergedPageRef.value - (props.pageSlot - 4), 1)
doUpdatePage(page)
}
function handleSizePickerChange (value) {
doUpdatePageSize(value)
}
function handleQuickJumperKeyUp (e) {
if (e.code === 'Enter') {
const page = parseInt(jumperValueRef.value)
if (
!Number.isNaN(page) &&
page >= 1 &&
page <= compitablePageCountRef.value
) {
doUpdatePage(page)
jumperValueRef.value = ''
}
}
}
function handlePageItemClick (pageItem) {
if (props.disabled) return
switch (pageItem.type) {
case 'page':
doUpdatePage(pageItem.label)
break
case 'fastBackward':
fastBackward()
break
case 'fastForward':
fastForward()
break
}
}
function handlePageItemMouseEnter (pageItem) {
if (props.disabled) return
switch (pageItem.type) {
default:
return
case 'fastBackward':
showFastBackwardRef.value = true
break
case 'fastForward':
showFastForwardRef.value = true
break
}
disableTransitionOneTick()
}
function handlePageItemMouseLeave (pageItem) {
if (props.disabled) return
switch (pageItem.type) {
default:
return
case 'fastBackward':
showFastBackwardRef.value = false
break
case 'fastForward':
showFastForwardRef.value = false
break
}
disableTransitionOneTick()
}
return {
handleBackwardClick: backward,
handleForwardClick: forward,
handlePageItemClick,
handleSizePickerChange,
handleQuickJumperKeyUp,
handlePageItemMouseEnter,
handlePageItemMouseLeave
}
}
export default {
name: 'Pagination',
components: {
NSelect,
NInput,
NBaseIcon,
BackwardIcon,
ForwardIcon,
MoreIcon,
FastForwardIcon,
FastBackwardIcon
},
props: {
...useTheme.props,
page: {
type: Number,
required: true
},
pageCount: {
validator (value) {
return Number.isInteger(value) && value > 0
},
default: undefined
},
defaultPageCount: {
validator (value) {
return Number.isInteger(value) && value > 0
},
default: 1
},
showSizePicker: {
type: Boolean,
default: false
},
pageSize: {
type: Number,
default: undefined
},
defaultPageSize: {
type: Number,
default: null
},
pageSizes: {
type: Array,
default: () => []
},
showQuickJumper: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
pageSlot: {
type: Number,
default: 9
},
// eslint-disable-next-line vue/prop-name-casing
'onUpdate:page': {
type: Function,
default: undefined
},
// eslint-disable-next-line vue/prop-name-casing
'onUpdate:pageSize': {
type: Function,
default: undefined
},
// deprecated
onPageSizeChange: {
type: Function,
default: undefined
},
onChange: {
type: Function,
default: undefined
},
total: {
validator (value) {
return Number.isInteger(value) && value > 0
},
default: undefined
}
},
setup (props) {
const themeRef = useTheme(
'Pagination',
'Pagination',
style,
paginationLight,
props
)
const selfRef = ref(null)
const compitablePageCountRef = useCompitable(props, ['total', 'pageCount'])
const jumperValueRef = ref('')
const uncontrolledPageRef = ref(props.defaultPage)
const uncontrolledPageSizeRef = ref(props.defaultPageSize)
const mergedPageRef = useMergedState(
toRef(props, 'page'),
uncontrolledPageRef
)
const mergedPageSizeRef = useMergedState(
toRef(props, 'pageSize'),
uncontrolledPageSizeRef
)
const showFastForwardRef = ref(false)
const showFastBackwardRef = ref(false)
const transitionDisabledRef = ref(false)
const disableTransitionOneTick = () => {
transitionDisabledRef.value = true
nextTick(() => {
void selfRef.value.offsetWidth
transitionDisabledRef.value = false
})
}
watch(mergedPageRef, disableTransitionOneTick)
return {
...useLocale('Pagination'),
...useMethods(props, {
showFastForwardRef,
showFastBackwardRef,
mergedPageRef,
mergedPageSizeRef,
compitablePageCountRef,
jumperValueRef,
disableTransitionOneTick
}),
selfRef,
showFastBackward: showFastBackwardRef,
showFastForward: showFastForwardRef,
compitablePageCount: compitablePageCountRef,
pageItems: computed(() =>
pageItems(props.page, compitablePageCountRef.value, props.pageSlot)
),
jumperValue: jumperValueRef,
transitionDisabled: transitionDisabledRef,
mergedTheme: themeRef,
cssVars: computed(() => {
const {
self: {
itemSize,
itemPadding,
itemMargin,
inputWidth,
selectWidth,
inputMargin,
selectMargin,
buttonBorder,
buttonBorderHover,
buttonBorderPressed,
buttonIconColor,
buttonIconColorHover,
buttonIconColorPressed,
buttonIconSize,
itemTextColor,
itemTextColorHover,
itemTextColorPressed,
itemTextColorActive,
itemTextColorDisabled,
itemColor,
itemColorHover,
itemColorPressed,
itemColorActive,
itemColorDisabled,
itemBorder,
itemBorderHover,
itemBorderPressed,
itemBorderActive,
itemBorderDisabled,
itemBorderRadius,
itemFontSize,
jumperFontSize,
jumperTextColor,
jumperTextColorDisabled
},
common: { cubicBezierEaseInOut }
} = themeRef.value
return {
'--item-font-size': itemFontSize,
'--select-width': selectWidth,
'--select-margin': selectMargin,
'--input-width': inputWidth,
'--input-margin': inputMargin,
'--item-size': itemSize,
'--item-text-color': itemTextColor,
'--item-text-color-disabled': itemTextColorDisabled,
'--item-text-color-hover': itemTextColorHover,
'--item-text-color-active': itemTextColorActive,
'--item-text-color-pressed': itemTextColorPressed,
'--item-color': itemColor,
'--item-color-hover': itemColorHover,
'--item-color-disabled': itemColorDisabled,
'--item-color-active': itemColorActive,
'--item-color-pressed': itemColorPressed,
'--item-border': itemBorder,
'--item-border-hover': itemBorderHover,
'--item-border-disabled': itemBorderDisabled,
'--item-border-active': itemBorderActive,
'--item-border-pressed': itemBorderPressed,
'--item-padding': itemPadding,
'--item-border-radius': itemBorderRadius,
'--bezier': cubicBezierEaseInOut,
'--jumper-font-size': jumperFontSize,
'--jumper-text-color': jumperTextColor,
'--jumper-text-color-disabled': jumperTextColorDisabled,
'--item-margin': itemMargin,
'--button-base-icon-size': buttonIconSize,
'--button-base-icon-color': buttonIconColor,
'--button-base-icon-color-hover': buttonIconColorHover,
'--button-base-icon-color-pressed': buttonIconColorPressed,
'--button-border': buttonBorder,
'--button-border-hover': buttonBorderHover,
'--button-border-pressed': buttonBorderPressed
}
})
}
},
computed: {
pageSizeOptions () {
const suffix = this.locale.selectionSuffix
return this.pageSizes.map((size) => ({
label: `${size} / ${suffix}`,
value: size
}))
},
// unstable feature
inputSize () {
const { unstableConfig } = this.$naive
const size = unstableConfig?.Pagination?.inputSize
if (size) {
return size
}
return 'small'
}
}
}
</script>

View File

@ -1,4 +1,4 @@
import { cB, c, cE, cM, cNotM } from '../../../_utils/cssr'
import { cB, c, cM, cNotM } from '../../../_utils/cssr'
// vars:
// --item-font-size
@ -58,16 +58,7 @@ export default cB('pagination', `
cB('input', `
margin: var(--input-margin);
width: var(--input-width);
`, [
cE('placeholder', {
left: '6px',
right: '6px'
}),
c('input', `
padding-left: 6px;
padding-right: 6px;
`)
])
`)
]),
cB('pagination-item', `
position: relative;

View File

@ -1,9 +1,8 @@
/**
*
* @param {number} currentPage
* @param {number} pageCount
*/
function pagesToShow (currentPage, pageCount, pageSlot = 9) {
function pagesToShow (
currentPage: number,
pageCount: number,
pageSlot: number = 9
): number[] {
if (pageCount === 1) return [1]
if (pageCount === 2) return [1, 2]
const firstPage = 1
@ -47,18 +46,32 @@ function pagesToShow (currentPage, pageCount, pageSlot = 9) {
return items
}
function mapPagesToPageItems (pages, currentPage) {
export type PageItem =
| {
type: 'fastBackward' | 'fastForward'
label: string
active: false
}
| {
type: 'page'
label: number
active: boolean
}
function mapPagesToPageItems (pages: number[], currentPage: number): PageItem[] {
return pages.map((page) => {
switch (page) {
case -2:
return {
type: 'fastBackward',
label: 'fastBackward'
label: 'fastBackward',
active: false
}
case -1:
return {
type: 'fastForward',
label: 'fastForward'
label: 'fastForward',
active: false
}
default:
if (page === currentPage) {
@ -78,10 +91,13 @@ function mapPagesToPageItems (pages, currentPage) {
})
}
function pageItems (currentPage, pageCount, pageSlot) {
function pageItems (
currentPage: number,
pageCount: number,
pageSlot: number
): PageItem[] {
const pages = pagesToShow(currentPage, pageCount, pageSlot)
const items = mapPagesToPageItems(pages, currentPage)
return items
return mapPagesToPageItems(pages, currentPage)
}
export { pagesToShow, mapPagesToPageItems, pageItems }

View File

@ -2,9 +2,10 @@ import { changeColor } from 'seemly'
import { selectDark } from '../../select/styles'
import { inputDark } from '../../input/styles'
import { commonDark } from '../../_styles/new-common'
import commonVariables from './_common.js'
import commonVariables from './_common'
import type { PaginationTheme } from './light'
export default {
const paginationDark: PaginationTheme = {
name: 'Pagination',
common: commonDark,
peers: {
@ -25,7 +26,7 @@ export default {
fontSize
} = vars
const borderColor = changeColor(primaryColor, {
alpha: opacity3
alpha: Number(opacity3)
})
return {
...commonVariables,
@ -60,3 +61,5 @@ export default {
}
}
}
export default paginationDark

View File

@ -1,2 +0,0 @@
export { default as paginationDark } from './dark.js'
export { default as paginationLight } from './light.js'

View File

@ -0,0 +1,3 @@
export { default as paginationDark } from './dark'
export { default as paginationLight } from './light'
export type { PaginationTheme, PaginationThemeVars } from './light'

View File

@ -1,58 +0,0 @@
import { selectLight } from '../../select/styles'
import { inputLight } from '../../input/styles'
import { commonLight } from '../../_styles/new-common'
import commonVariables from './_common.js'
export default {
name: 'Pagination',
common: commonLight,
peers: {
Select: selectLight,
Input: inputLight
},
self (vars) {
const {
textColor2,
primaryColor,
primaryColorHover,
primaryColorPressed,
inputColorDisabled,
textColorDisabled,
borderColor,
borderRadius,
fontSize
} = vars
return {
...commonVariables,
buttonColor: 'transparent',
buttonColorHover: 'transparent',
buttonColorPressed: 'transparent',
buttonBorder: `1px solid ${borderColor}`,
buttonBorderHover: `1px solid ${borderColor}`,
buttonBorderPressed: `1px solid ${borderColor}`,
buttonIconColor: textColor2,
buttonIconColorHover: textColor2,
buttonIconColorPressed: textColor2,
itemTextColor: textColor2,
itemTextColorHover: primaryColorHover,
itemTextColorPressed: primaryColorPressed,
itemTextColorActive: primaryColor,
itemTextColorDisabled: textColorDisabled,
itemColor: 'transparent',
itemColorHover: 'transparent',
itemColorPressed: 'transparent',
itemColorActive: 'transparent',
itemColorDisabled: inputColorDisabled,
itemBorder: '1px solid transparent',
itemBorderHover: '1px solid transparent',
itemBorderPressed: '1px solid transparent',
itemBorderActive: `1px solid ${primaryColor}`,
itemBorderDisabled: `1px solid ${borderColor}`,
itemBorderRadius: borderRadius,
itemFontSize: fontSize,
jumperTextColor: textColor2,
jumperTextColorDisabled: textColorDisabled
}
}
}

View File

@ -0,0 +1,66 @@
import { selectLight } from '../../select/styles'
import { inputLight } from '../../input/styles'
import { commonLight, ThemeCommonVars } from '../../_styles/new-common'
import commonVariables from './_common'
import { createTheme } from '../../_mixins'
const self = (vars: ThemeCommonVars) => {
const {
textColor2,
primaryColor,
primaryColorHover,
primaryColorPressed,
inputColorDisabled,
textColorDisabled,
borderColor,
borderRadius,
fontSize
} = vars
return {
...commonVariables,
buttonColor: 'transparent',
buttonColorHover: 'transparent',
buttonColorPressed: 'transparent',
buttonBorder: `1px solid ${borderColor}`,
buttonBorderHover: `1px solid ${borderColor}`,
buttonBorderPressed: `1px solid ${borderColor}`,
buttonIconColor: textColor2,
buttonIconColorHover: textColor2,
buttonIconColorPressed: textColor2,
itemTextColor: textColor2,
itemTextColorHover: primaryColorHover,
itemTextColorPressed: primaryColorPressed,
itemTextColorActive: primaryColor,
itemTextColorDisabled: textColorDisabled,
itemColor: 'transparent',
itemColorHover: 'transparent',
itemColorPressed: 'transparent',
itemColorActive: 'transparent',
itemColorDisabled: inputColorDisabled,
itemBorder: '1px solid transparent',
itemBorderHover: '1px solid transparent',
itemBorderPressed: '1px solid transparent',
itemBorderActive: `1px solid ${primaryColor}`,
itemBorderDisabled: `1px solid ${borderColor}`,
itemBorderRadius: borderRadius,
itemFontSize: fontSize,
jumperTextColor: textColor2,
jumperTextColorDisabled: textColorDisabled
}
}
export type PaginationThemeVars = ReturnType<typeof self>
const paginationLight = createTheme({
name: 'Pagination',
common: commonLight,
peers: {
Select: selectLight,
Input: inputLight
},
self
})
export default paginationLight
export type PaginationTheme = typeof paginationLight

View File

@ -144,6 +144,13 @@ export default defineComponent({
>,
default: undefined
},
// for jsx
onUpdateValue: {
type: [Function, Array] as PropType<
MaybeArray<(value: string | number | null) => void> | undefined
>,
default: undefined
},
onBlur: {
type: [Function, Array] as PropType<
MaybeArray<(e: FocusEvent) => void> | undefined
@ -315,10 +322,15 @@ export default defineComponent({
function doUpdateValue (
value: string | number | Array<string | number> | null
): void {
const { onChange, 'onUpdate:value': onUpdateValue } = props
const {
onChange,
'onUpdate:value': _onUpdateValue,
onUpdateValue
} = props
const { nTriggerFormChange, nTriggerFormInput } = formItem
if (onChange) call(onChange, value)
if (onUpdateValue) call(onUpdateValue, value)
if (_onUpdateValue) call(_onUpdateValue, value)
uncontrolledValueRef.value = value
nTriggerFormChange()
nTriggerFormInput()