@ithinkdt/naive
Version:
iThinkDT Naive UI
147 lines (134 loc) • 6.23 kB
JSX
import { watch, ref, defineComponent, withDirectives, resolveDirective } from 'vue'
import { useI18n } from '@ithinkdt/core'
import { NButton, NIcon, NPopover } from 'ithinkdt-ui'
import { Sortable } from 'sortablejs/modular/sortable.core.esm.js'
import {
fullWidth,
flexJustifySB,
cB,
cE,
CSS_MOUNT_ANCHOR_META_NAME,
CSS_STYLE_PREFIX as p,
} from '@ithinkdt/core/cssr'
import { CustomCol } from './CustomCol.jsx'
const ICustom = () => (
<svg width="1em" height="1em" viewBox="0 0 1024 1024">
<path
fill="currentColor"
d="m924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 0 0 9.3-35.2l-.9-2.6a443.74 443.74 0 0 0-79.7-137.9l-1.8-2.1a32.12 32.12 0 0 0-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 0 0-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 0 0-25.8 25.7l-15.8 85.4a351.86 351.86 0 0 0-99 57.4l-81.9-29.1a32 32 0 0 0-35.1 9.5l-1.8 2.1a446.02 446.02 0 0 0-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1c0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 0 0-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0 0 35.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0 0 25.8 25.7l2.7.5a449.4 449.4 0 0 0 159 0l2.7-.5a32.05 32.05 0 0 0 25.8-25.7l15.7-85a350 350 0 0 0 99.7-57.6l81.3 28.9a32 32 0 0 0 35.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1l74.7 63.9a370.03 370.03 0 0 1-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3l-17.9 97a377.5 377.5 0 0 1-85 0l-17.9-97.2l-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9l-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5l-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5c0-15.3 1.2-30.6 3.7-45.5l6.5-40l-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2l31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3l17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97l38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8l92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176s176-78.8 176-176s-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 0 1 512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 0 1 400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 0 1 624 502c0 29.9-11.7 58-32.8 79.2z"
/>
</svg>
)
export const DtCustomCols = defineComponent({
name: 'DtCustomCols',
props: {
columns: {
type: Array,
required: true,
},
cached: {
type: [Boolean, String],
required: false,
default: true,
},
},
emits: ['custom', 'reset'],
setup(props, { emit }) {
const cls = `${p}-custom-cols`
createStyle(cls)
const { t } = useI18n('global')
function emitCols(col, field, value) {
emit('custom', {
key: col.key,
field,
value,
})
}
const ulRef = ref()
watch(ulRef, (el) => {
if (!el) return
Sortable.create(el, {
animation: 150,
ghostClass: 'ghost',
handle: '.icon-drag',
filter: '.disabled',
onEnd(e) {
emitCols(props.columns[e.oldIndex], 'index', e.newIndex)
},
})
})
const vTooltip = resolveDirective('tooltip')
return () => (
<NPopover
trigger="click"
scrollable
placement="left-start"
displayDirective="show"
style="max-height: 400px; width: 240px"
>
{{
trigger: () =>
withDirectives(
<NButton text>
<NIcon size="20">
<ICustom />
</NIcon>
</NButton>,
[[vTooltip, t('page.column.custom')]],
),
default: () => (
<div class={cls}>
<div class={`${cls}__op`}>
<span>{t('page.column.custom')}</span>
<NButton text type="primary" onClick={() => emit('reset')}>
{t('page.column.reset')}
</NButton>
</div>
<div ref={ulRef} class={`${cls}__content`}>
{props.columns.map((col) => (
<div key={col.key} v-show={col.format !== 'select'}>
<CustomCol
column={col}
onUpdateHidden={(v) => emitCols(col, 'hidden', v)}
onUpdateFixed={(v) => emitCols(col, 'fixed', v)}
/>
</div>
))}
</div>
</div>
),
}}
</NPopover>
)
},
})
let style
function createStyle(cls) {
if (!style) {
style = cB(
'custom-cols',
{
...fullWidth,
padding: `0 10px 0 7px`,
boxSizing: 'border-box',
},
[
cE('op', {
...flexJustifySB,
padding: '10px 4px 10px 1px',
position: 'sticky',
top: '0',
background: '#fff',
zIndex: '2',
}),
cE('content', {
lineHeight: '32px',
}),
],
)
style.mount({
id: cls,
anchorMetaName: CSS_MOUNT_ANCHOR_META_NAME,
})
}
}