forked from opentiny/tiny-vue
feat(components):[color-picker] add props size、predefine and history (#711)
* feat(components):[color-picker] add props size、predefine and history * fix(e2e):[color-picker] Add e2e tests for size, predefine, and history in color-picker * fix(e2e):[color-picker] fix e2e tests bug * add key
This commit is contained in:
parent
32cca5ede1
commit
fc6c6cb2c0
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<div>
|
||||
<ColorPicker v-model="color" :history="history" />
|
||||
<Button @click="addHistoryColor">Append history color</Button>
|
||||
<Button @click="popHistoryColor">Pop history color</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { ColorPicker, Button } from '@opentiny/vue';
|
||||
const color = ref('#66ccff');
|
||||
const history = ref(['#66ccff']);
|
||||
const randomHex = () => "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");
|
||||
const addHistoryColor = () => {
|
||||
history.value.push(
|
||||
randomHex()
|
||||
);
|
||||
}
|
||||
const popHistoryColor = () => {
|
||||
history.value.pop();
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,29 @@
|
|||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test('测试历史记录', async ({ page }) => {
|
||||
page.on('pageerror', (exception) => expect(exception).toBeNull())
|
||||
await page.goto('color-picker#history')
|
||||
await page.locator('.tiny-color-picker__trigger').click()
|
||||
await page.waitForSelector('.tiny-collapse-item__arrow')
|
||||
const arrow = page.locator('.tiny-collapse-item__arrow')
|
||||
await arrow.click()
|
||||
await expect(page.locator('.tiny-color-select-panel__history')).toHaveCount(1)
|
||||
await page.locator('.mr20.fw-bold').click()
|
||||
//用户行为更改历史记录测试
|
||||
await page.getByRole('button', { name: 'Append history color' }).click()
|
||||
await page.locator('.tiny-color-picker__trigger').click()
|
||||
await page.waitForSelector('.tiny-collapse-item__arrow')
|
||||
await page.locator('.tiny-collapse-item__arrow').click()
|
||||
await expect(page.locator('.tiny-color-select-panel__history .tiny-color-select-panel__history__color-block:nth-child(2)')).toBeVisible()
|
||||
//点击色块中心,并点击选择,历史记录增加1的测试
|
||||
const black = page.locator('.black')
|
||||
const center = await black.boundingBox()
|
||||
const x = center?.x ?? 0 + (center?.width ?? 0) / 2
|
||||
const y = center?.y ?? 0 + (center?.height ?? 0) / 2
|
||||
await black.click(x, y)
|
||||
await page.getByRole('button', { name: '选择' }).click()
|
||||
await page.locator('.tiny-color-picker__trigger').click()
|
||||
await page.waitForSelector('.tiny-collapse-item__arrow')
|
||||
await page.locator('.tiny-collapse-item__arrow').click()
|
||||
await expect(page.locator('.tiny-color-select-panel__history .tiny-color-select-panel__history__color-block:nth-child(3)')).toBeVisible()
|
||||
})
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<div>
|
||||
<tiny-color-picker v-model="color" :history="history" />
|
||||
<Button @click="addHistoryColor">Append history color</Button>
|
||||
<Button @click="popHistoryColor">Pop history color</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue';
|
||||
import { ColorPicker, Button } from '@opentiny/vue';
|
||||
export default {
|
||||
components: {
|
||||
TinyColorPicker: ColorPicker,
|
||||
Button
|
||||
},
|
||||
setup() {
|
||||
const color = ref('#66ccff');
|
||||
const history = ref(['#66ccff25']);
|
||||
const randomHex = () => "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");
|
||||
const addHistoryColor = () => {
|
||||
history.value.push(
|
||||
randomHex()
|
||||
);
|
||||
}
|
||||
const popHistoryColor = () => {
|
||||
history.value.pop();
|
||||
}
|
||||
return {
|
||||
color,
|
||||
history,
|
||||
addHistoryColor,
|
||||
popHistoryColor
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<div>
|
||||
<ColorPicker v-model="color" :predefine="predefine" />
|
||||
<Button @click="addPredefineColor">Append predefine color</Button>
|
||||
<Button @click="popPredefineColor">Pop predefine color</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { ColorPicker, Button } from '@opentiny/vue';
|
||||
const color = ref('#66ccff');
|
||||
const randomHex = () => "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");
|
||||
const predefine = ref(new Array(8).fill(0).map(() => randomHex()))
|
||||
const addPredefineColor = () => {
|
||||
predefine.value.push(
|
||||
randomHex()
|
||||
);
|
||||
}
|
||||
const popPredefineColor = () => {
|
||||
predefine.value.pop();
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test('测试预定义颜色', async ({ page }) => {
|
||||
page.on('pageerror', (exception) => expect(exception).toBeNull())
|
||||
await page.goto('color-picker#predefine')
|
||||
await page.locator('.tiny-color-picker__trigger').click()
|
||||
await page.waitForSelector('.tiny-collapse-item__arrow')
|
||||
const arrow = page.locator('.tiny-collapse-item__arrow')
|
||||
await arrow.click()
|
||||
await expect(page.locator('.tiny-color-select-panel__predefine .tiny-color-select-panel__predefine__color-block:nth-child(8)')).toBeVisible()
|
||||
await page.locator('.mr20.fw-bold').click()
|
||||
//用户行为预定义颜色测试
|
||||
await page.getByRole('button', { name: 'Append predefine color' }).click()
|
||||
await page.locator('.tiny-color-picker__trigger').click()
|
||||
await page.waitForSelector('.tiny-collapse-item__arrow')
|
||||
await page.locator('.tiny-collapse-item__arrow').click()
|
||||
await expect(page.locator('.tiny-color-select-panel__predefine .tiny-color-select-panel__predefine__color-block:nth-child(9)')).toBeVisible()
|
||||
})
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<div>
|
||||
<tiny-color-picker v-model="color" :predefine="predefine" />
|
||||
<Button @click="addPredefineColor">Append predefine color</Button>
|
||||
<Button @click="popPredefineColor">Pop predefine color</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue';
|
||||
import { ColorPicker, Button } from '@opentiny/vue';
|
||||
export default {
|
||||
components: {
|
||||
TinyColorPicker: ColorPicker,
|
||||
Button
|
||||
},
|
||||
setup() {
|
||||
const color = ref('#66ccff');
|
||||
const randomHex = () => "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");
|
||||
const predefine = ref(new Array(8).fill(0).map(() => randomHex()))
|
||||
const addPredefineColor = () => {
|
||||
predefine.value.push(
|
||||
randomHex()
|
||||
);
|
||||
}
|
||||
const popPredefineColor = () => {
|
||||
predefine.value.pop();
|
||||
}
|
||||
return {
|
||||
color,
|
||||
predefine,
|
||||
addPredefineColor,
|
||||
popPredefineColor
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div>
|
||||
<tiny-color-picker v-model="color" size="large" />
|
||||
<tiny-color-picker v-model="color" size="medium" />
|
||||
<tiny-color-picker v-model="color" size="small" />
|
||||
<tiny-color-picker v-model="color" size="mini" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ColorPicker as TinyColorPicker } from '@opentiny/vue'
|
||||
import { ref } from 'vue'
|
||||
const color = ref('#66ccff')
|
||||
</script>
|
|
@ -0,0 +1,10 @@
|
|||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test('测试尺寸', async ({ page }) => {
|
||||
page.on('pageerror', (exception) => expect(exception).toBeNull())
|
||||
await page.goto('color-picker#size')
|
||||
await expect(page.locator('.tiny-color-picker__trigger.tiny-color-picker--large')).toHaveCSS('width', '64px')
|
||||
await expect(page.locator('.tiny-color-picker__trigger.tiny-color-picker--medium')).toHaveCSS('width', '48px')
|
||||
await expect(page.locator('.tiny-color-picker__trigger.tiny-color-picker--small')).toHaveCSS('width', '36px')
|
||||
await expect(page.locator('.tiny-color-picker__trigger.tiny-color-picker--mini')).toHaveCSS('width', '24px')
|
||||
})
|
|
@ -0,0 +1,22 @@
|
|||
<template>
|
||||
<div>
|
||||
<tiny-color-picker v-model="color" size="large" />
|
||||
<tiny-color-picker v-model="color" size="medium" />
|
||||
<tiny-color-picker v-model="color" size="small" />
|
||||
<tiny-color-picker v-model="color" size="mini" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ColorPicker } from '@opentiny/vue'
|
||||
export default {
|
||||
components: {
|
||||
TinyColorPicker: ColorPicker
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
color: '#66ccff',
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -8,6 +8,12 @@ export default {
|
|||
'desc': { 'zh-CN': '详细用法参考如下示例', 'en-US': 'For details, see the following example.' },
|
||||
'codeFiles': ['base.vue']
|
||||
},
|
||||
{
|
||||
'demoId': 'size',
|
||||
'name': { 'zh-CN': '尺寸设置', 'en-US': 'Size Setting' },
|
||||
'desc': { 'zh-CN': '通过 size 属性设置large 、medium 、small 、mini 四种不同大小尺寸。不设置时为默认尺寸。', 'en-US': 'For details, see the following example.' },
|
||||
'codeFiles': ['size.vue']
|
||||
},
|
||||
{
|
||||
'demoId': 'event',
|
||||
'name': { 'zh-CN': '事件触发', 'en-US': 'event' },
|
||||
|
@ -20,6 +26,27 @@ export default {
|
|||
'desc': { 'zh-CN': 'Alpha选择', 'en-US': 'Alpha select.' },
|
||||
'codeFiles': ['alpha.vue']
|
||||
},
|
||||
{
|
||||
'demoId': 'history',
|
||||
'name': { 'zh-CN': '历史记录', 'en-US': 'history' },
|
||||
'desc': {
|
||||
'zh-CN': '当history不为undefined时, 将会启用历史记录功能。当用户点击确认时, 将会自动将颜色插入到history. 用户行为会更改历史记录, 外部可以更改历史记录',
|
||||
'en-US': 'When history is not undefined, the history function will be enabled. When the user clicks confirm, the color will automatically be inserted into the history User behavior can change history, and external users can also change history'
|
||||
},
|
||||
'codeFiles': ['history.vue']
|
||||
},
|
||||
{
|
||||
'demoId': 'predefine',
|
||||
'name': {
|
||||
'zh-CN': '预定义颜色',
|
||||
'en-US': 'predefine color'
|
||||
},
|
||||
'desc': {
|
||||
'zh-CN': '提供给一些定义颜色, 用户行为不会更改预定义颜色, 但外部可以更改',
|
||||
'en-US': 'Provide some defined colors, user behavior will not change the predefined colors, but can be changed externally'
|
||||
},
|
||||
'codeFiles': ['predefine.vue']
|
||||
},
|
||||
{
|
||||
'demoId': 'default-visible',
|
||||
'name': { 'zh-CN': '默认显示', 'en-US': 'default-visible' },
|
||||
|
@ -64,6 +91,16 @@ export default {
|
|||
},
|
||||
demoId: 'default-visible'
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
type: 'string',
|
||||
defaultValue: '',
|
||||
desc: {
|
||||
'zh-CN': '定义color-picker尺寸;该属性的可选值为 large / medium / small / mini',
|
||||
'en-US': 'Define color-picker dimensions; The optional values for this attribute are large/medium/small/mini'
|
||||
},
|
||||
demoId: 'size'
|
||||
},
|
||||
{
|
||||
name: 'alpha',
|
||||
type: 'boolean',
|
||||
|
@ -73,6 +110,26 @@ export default {
|
|||
'en-US': 'enable alpha select or not'
|
||||
},
|
||||
demoId: 'enable-alpha'
|
||||
},
|
||||
{
|
||||
name: 'history',
|
||||
type: 'string[] | undefined',
|
||||
defaultValue: 'undefined',
|
||||
desc: {
|
||||
'zh-CN': '启用历史记录',
|
||||
'en-US': 'enable history or not'
|
||||
},
|
||||
demoId: 'history'
|
||||
},
|
||||
{
|
||||
name: 'predefine',
|
||||
type: 'string[] | undefined',
|
||||
defaultValue: 'undefined',
|
||||
desc: {
|
||||
'zh-CN': '启用预定义颜色',
|
||||
'en-US': 'enable predefine or not'
|
||||
},
|
||||
demoId: 'predefine'
|
||||
}
|
||||
],
|
||||
'events': [
|
||||
|
|
|
@ -16,7 +16,7 @@ export const api = [
|
|||
]
|
||||
|
||||
export const renderless = (props, context, { emit }) => {
|
||||
const { modelValue, visible } = context.toRefs(props)
|
||||
const { modelValue, visible, predefine, size, history } = context.toRefs(props)
|
||||
const hex = context.ref(modelValue.value ?? 'transparent')
|
||||
const res = context.ref(modelValue.value ?? 'transparent')
|
||||
const triggerBg = context.ref(modelValue.value ?? 'transparent')
|
||||
|
@ -25,6 +25,12 @@ export const renderless = (props, context, { emit }) => {
|
|||
const changeVisible = (state: boolean) => {
|
||||
isShow.value = state
|
||||
}
|
||||
const stack: Ref<string[]> = context.ref(
|
||||
[...(history?.value ?? [])]
|
||||
)
|
||||
const predefineStack: Ref<string[]> = context.ref(
|
||||
[...(predefine?.value ?? [])]
|
||||
)
|
||||
const color = new Color(hex.value, props.alpha)
|
||||
const state = context.reactive({
|
||||
isShow,
|
||||
|
@ -32,8 +38,17 @@ export const renderless = (props, context, { emit }) => {
|
|||
color,
|
||||
triggerBg,
|
||||
defaultValue: modelValue,
|
||||
res
|
||||
res,
|
||||
predefineStack,
|
||||
size: size ?? '',
|
||||
stack
|
||||
})
|
||||
context.watch(predefine, (newPredefine: string[]) => {
|
||||
predefineStack.value = [...newPredefine];
|
||||
}, { deep: true })
|
||||
context.watch(history, (newHistory: string[]) => {
|
||||
stack.value = [...newHistory]
|
||||
}, { deep: true })
|
||||
context.watch(modelValue, (newValue) => {
|
||||
hex.value = newValue
|
||||
res.value = newValue
|
||||
|
|
|
@ -126,4 +126,23 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
&--large {
|
||||
width: var(--ti-color-picker-size-large-width);
|
||||
height: var(--ti-color-picker-size-large-height);
|
||||
}
|
||||
|
||||
&--small {
|
||||
width: var(--ti-color-picker-size-small-width);
|
||||
height: var(--ti-color-picker-size-small-height);
|
||||
}
|
||||
|
||||
&--medium {
|
||||
width: var(--ti-color-picker-size-medium-width);
|
||||
height: var(--ti-color-picker-size-medium-height);
|
||||
}
|
||||
|
||||
&--mini {
|
||||
width: var(--ti-color-picker-size-mini-width);
|
||||
height: var(--ti-color-picker-size-mini-height);
|
||||
}
|
||||
}
|
|
@ -10,4 +10,24 @@
|
|||
--ti-color-picker-shadow: var(--ti-common-shadow-2-down);
|
||||
--ti-color-picker__select__wrapper-zindex: 1000;
|
||||
--ti-color-picker__wrapper-bg: var(--ti-common-color-bg-white-emphasize);
|
||||
|
||||
// 超大尺寸高度
|
||||
--ti-color-picker-size-large-height: var(--ti-common-size-16x);
|
||||
// 超大尺寸宽度
|
||||
--ti-color-picker-size-large-width: var(--ti-common-size-16x);
|
||||
|
||||
// 中等尺寸高度
|
||||
--ti-color-picker-size-medium-height: var(--ti-common-size-12x);
|
||||
// 中等尺寸最小宽度
|
||||
--ti-color-picker-size-medium-width: var(--ti-common-size-12x);
|
||||
|
||||
// 小型高度
|
||||
--ti-color-picker-size-small-height: var(--ti-common-size-9x);
|
||||
// 小尺寸宽度
|
||||
--ti-color-picker-size-small-width: var(--ti-common-size-9x);
|
||||
|
||||
// 迷你尺寸按钮高度
|
||||
--ti-color-picker-size-mini-height: var(--ti-common-size-6x);
|
||||
// 迷你尺寸宽度
|
||||
--ti-color-picker-size-mini-width: var(--ti-common-size-6x);
|
||||
}
|
|
@ -13,7 +13,16 @@ export default defineComponent({
|
|||
},
|
||||
modelValue: String,
|
||||
visible: Boolean,
|
||||
alpha: Boolean
|
||||
alpha: Boolean,
|
||||
predefine: Array,
|
||||
history: Array,
|
||||
size: {
|
||||
type: String,
|
||||
default: '',
|
||||
validator(val: string) {
|
||||
return ['large', 'medium', 'small', 'mini', ''].includes(val)
|
||||
}
|
||||
},
|
||||
},
|
||||
setup(props, context) {
|
||||
return $setup({ props, context, template })
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
<template>
|
||||
<div class="tiny-color-picker__trigger" @click="() => changeVisible(!state.isShow)">
|
||||
<div
|
||||
:class="[{
|
||||
'tiny-color-picker__trigger': true
|
||||
},
|
||||
state.size ? 'tiny-color-picker--' + state.size : '',
|
||||
]"
|
||||
@click="() => changeVisible(!state.isShow)"
|
||||
>
|
||||
<div
|
||||
class="tiny-color-picker__inner"
|
||||
:style="{
|
||||
|
@ -17,6 +24,8 @@
|
|||
v-model="state.hex"
|
||||
:visible="state.isShow"
|
||||
:alpha="alpha"
|
||||
:predefine="state.predefineStack.length > 0 ? state.predefineStack : undefined"
|
||||
:history="state.stack.length > 0 ? state.stack : undefined"
|
||||
/>
|
||||
</Transition>
|
||||
</div>
|
||||
|
@ -31,13 +40,13 @@ import '@opentiny/vue-theme/color-picker/index.less'
|
|||
|
||||
export default defineComponent({
|
||||
emits: ['update:modelValue', 'confirm', 'cancel'],
|
||||
props: [...props, 'modelValue', 'visible', 'alpha'],
|
||||
props: [...props, 'modelValue', 'visible', 'alpha', 'predefine', 'history', 'size'],
|
||||
components: {
|
||||
IconChevronDown: IconChevronDown(),
|
||||
ColorSelect: colorSelect
|
||||
},
|
||||
setup(props, context) {
|
||||
return setup({ props, context, renderless, api })
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue