Skip to content
This repository has been archived by the owner on Feb 2, 2024. It is now read-only.

Momo poppy/fix select #40

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/auto-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ jobs:
steps:
- name: CheckOut Code
uses: actions/checkout@master
with:
ref: release

- name: Setup Node
uses: actions/setup-node@v3
Expand Down
56 changes: 46 additions & 10 deletions src/input/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/**
* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/

import { isSame } from '@opentiny/vue-renderless/common/type'

Expand Down Expand Up @@ -315,3 +315,39 @@ export const hasSelection = (api) => () => {
const input = api.getInput()
return input && input.selectionStart !== input.selectionEnd
}

export const handleEnterDisplayOnlyContent = ({ state, props }) => ($event, type) => {
const target = $event.target

if (target && (target.scrollWidth > target.offsetWidth || (type === 'textarea' && target.scrollHeight > target.offsetHeight))) {
state.displayOnlyTooltip = props.displayContent || state.nativeInputValue
}
}

export const hiddenPassword = ({ state, props }) => () => {
let str = ''
const password = props.displayOnlyContent || state.nativeInputValue

for (let i = 0; i < password.length; i++) {
str += '*'
}

return str
}

export const dispatchDisplayedValue = ({ state, props, dispatch, api }) => () => {
if (state.isDisplayOnly) {
dispatch('FormItem', 'displayed-value-changed', {
type: props.type || 'text',
val: api.getDisplayedValue()
})
}
}

export const getDisplayedValue = ({ state, props }) => () => {
if (props.type === 'password') {
return state.hiddenPassword || '-'
} else {
return props.displayOnlyContent || state.nativeInputValue || '-'
}
}
57 changes: 42 additions & 15 deletions src/input/vue.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/**
* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/

import {
blur,
Expand All @@ -34,7 +34,11 @@ import {
handlePasswordVisible,
handleCompositionStart,
handleCompositionUpdate,
hasSelection
hasSelection,
handleEnterDisplayOnlyContent,
hiddenPassword,
dispatchDisplayedValue,
getDisplayedValue
} from './index'
import useStorageBox from '@opentiny/vue-renderless/tall-storage/vue-storage-box'

Expand Down Expand Up @@ -66,7 +70,9 @@ export const api = [
'selectedMemory',
'storageData',
'isMemoryStorage',
'hasSelection'
'hasSelection',
'handleEnterDisplayOnlyContent',
'hiddenPassword'
]

const initState = ({ reactive, computed, mode, props, parent, constants }) => {
Expand Down Expand Up @@ -105,7 +111,12 @@ const initState = ({ reactive, computed, mode, props, parent, constants }) => {
!state.inputDisabled &&
!props.readonly &&
!props.showPassword
)
),
isDisplayOnly: computed(
() => (props.displayOnly || (parent.tinyForm || {}).displayOnly) && ['text', 'textarea', 'password', 'number'].includes(props.type)
),
displayOnlyTooltip: '',
hiddenPassword: computed(() => api.hiddenPassword())
})

return state
Expand All @@ -125,7 +136,9 @@ const initApi = ({ api, state, dispatch, broadcast, emit, refs, props, CLASS_PRE
getSuffixVisible: getSuffixVisible({ parent, props, state }),
calculateNodeStyling: calculateNodeStyling(),
handleCompositionStart: handleCompositionStart(state),
handleCompositionUpdate: handleCompositionUpdate(state)
handleCompositionUpdate: handleCompositionUpdate(state),
dispatchDisplayedValue: dispatchDisplayedValue({ state, props, dispatch, api }),
getDisplayedValue: getDisplayedValue({ state, props })
})
}

Expand Down Expand Up @@ -161,7 +174,9 @@ const mergeApi = ({ storages, api, componentName, props, emit, eventName, nextTi
setNativeInputValue: setNativeInputValue({ api, state }),
handleCompositionEnd: handleCompositionEnd({ api, state }),
handlePasswordVisible: handlePasswordVisible({ api, nextTick, state }),
hasSelection: hasSelection(api)
hasSelection: hasSelection(api),
handleEnterDisplayOnlyContent: handleEnterDisplayOnlyContent({ state, props }),
hiddenPassword: hiddenPassword({ state, props })
})
}

Expand Down Expand Up @@ -206,6 +221,18 @@ const initWatch = ({ watch, state, api, props, nextTick, emit, componentName, ev
}
)

watch(
() => state.isDisplayOnly,
() => {
nextTick(() => {
api.setNativeInputValue()
api.resizeTextarea()
api.updateIconOffset()
api.dispatchDisplayedValue()
})
}
)

watch(
() => state.sheetvalue,
(value) => api.watchFormSelect(value),
Expand Down
66 changes: 38 additions & 28 deletions src/select/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import { find } from '@opentiny/vue-renderless/common/array'
import { getObj, isEqual } from '@opentiny/vue-renderless/common/object'
import { hasClass } from '@opentiny/vue-renderless/common/deps/dom'
import { isKorean } from '@opentiny/vue-renderless/common/string'
import scrollIntoView from '@opentiny/vue-renderless/common/deps/scroll-into-view'
import PopupManager from '@opentiny/vue-renderless/common/deps/popup-manager'
Expand Down Expand Up @@ -299,41 +300,49 @@ const getResultOfSetSelected = ({ props, isGrid, isTree, api }) => {
return result
}

export const setSelected = ({ api, constants, nextTick, props, refs, state }) => () => {
export const setGridOrTreeSelected = ({ props, state, vm, isTree, api }) => () => {
if (!props.modelValue) {
state.selectedLabel = ''
state.selected = {}
state.currentKey = ''
vm.$refs.selectGrid && vm.$refs.selectGrid.clearRadioRow()
vm.$refs.selectTree && vm.$refs.selectTree.setCurrentKey && vm.$refs.selectTree.setCurrentKey(null)
return
}

const isRemote = state.filterOrSearch && props.remote && typeof props.remoteMethod === 'function'
const nestdata = isRemote ? state.remoteData : isTree ? api.getTreeData(state.treeData) : state.gridData
const data = find(nestdata, (item) => props.modelValue == item[props.valueField])

if (isEmptyObject(data)) {
return
}

const obj = { ...data }
const label = data[props.textField]

obj.currentLabel = label
state.selectedLabel = label
state.selected = obj
state.currentKey = data[props.valueField]
}

export const setSelected = ({ api, constants, nextTick, props, vm, state }) => () => {
const isTree = props.renderType === constants.TYPE.Tree
const isGrid = props.renderType === constants.TYPE.Grid

if (!props.multiple) {
if (isGrid || isTree) {
if (!props.modelValue) {
state.selectedLabel = ''
state.selected = {}
state.currentKey = ''
refs.selectGrid && refs.selectGrid.clearRadioRow()
refs.selectTree && refs.selectTree.setCurrentKey && refs.selectTree.setCurrentKey(null)
return
}

const isRemote = state.filterOrSearch && props.remote && typeof props.remoteMethod === 'function'
const nestdata = isRemote ? state.remoteData : isTree ? api.getTreeData(state.treeData) : state.gridData
const data = find(nestdata, (item) => props.modelValue == item[props.valueField])

if (isEmptyObject(data)) {
return
}

const obj = { ...data }
const label = data[props.textField]
obj.currentLabel = label
state.selectedLabel = label
state.selected = obj
state.currentKey = data[props.valueField]
setGridOrTreeSelected({ props, state, vm, isTree, api })
} else {
const option = getOptionOfSetSelected({ api, props })
nextTick(() => {
state.selected = option
state.selectedLabel = option.state.currentLabel || option.currentLabel
props.filterable && (state.query = state.selectedLabel)

if (state.filterOrSearch && !props.shape && !props.allowCreate) {
state.query = state.selectedLabel
}
})
}

Expand All @@ -344,7 +353,7 @@ export const setSelected = ({ api, constants, nextTick, props, refs, state }) =>

state.selectCls = result.length ? (result.length === state.options.length ? 'checked-sur' : 'halfselect') : 'check'
state.selected = result
refs.selectTree && refs.selectTree.setCheckedNodes && refs.selectTree.setCheckedNodes(state.selected)
vm.$refs.selectTree && vm.$refs.selectTree.setCheckedNodes && vm.$refs.selectTree.setCheckedNodes(state.selected)
state.tips = state.selected.map((item) => (item.state ? item.state.currentLabel : item.currentLabel)).join(',')

nextTick(api.resetInputHeight)
Expand Down Expand Up @@ -527,8 +536,9 @@ export const resetInputHeight = ({ constants, nextTick, props, refs, state }) =>
return
}

let inputChildNodes = refs.reference.$el.childNodes
let input = [].filter.call(inputChildNodes, (item) => item.tagName === 'INPUT')[0]
const inputChildNodes = refs.reference.$el.childNodes
const inputContainer = [].filter.call(inputChildNodes, (item) => hasClass(item, 'tiny-input-display-only'))[0]
const input = inputContainer && inputContainer.querySelector('input')
const tags = refs.tags

if (!input) {
Expand Down
21 changes: 15 additions & 6 deletions src/select/vue.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ const addApi = ({ api, props, state, refs, emit, constants, parent, nextTick, di
watchValue: watchValue({ api, constants, dispatch, props, refs, state }),
toHide: toHide({ constants, state, props, vm, api }),
toVisible: toVisible({ constants, state, props, vm, api, nextTick }),
setSelected: setSelected({ api, constants, nextTick, props, refs, state }),
setSelected: setSelected({ api, constants, nextTick, props, vm, state }),
selectOption: selectOption({ api, state, props }),
handleResize: handleResize({ api, props }),
watchOptions: watchOptions({ api, constants, nextTick, parent, props, state }),
Expand Down Expand Up @@ -335,35 +335,44 @@ const initApi = ({ api, props, state, refs, emit, maskState, constants, parent,
const addWatch = ({ watch, props, api, state }) => {
watch(() => [...state.options], api.watchOptions)

watch(() => state.gridData, api.setSelected, { immediate: true })
if (props.renderType === 'grid') {
watch(() => state.gridData, api.setSelected, { immediate: true })
}

watch(() => state.treeData, api.setSelected, { immediate: true })
if (props.renderType === 'tree') {
watch(() => state.treeData, api.setSelected, { immediate: true })
}

watch(() => state.hoverIndex, api.watchHoverIndex)

props.options && watch(() => props.options, api.watchPropsOption, { immediate: true, deep: true })
if (props.options) {
watch(() => props.options, api.watchPropsOption, { immediate: true, deep: true })
}


watch(() => state.optimizeOpts, api.watchOptimizeOpts)
}

const initWatch = ({ watch, props, api, state, nextTick, refs }) => {
props.treeOp.data &&
if (props.renderType === 'tree' && props.treeOp.data) {
watch(
() => props.treeOp.data,
(data) => {
state.treeData = data
},
{ immediate: true, deep: true }
)
}

props.gridOp.data &&
if (props.renderType === 'grid' && props.gridOp.data) {
watch(
() => props.gridOp.data,
(data) => {
state.gridData = data
},
{ immediate: true, deep: true }
)
}

watch(
() => state.selectDisabled,
Expand Down