35 changed files with 1099 additions and 454 deletions
@ -0,0 +1,55 @@ |
|||
<template> |
|||
<EditTableHeaderCell v-if="getIsEdit"> |
|||
{{ getTitle }} |
|||
</EditTableHeaderCell> |
|||
<span v-else>{{ getTitle }}</span> |
|||
<BasicHelp v-if="getHelpMessage" :text="getHelpMessage" :class="`${prefixCls}__help`" /> |
|||
</template> |
|||
<script lang="ts"> |
|||
import type { PropType } from 'vue'; |
|||
import type { BasicColumn } from '../types/table'; |
|||
|
|||
import { defineComponent, computed } from 'vue'; |
|||
|
|||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
|||
import { useDesign } from '/@/hooks/web/useDesign'; |
|||
export default defineComponent({ |
|||
name: 'TableHeaderCell', |
|||
components: { |
|||
EditTableHeaderCell: createAsyncComponent(() => import('./EditTableHeaderIcon.vue')), |
|||
BasicHelp: createAsyncComponent(() => import('/@/components/Basic/src/BasicHelp.vue')), |
|||
}, |
|||
props: { |
|||
column: { |
|||
type: Object as PropType<BasicColumn>, |
|||
default: {}, |
|||
}, |
|||
}, |
|||
setup(props) { |
|||
const { prefixCls } = useDesign('basic-table-header-cell'); |
|||
const getIsEdit = computed(() => { |
|||
return !!props.column?.edit; |
|||
}); |
|||
|
|||
const getTitle = computed(() => { |
|||
return props.column?.customTitle; |
|||
}); |
|||
|
|||
const getHelpMessage = computed(() => { |
|||
return props.column?.helpMessage; |
|||
}); |
|||
|
|||
return { prefixCls, getIsEdit, getTitle, getHelpMessage }; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style lang="less"> |
|||
@prefix-cls: ~'@{namespace}-basic-table-header-cell'; |
|||
|
|||
.@{prefix-cls} { |
|||
&__help { |
|||
margin-left: 8px; |
|||
color: rgba(0, 0, 0, 0.65) !important; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,33 @@ |
|||
import type { FunctionalComponent, defineComponent } from 'vue'; |
|||
import type { ComponentType } from '../../types/componentType'; |
|||
import { componentMap } from '/@/components/Table/src/componentMap'; |
|||
|
|||
import { Popover } from 'ant-design-vue'; |
|||
import { h } from 'vue'; |
|||
|
|||
export interface ComponentProps { |
|||
component: ComponentType; |
|||
rule: boolean; |
|||
popoverVisible: boolean; |
|||
ruleMessage: string; |
|||
} |
|||
|
|||
export const CellComponent: FunctionalComponent = ( |
|||
{ component = 'Input', rule = true, ruleMessage, popoverVisible }: ComponentProps, |
|||
{ attrs } |
|||
) => { |
|||
const Comp = componentMap.get(component) as typeof defineComponent; |
|||
|
|||
const DefaultComp = h(Comp, attrs); |
|||
if (!rule) { |
|||
return DefaultComp; |
|||
} |
|||
return h( |
|||
Popover, |
|||
{ overlayClassName: 'edit-cell-rule-popover', visible: !!popoverVisible }, |
|||
{ |
|||
default: () => DefaultComp, |
|||
content: () => ruleMessage, |
|||
} |
|||
); |
|||
}; |
|||
@ -0,0 +1,359 @@ |
|||
<template> |
|||
<div :class="prefixCls"> |
|||
<div v-show="!isEdit" :class="`${prefixCls}__normal`" @click="handleEdit"> |
|||
{{ value || ' ' }} |
|||
<FormOutlined :class="`${prefixCls}__normal-icon`" v-if="!column.editRow" /> |
|||
</div> |
|||
|
|||
<div v-if="isEdit" :class="`${prefixCls}__wrapper`" v-click-outside="onClickOutside"> |
|||
<CellComponent |
|||
v-bind="getComponentProps" |
|||
:component="getComponent" |
|||
:style="getWrapperStyle" |
|||
:popoverVisible="getRuleVisible" |
|||
:rule="getRule" |
|||
:ruleMessage="ruleMessage" |
|||
size="small" |
|||
ref="elRef" |
|||
@change="handleChange" |
|||
@options-change="handleOptionsChange" |
|||
@pressEnter="handleSubmit" |
|||
> |
|||
</CellComponent> |
|||
<div :class="`${prefixCls}__action`" v-if="!getRowEditable"> |
|||
<CheckOutlined :class="[`${prefixCls}__icon`, 'mx-2']" @click="handleSubmit" /> |
|||
<CloseOutlined :class="`${prefixCls}__icon `" @click="handleCancel" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import type { CSSProperties, PropType } from 'vue'; |
|||
import type { BasicColumn } from '../../types/table'; |
|||
|
|||
import { defineComponent, ref, unref, nextTick, computed, watchEffect, toRaw } from 'vue'; |
|||
import { FormOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons-vue'; |
|||
|
|||
import { useDesign } from '/@/hooks/web/useDesign'; |
|||
import { isString, isBoolean, isFunction, isNumber, isArray } from '/@/utils/is'; |
|||
import clickOutside from '/@/directives/clickOutside'; |
|||
|
|||
import { CellComponent } from './CellComponent'; |
|||
import { useTableContext } from '../../hooks/useTableContext'; |
|||
import { propTypes } from '/@/utils/propTypes'; |
|||
import { createPlaceholderMessage } from './helper'; |
|||
|
|||
import type { EditRecordRow } from './index'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'EditableCell', |
|||
components: { FormOutlined, CloseOutlined, CheckOutlined, CellComponent }, |
|||
props: { |
|||
value: { |
|||
type: [String, Number, Boolean, Object] as PropType<string | number | boolean | Recordable>, |
|||
default: '', |
|||
}, |
|||
record: { |
|||
type: Object as PropType<EditRecordRow>, |
|||
}, |
|||
column: { |
|||
type: Object as PropType<BasicColumn>, |
|||
default: {}, |
|||
}, |
|||
index: propTypes.number, |
|||
}, |
|||
directives: { |
|||
clickOutside, |
|||
}, |
|||
|
|||
setup(props) { |
|||
const table = useTableContext(); |
|||
const isEdit = ref(false); |
|||
const elRef = ref<any>(null); |
|||
const ruleVisible = ref(false); |
|||
const ruleMessage = ref(''); |
|||
const optionsRef = ref<LabelValueOptions>([]); |
|||
const currentValueRef = ref<any>(props.value); |
|||
const defaultValueRef = ref<any>(props.value); |
|||
|
|||
const { prefixCls } = useDesign('editable-cell'); |
|||
|
|||
const getComponent = computed(() => props.column?.editComponent || 'Input'); |
|||
const getRule = computed(() => props.column?.editRule); |
|||
|
|||
const getRuleVisible = computed(() => { |
|||
return unref(ruleMessage) && unref(ruleVisible); |
|||
}); |
|||
|
|||
const getIsCheckComp = computed(() => { |
|||
const component = unref(getComponent); |
|||
return ['Checkbox', 'Switch'].includes(component); |
|||
}); |
|||
|
|||
const getComponentProps = computed(() => { |
|||
const compProps = props.column?.editComponentProps ?? {}; |
|||
const component = unref(getComponent); |
|||
const apiSelectProps: Recordable = {}; |
|||
if (component === 'ApiSelect') { |
|||
apiSelectProps.cache = true; |
|||
} |
|||
|
|||
const isCheckValue = unref(getIsCheckComp); |
|||
|
|||
const valueField = isCheckValue ? 'checked' : 'value'; |
|||
const val = unref(currentValueRef); |
|||
|
|||
const value = isCheckValue ? (isNumber(val) && isBoolean(val) ? val : !!val) : val; |
|||
|
|||
return { |
|||
placeholder: createPlaceholderMessage(unref(getComponent)), |
|||
...apiSelectProps, |
|||
...compProps, |
|||
[valueField]: value, |
|||
}; |
|||
}); |
|||
|
|||
const getValues = computed(() => { |
|||
const { editComponentProps, editValueMap } = props.column; |
|||
|
|||
const value = unref(currentValueRef); |
|||
|
|||
if (editValueMap && isFunction(editValueMap)) { |
|||
return editValueMap(value); |
|||
} |
|||
|
|||
const component = unref(getComponent); |
|||
if (!component.includes('Select')) { |
|||
return value; |
|||
} |
|||
const options: LabelValueOptions = editComponentProps?.options ?? (unref(optionsRef) || []); |
|||
const option = options.find((item) => `${item.value}` === `${value}`); |
|||
return option?.label; |
|||
}); |
|||
|
|||
const getWrapperStyle = computed( |
|||
(): CSSProperties => { |
|||
if (unref(getIsCheckComp) || unref(getRowEditable)) { |
|||
return {}; |
|||
} |
|||
return { |
|||
width: 'calc(100% - 48px)', |
|||
}; |
|||
} |
|||
); |
|||
|
|||
const getRowEditable = computed(() => { |
|||
const { editable } = props.record || {}; |
|||
return !!editable; |
|||
}); |
|||
|
|||
watchEffect(() => { |
|||
defaultValueRef.value = props.value; |
|||
}); |
|||
|
|||
watchEffect(() => { |
|||
const { editable } = props.column; |
|||
if (isBoolean(editable) || isBoolean(unref(getRowEditable))) { |
|||
isEdit.value = !!editable || unref(getRowEditable); |
|||
} |
|||
}); |
|||
|
|||
function handleEdit() { |
|||
if (unref(getRowEditable) || unref(props.column?.editRow)) return; |
|||
ruleMessage.value = ''; |
|||
isEdit.value = true; |
|||
nextTick(() => { |
|||
const el = unref(elRef); |
|||
el?.focus?.(); |
|||
}); |
|||
} |
|||
|
|||
async function handleChange(e: any) { |
|||
const component = unref(getComponent); |
|||
if (e?.target && Reflect.has(e.target, 'value')) { |
|||
currentValueRef.value = (e as ChangeEvent).target.value; |
|||
} |
|||
if (component === 'Checkbox') { |
|||
currentValueRef.value = (e as ChangeEvent).target.checked; |
|||
} else if (isString(e) || isBoolean(e) || isNumber(e)) { |
|||
currentValueRef.value = e; |
|||
} |
|||
handleSubmiRule(); |
|||
} |
|||
|
|||
async function handleSubmiRule() { |
|||
const { column, record } = props; |
|||
const { editRule } = column; |
|||
const currentValue = unref(currentValueRef); |
|||
|
|||
if (editRule) { |
|||
if (isBoolean(editRule) && !currentValue && !isNumber(currentValue)) { |
|||
ruleVisible.value = true; |
|||
const component = unref(getComponent); |
|||
const message = createPlaceholderMessage(component); |
|||
ruleMessage.value = message; |
|||
return false; |
|||
} |
|||
if (isFunction(editRule)) { |
|||
const res = await editRule(currentValue, record as Recordable); |
|||
if (!!res) { |
|||
ruleMessage.value = res; |
|||
ruleVisible.value = true; |
|||
return false; |
|||
} else { |
|||
ruleMessage.value = ''; |
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
ruleMessage.value = ''; |
|||
return true; |
|||
} |
|||
|
|||
async function handleSubmit() { |
|||
const isPass = await handleSubmiRule(); |
|||
if (!isPass) return false; |
|||
const { column, index } = props; |
|||
const { key, dataIndex } = column; |
|||
// const value = unref(currentValueRef); |
|||
if (!key || !dataIndex) return; |
|||
const dataKey = (dataIndex || key) as string; |
|||
|
|||
const record = await table.updateTableData(index, dataKey, unref(getValues)); |
|||
table.emit?.('edit-end', { record, index, key, value: unref(currentValueRef) }); |
|||
isEdit.value = false; |
|||
} |
|||
|
|||
function handleCancel() { |
|||
isEdit.value = false; |
|||
currentValueRef.value = defaultValueRef.value; |
|||
table.emit?.('edit-cancel', unref(currentValueRef)); |
|||
} |
|||
|
|||
function onClickOutside() { |
|||
if (props.column?.editable || unref(getRowEditable)) { |
|||
return; |
|||
} |
|||
const component = unref(getComponent); |
|||
|
|||
if (component.includes('Input')) { |
|||
handleCancel(); |
|||
} |
|||
} |
|||
|
|||
// only ApiSelect |
|||
function handleOptionsChange(options: LabelValueOptions) { |
|||
optionsRef.value = options; |
|||
} |
|||
|
|||
function initCbs(cbs: 'submitCbs' | 'validCbs' | 'cancelCbs', handle: Fn) { |
|||
if (props.record) { |
|||
/* eslint-disable */ |
|||
isArray(props.record[cbs]) |
|||
? props.record[cbs].push(handle) |
|||
: (props.record[cbs] = [handle]); |
|||
} |
|||
} |
|||
|
|||
if (props.record) { |
|||
initCbs('submitCbs', handleSubmit); |
|||
initCbs('validCbs', handleSubmiRule); |
|||
initCbs('cancelCbs', handleCancel); |
|||
|
|||
/* eslint-disable */ |
|||
props.record.onCancelEdit = () => { |
|||
isArray(props.record?.cancelCbs) && props.record?.cancelCbs.forEach((fn) => fn()); |
|||
}; |
|||
/* eslint-disable */ |
|||
props.record.onSubmitEdit = async () => { |
|||
if (isArray(props.record?.submitCbs)) { |
|||
const validFns = props.record?.validCbs || []; |
|||
|
|||
const res = await Promise.all(validFns.map((fn) => fn())); |
|||
const pass = res.every((item) => !!item); |
|||
|
|||
if (!pass) return; |
|||
const submitFns = props.record?.submitCbs || []; |
|||
submitFns.forEach((fn) => fn()); |
|||
return true; |
|||
} |
|||
// isArray(props.record?.submitCbs) && props.record?.submitCbs.forEach((fn) => fn()); |
|||
}; |
|||
} |
|||
|
|||
return { |
|||
isEdit, |
|||
prefixCls, |
|||
handleEdit, |
|||
currentValueRef, |
|||
handleSubmit, |
|||
handleChange, |
|||
handleCancel, |
|||
elRef, |
|||
getComponent, |
|||
getRule, |
|||
onClickOutside, |
|||
ruleMessage, |
|||
getRuleVisible, |
|||
getComponentProps, |
|||
handleOptionsChange, |
|||
getWrapperStyle, |
|||
getRowEditable, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style lang="less"> |
|||
@prefix-cls: ~'@{namespace}-editable-cell'; |
|||
|
|||
.edit-cell-rule-popover { |
|||
// .ant-popover-arrow { |
|||
// // border-color: transparent @error-color @error-color transparent !important; |
|||
// } |
|||
|
|||
.ant-popover-inner-content { |
|||
padding: 4px 8px; |
|||
color: @error-color; |
|||
// border: 1px solid @error-color; |
|||
border-radius: 2px; |
|||
} |
|||
} |
|||
.@{prefix-cls} { |
|||
position: relative; |
|||
|
|||
&__wrapper { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
&__icon { |
|||
&:hover { |
|||
transform: scale(1.2); |
|||
|
|||
svg { |
|||
color: @primary-color; |
|||
} |
|||
} |
|||
} |
|||
|
|||
&__normal { |
|||
padding-right: 48px; |
|||
|
|||
&-icon { |
|||
position: absolute; |
|||
top: 4px; |
|||
right: 0; |
|||
display: none; |
|||
width: 20px; |
|||
cursor: pointer; |
|||
} |
|||
} |
|||
|
|||
&:hover { |
|||
.@{prefix-cls}__normal-icon { |
|||
display: inline-block; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,26 @@ |
|||
import { ComponentType } from '../../types/componentType'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
/** |
|||
* @description: 生成placeholder |
|||
*/ |
|||
export function createPlaceholderMessage(component: ComponentType) { |
|||
if (component.includes('Input')) { |
|||
return t('component.form.input'); |
|||
} |
|||
if (component.includes('Picker')) { |
|||
return t('component.form.choose'); |
|||
} |
|||
|
|||
if ( |
|||
component.includes('Select') || |
|||
component.includes('Checkbox') || |
|||
component.includes('Radio') || |
|||
component.includes('Switch') |
|||
) { |
|||
return t('component.form.choose'); |
|||
} |
|||
return ''; |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
import type { BasicColumn } from '/@/components/Table/src/types/table'; |
|||
|
|||
import { h } from 'vue'; |
|||
|
|||
import EditableCell from './EditableCell.vue'; |
|||
|
|||
interface Params { |
|||
text: string; |
|||
record: Recordable; |
|||
index: number; |
|||
} |
|||
|
|||
export function renderEditCell(column: BasicColumn) { |
|||
return ({ text: value, record, index }: Params) => { |
|||
record.onEdit = async (edit: boolean, submit = false) => { |
|||
if (!submit) { |
|||
record.editable = edit; |
|||
} |
|||
|
|||
if (!edit && submit) { |
|||
const res = await record.onSubmitEdit?.(); |
|||
if (res) { |
|||
record.editable = false; |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
// cancel
|
|||
if (!edit && !submit) { |
|||
record.onCancelEdit?.(); |
|||
} |
|||
return true; |
|||
}; |
|||
|
|||
return h(EditableCell, { |
|||
value, |
|||
record, |
|||
column, |
|||
index, |
|||
}); |
|||
}; |
|||
} |
|||
|
|||
export type EditRecordRow<T = Hash<any>> = { |
|||
onEdit: (editable: boolean, submit?: boolean) => Promise<boolean>; |
|||
editable: boolean; |
|||
onCancel: Fn; |
|||
onSubmit: Fn; |
|||
submitCbs: Fn[]; |
|||
cancelCbs: Fn[]; |
|||
validCbs: Fn[]; |
|||
} & T; |
|||
@ -1,241 +0,0 @@ |
|||
import '../style/editable-cell.less'; |
|||
|
|||
import { defineComponent, PropType, ref, unref, nextTick, watchEffect } from 'vue'; |
|||
import { ClickOutSide } from '/@/components/ClickOutSide'; |
|||
|
|||
import { RenderEditableCellParams } from '../types/table'; |
|||
import { ComponentType } from '../types/componentType'; |
|||
|
|||
import { componentMap } from '../componentMap'; |
|||
import { isString, isBoolean, isArray } from '/@/utils/is'; |
|||
import { FormOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons-vue'; |
|||
|
|||
const prefixCls = 'editable-cell'; |
|||
const EditableCell = defineComponent({ |
|||
name: 'EditableCell', |
|||
props: { |
|||
value: { |
|||
type: String as PropType<string>, |
|||
default: '', |
|||
}, |
|||
componentProps: { |
|||
type: Object as PropType<any>, |
|||
default: null, |
|||
}, |
|||
|
|||
dataKey: { |
|||
type: String as PropType<string>, |
|||
default: '', |
|||
}, |
|||
|
|||
dataIndex: { |
|||
type: String as PropType<string>, |
|||
default: '', |
|||
}, |
|||
|
|||
component: { |
|||
type: String as PropType<ComponentType>, |
|||
default: 'Input', |
|||
}, |
|||
editable: { |
|||
type: Boolean as PropType<boolean>, |
|||
default: false, |
|||
}, |
|||
editRow: { |
|||
type: Boolean as PropType<boolean>, |
|||
default: false, |
|||
}, |
|||
record: { |
|||
type: Object as PropType<EditRecordRow>, |
|||
}, |
|||
placeholder: { |
|||
type: String as PropType<string>, |
|||
default: '', |
|||
}, |
|||
}, |
|||
emits: ['submit', 'cancel'], |
|||
setup(props, { attrs, emit }) { |
|||
const elRef = ref<any>(null); |
|||
|
|||
const isEditRef = ref(false); |
|||
const currentValueRef = ref<string | boolean>(props.value); |
|||
const defaultValueRef = ref<string | boolean>(props.value); |
|||
|
|||
watchEffect(() => { |
|||
defaultValueRef.value = props.value; |
|||
if (isBoolean(props.editable)) { |
|||
isEditRef.value = props.editable; |
|||
} |
|||
}); |
|||
|
|||
function handleChange(e: any) { |
|||
if (e && e.target && Reflect.has(e.target, 'value')) { |
|||
currentValueRef.value = (e as ChangeEvent).target.value; |
|||
} |
|||
if (isString(e) || isBoolean(e)) { |
|||
currentValueRef.value = e; |
|||
} |
|||
} |
|||
|
|||
function handleEdit() { |
|||
isEditRef.value = true; |
|||
nextTick(() => { |
|||
const el = unref(elRef); |
|||
el && el.focus(); |
|||
}); |
|||
} |
|||
|
|||
function handleCancel() { |
|||
isEditRef.value = false; |
|||
currentValueRef.value = defaultValueRef.value; |
|||
emit('cancel'); |
|||
} |
|||
|
|||
if (props.record) { |
|||
/* eslint-disable */ |
|||
isArray(props.record.submitCbs) |
|||
? props.record.submitCbs.push(handleSubmit) |
|||
: (props.record.submitCbs = [handleSubmit]); |
|||
/* eslint-disable */ |
|||
isArray(props.record.cancelCbs) |
|||
? props.record.cancelCbs.push(handleCancel) |
|||
: (props.record.cancelCbs = [handleCancel]); |
|||
|
|||
/* eslint-disable */ |
|||
props.record.onCancel = () => { |
|||
isArray(props.record?.cancelCbs) && props.record?.cancelCbs.forEach((fn) => fn()); |
|||
}; |
|||
/* eslint-disable */ |
|||
props.record.onSubmit = () => { |
|||
isArray(props.record?.submitCbs) && props.record?.submitCbs.forEach((fn) => fn()); |
|||
}; |
|||
} |
|||
|
|||
function handleSubmit() { |
|||
const { dataKey, dataIndex } = props; |
|||
if (!dataKey || !dataIndex) return; |
|||
|
|||
if (props.record) { |
|||
/* eslint-disable */ |
|||
props.record[dataIndex] = unref(currentValueRef) as string; |
|||
} |
|||
isEditRef.value = false; |
|||
} |
|||
|
|||
function onClickOutside() { |
|||
if (props.editRow) return; |
|||
const { component } = props; |
|||
|
|||
if (component && component.includes('Input')) { |
|||
handleCancel(); |
|||
} |
|||
} |
|||
|
|||
function renderValue() { |
|||
const { value } = props; |
|||
if (props.editRow) { |
|||
return !unref(isEditRef) ? value : null; |
|||
} |
|||
return ( |
|||
!unref(isEditRef) && ( |
|||
<div class={`${prefixCls}__normal`} onClick={handleEdit}> |
|||
{value} |
|||
<FormOutlined class={`${prefixCls}__normal-icon`} /> |
|||
</div> |
|||
) |
|||
); |
|||
} |
|||
return () => { |
|||
const { component, componentProps = {} } = props; |
|||
|
|||
const Comp = componentMap.get(component!) as any; |
|||
return ( |
|||
<div class={prefixCls}> |
|||
{unref(isEditRef) && ( |
|||
<ClickOutSide onClickOutside={onClickOutside}> |
|||
{() => ( |
|||
<div class={`${prefixCls}__wrapper`}> |
|||
<Comp |
|||
placeholder={props.placeholder} |
|||
{...{ |
|||
...attrs, |
|||
...componentProps, |
|||
}} |
|||
style={{ width: 'calc(100% - 48px)' }} |
|||
ref={elRef} |
|||
value={unref(currentValueRef)} |
|||
size="small" |
|||
onChange={handleChange} |
|||
onPressEnter={handleSubmit} |
|||
/> |
|||
{!props.editRow && ( |
|||
<div class={`${prefixCls}__action`}> |
|||
<CheckOutlined |
|||
class={[`${prefixCls}__icon`, 'mx-2']} |
|||
onClick={handleSubmit} |
|||
/> |
|||
<CloseOutlined class={[`${prefixCls}__icon `]} onClick={handleCancel} /> |
|||
</div> |
|||
)} |
|||
</div> |
|||
)} |
|||
</ClickOutSide> |
|||
)} |
|||
{renderValue()} |
|||
</div> |
|||
); |
|||
}; |
|||
}, |
|||
}); |
|||
|
|||
export function renderEditableCell({ |
|||
dataIndex, |
|||
component, |
|||
componentProps = {}, |
|||
placeholder, |
|||
}: RenderEditableCellParams) { |
|||
return ({ text, record }: { text: string; record: EditRecordRow }) => { |
|||
return ( |
|||
<EditableCell |
|||
{...componentProps} |
|||
placeholder={placeholder} |
|||
value={text} |
|||
record={record} |
|||
dataKey={record.key} |
|||
dataIndex={dataIndex} |
|||
component={component} |
|||
/> |
|||
); |
|||
}; |
|||
} |
|||
|
|||
export function renderEditableRow({ |
|||
dataIndex, |
|||
component, |
|||
componentProps = {}, |
|||
placeholder, |
|||
}: RenderEditableCellParams) { |
|||
return ({ text, record }: { text: string; record: EditRecordRow }) => { |
|||
return ( |
|||
<EditableCell |
|||
{...componentProps} |
|||
value={text} |
|||
placeholder={placeholder} |
|||
editRow={true} |
|||
editable={record.editable} |
|||
dataKey={record.key} |
|||
record={record} |
|||
dataIndex={dataIndex} |
|||
component={component} |
|||
/> |
|||
); |
|||
}; |
|||
} |
|||
|
|||
export type EditRecordRow<T = Hash<any>> = { |
|||
editable: boolean; |
|||
onCancel: Fn; |
|||
onSubmit: Fn; |
|||
submitCbs: Fn[]; |
|||
cancelCbs: Fn[]; |
|||
} & T; |
|||
@ -1,14 +0,0 @@ |
|||
import { BasicArrow } from '/@/components/Basic'; |
|||
|
|||
export default () => { |
|||
return (props: Recordable) => { |
|||
return ( |
|||
<BasicArrow |
|||
onClick={(e: Event) => { |
|||
props.onExpand(props.record, e); |
|||
}} |
|||
expand={props.expanded} |
|||
/> |
|||
); |
|||
}; |
|||
}; |
|||
@ -1,39 +0,0 @@ |
|||
@prefix-cls: ~'editable-cell'; |
|||
|
|||
.@{prefix-cls} { |
|||
position: relative; |
|||
|
|||
&__wrapper { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
&__icon { |
|||
&:hover { |
|||
transform: scale(1.2); |
|||
|
|||
svg { |
|||
color: @primary-color; |
|||
} |
|||
} |
|||
} |
|||
|
|||
&__normal { |
|||
padding-right: 48px; |
|||
|
|||
&-icon { |
|||
position: absolute; |
|||
top: 4px; |
|||
right: 0; |
|||
display: none; |
|||
width: 20px; |
|||
cursor: pointer; |
|||
} |
|||
} |
|||
|
|||
&:hover { |
|||
.@{prefix-cls}__normal-icon { |
|||
display: inline-block; |
|||
} |
|||
} |
|||
} |
|||
@ -1,8 +1,7 @@ |
|||
export type ComponentType = |
|||
| 'Input' |
|||
| 'InputPassword' |
|||
| 'InputNumber' |
|||
| 'Select' |
|||
| 'ApiSelect' |
|||
| 'Checkbox' |
|||
| 'CheckboxGroup' |
|||
| 'Switch'; |
|||
|
|||
Loading…
Reference in new issue