-
Notifications
You must be signed in to change notification settings - Fork 278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: [color-select-panel] color select panel #2529
Changes from all commits
af9ade1
69de127
6e706cf
841d290
3a655e9
4f9b39f
7f567fb
6a39b84
99f3c5f
94e15c1
fafc36c
a758607
d6a0402
9174bec
94fee8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,38 @@ | ||||||||||||||||||||||||||||||||||
<template> | ||||||||||||||||||||||||||||||||||
<div> | ||||||||||||||||||||||||||||||||||
<tiny-button @click="changeVisible">Show Color select panel</tiny-button> | ||||||||||||||||||||||||||||||||||
<div style="position: relative"> | ||||||||||||||||||||||||||||||||||
<tiny-color-select-panel | ||||||||||||||||||||||||||||||||||
v-model="color" | ||||||||||||||||||||||||||||||||||
:visible="visible" | ||||||||||||||||||||||||||||||||||
@color-update="onColorUpdate" | ||||||||||||||||||||||||||||||||||
@confirm="onConfirm" | ||||||||||||||||||||||||||||||||||
@cancel="hidden" | ||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||
</template> | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
<script setup> | ||||||||||||||||||||||||||||||||||
import { TinyColorSelectPanel, TinyButton, TinyNotify } from '@opentiny/vue' | ||||||||||||||||||||||||||||||||||
import { ref } from 'vue' | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
const color = ref('#66ccff') | ||||||||||||||||||||||||||||||||||
const visible = ref(false) | ||||||||||||||||||||||||||||||||||
const changeVisible = () => { | ||||||||||||||||||||||||||||||||||
visible.value = !visible.value | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
const hidden = () => { | ||||||||||||||||||||||||||||||||||
visible.value = false | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
const onConfirm = () => { | ||||||||||||||||||||||||||||||||||
hidden() | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
const onColorUpdate = () => { | ||||||||||||||||||||||||||||||||||
TinyNotify({ | ||||||||||||||||||||||||||||||||||
type: 'success', | ||||||||||||||||||||||||||||||||||
position: 'top-right', | ||||||||||||||||||||||||||||||||||
title: '用户更改了颜色' | ||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
Comment on lines
+31
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve color update notification The current implementation has several issues:
+import { debounce } from 'lodash-es'
+
-const onColorUpdate = () => {
+const onColorUpdate = debounce(() => {
TinyNotify({
type: 'success',
position: 'top-right',
- title: '用户更改了颜色'
+ title: 'Color updated' // Consider using i18n for translations
})
-}
+}, 300) // Debounce for 300ms 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||
</script> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<template> | ||
<div> | ||
<tiny-button @click="changeVisible">Show Color select panel</tiny-button> | ||
<div style="position: relative"> | ||
<tiny-color-select-panel | ||
v-model="color" | ||
:visible="visible" | ||
@color-update="onColorUpdate" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Event is properly implemented but lacks detailed documentation The
However, there's no detailed API documentation found for this event. Consider adding documentation that explains:
🔗 Analysis chainVerify color-update event documentation The component uses the 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Search for color-update event documentation
rg -t md -t vue "color-update.*event" docs/
Length of output: 73 Script: #!/bin/bash
# Search for color-update event documentation with correct file type and broader scope
rg "color-update.*event|@color-update" -g "*.{md,vue}"
Length of output: 429 Script: #!/bin/bash
# Search for the component that emits this event
ast-grep --pattern 'emit($_, "color-update")'
Length of output: 47 Script: #!/bin/bash
# Look for any documentation about color events
rg "color.*event" -g "*.{md,vue}"
Length of output: 1064 Script: #!/bin/bash
# Let's check the component implementation to find the emit
rg "color-update" -g "*.{js,ts,vue}" -A 5 -B 5 packages/
Length of output: 2728 Script: #!/bin/bash
# Check the demo files to understand the usage context
cat examples/sites/demos/pc/app/color-select-panel/color-update.vue
Length of output: 989 |
||
@confirm="onConfirm" | ||
@cancel="hidden" | ||
/> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
import { TinyColorSelectPanel, TinyButton, TinyNotify } from '@opentiny/vue' | ||
|
||
export default { | ||
components: { | ||
TinyColorSelectPanel, | ||
TinyButton | ||
}, | ||
data() { | ||
return { | ||
color: '#66ccff', | ||
visible: false | ||
} | ||
}, | ||
methods: { | ||
changeVisible() { | ||
this.visible = !this.visible | ||
}, | ||
onConfirm() { | ||
this.hidden() | ||
}, | ||
hidden() { | ||
this.visible = false | ||
}, | ||
onColorUpdate() { | ||
TinyNotify({ | ||
type: 'success', | ||
position: 'top-right', | ||
title: '用户更改了颜色' | ||
}) | ||
} | ||
Comment on lines
+40
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve notification handling and add internationalization support The current implementation has several areas for improvement:
Consider applying these changes: + const NOTIFICATION_CONFIG = {
+ type: 'success',
+ position: 'top-right'
+ }
+
export default {
// ... other code ...
methods: {
onColorUpdate() {
+ try {
TinyNotify({
- type: 'success',
- position: 'top-right',
- title: '用户更改了颜色'
+ ...NOTIFICATION_CONFIG,
+ title: this.$t('colorSelect.colorChanged') // Add translation key
})
+ } catch (error) {
+ TinyNotify({
+ type: 'error',
+ ...NOTIFICATION_CONFIG,
+ title: this.$t('colorSelect.updateError')
+ })
+ }
}
}
}
|
||
} | ||
} | ||
</script> |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,23 +1,82 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import type { IColorSelectPanelRef } from '@/types' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import type { IColorSelectPanelAlphProps, IColorSelectPanelRef, ISharedRenderlessParamHooks } from '@/types' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import type { Color } from '../utils/color' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { getClientXY } from '../utils/getClientXY' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const calcLeftByAlpha = (wrapper: HTMLElement, thumb: HTMLElement, alpha: number) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return Math.round((alpha * (wrapper.offsetWidth - thumb.offsetWidth / 2)) / 100) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type State = ReturnType<typeof initState> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const initState = ({ ref, reactive }: ISharedRenderlessParamHooks) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const background = ref('') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const left = ref(0) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const state = reactive({ background, left }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return state | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const updateThumb = (alpha: number, thumb: HTMLElement, wrapper: HTMLElement) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
thumb.style.left = `${calcLeftByAlpha(wrapper, thumb, alpha)}px` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const useEvent = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
state: State, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
slider: IColorSelectPanelRef<HTMLElement | undefined>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
alphaWrapper: IColorSelectPanelRef<HTMLElement | undefined>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
alphaThumb: IColorSelectPanelRef<HTMLElement | undefined>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
props: IColorSelectPanelAlphProps<Color> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const onDrag = (event: MouseEvent | TouchEvent) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!slider.value || !alphaThumb.value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const el = alphaWrapper.value! | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const rect = el.getBoundingClientRect() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { clientX } = getClientXY(event) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let left = clientX - rect.left | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
left = Math.max(alphaThumb.value.offsetWidth / 2, left) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
left = Math.min(left, rect.width - alphaThumb.value.offsetWidth / 2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const alpha = Math.round( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
((left - alphaThumb.value.offsetWidth / 2) / (rect.width - alphaThumb.value.offsetWidth)) * 100 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
props.color.set('alpha', alpha) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const onClick = (event: MouseEvent | TouchEvent) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+21
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure In the Consider adding const onDrag = (event: MouseEvent | TouchEvent) => {
- if (!slider.value || !alphaThumb.value) {
+ if (!slider.value || !alphaThumb.value || !alphaWrapper.value) {
return
}
- const el = alphaWrapper.value!
+ const el = alphaWrapper.value
const rect = el.getBoundingClientRect()
// rest of the code...
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (event.target !== alphaThumb.value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onDrag(event) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const getLeft = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const thumb = alphaThumb.value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!thumb) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const el = alphaWrapper.value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!el) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const alpha = props.color.get('alpha') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return (alpha * (el.offsetWidth - thumb.offsetWidth / 2)) / 100 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const getBackground = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (props.color && props.color.value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { r, g, b } = props.color.toRgb() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return `linear-gradient(to right, rgba(${r}, ${g}, ${b}, 0) 0%, rgba(${r}, ${g}, ${b}, 1) 100%)` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const update = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
state.left = getLeft() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
state.background = getBackground() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { onDrag, onClick, update } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const onDrag = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
event: MouseEvent, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bar: IColorSelectPanelRef<HTMLElement>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
thumb: IColorSelectPanelRef<HTMLElement>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
alpha: IColorSelectPanelRef<number> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const initWatch = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
props: IColorSelectPanelAlphProps<Color>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
update: () => void, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ watch }: ISharedRenderlessParamHooks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const rect = bar.value.getBoundingClientRect() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { clientX } = event | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let left = clientX - rect.left | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
left = Math.max(thumb.value.offsetWidth / 2, left) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
left = Math.min(left, rect.width - thumb.value.offsetWidth / 2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
alpha.value = Math.round(((left - thumb.value.offsetWidth / 2) / (rect.width - thumb.value.offsetWidth)) * 100) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
watch( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
() => props.color.get('alpha'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
() => update(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ deep: true } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
watch( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
() => props.color, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
() => update(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ deep: true } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add color value validation
Consider adding validation for the color value to ensure it's a valid hex color code.
📝 Committable suggestion