diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2025-07-06 23:37:26 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-06 23:37:26 +0800 |
commit | 9dafcc5c9e779fba1957400a76041ed091660710 (patch) | |
tree | e1f0b92eeaec44e68d5ef209096171ac55aae34b | |
parent | e0745eb14daad91e1c27c795cf8546be30749dd0 (diff) | |
download | gitea-9dafcc5c9e779fba1957400a76041ed091660710.tar.gz gitea-9dafcc5c9e779fba1957400a76041ed091660710.zip |
Improve project & label color picker and image scroll (#34971)
Fix #34609
Fix #34967
-rw-r--r-- | templates/projects/view.tmpl | 2 | ||||
-rw-r--r-- | templates/repo/issue/label_precolors.tmpl | 43 | ||||
-rw-r--r-- | templates/repo/issue/labels/label_edit_modal.tmpl | 2 | ||||
-rw-r--r-- | web_src/css/base.css | 13 | ||||
-rw-r--r-- | web_src/css/features/colorpicker.css | 32 | ||||
-rw-r--r-- | web_src/css/features/projects.css | 3 | ||||
-rw-r--r-- | web_src/js/features/colorpicker.ts | 36 | ||||
-rw-r--r-- | web_src/js/features/comp/LabelEdit.ts | 2 |
8 files changed, 76 insertions, 57 deletions
diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl index 6aa776da02..692808a32d 100644 --- a/templates/projects/view.tmpl +++ b/templates/projects/view.tmpl @@ -134,7 +134,7 @@ </div> <div class="field"> <label class="project-column-color-label" for="project-column-color-input">color</label> - <div class="js-color-picker-input column"> + <div class="color-picker-combo" data-global-init="initColorPicker"> <input maxlength="7" placeholder="#c320f6" id="project-column-color-input" name="color"> {{template "repo/issue/label_precolors"}} </div> diff --git a/templates/repo/issue/label_precolors.tmpl b/templates/repo/issue/label_precolors.tmpl index 80007662c0..7be3f40350 100644 --- a/templates/repo/issue/label_precolors.tmpl +++ b/templates/repo/issue/label_precolors.tmpl @@ -1,22 +1,27 @@ <div class="precolors"> - <div class="tw-flex"> - <a class="color" style="background-color:#e11d21" data-color-hex="#e11d21"></a> - <a class="color" style="background-color:#eb6420" data-color-hex="#eb6420"></a> - <a class="color" style="background-color:#fbca04" data-color-hex="#fbca04"></a> - <a class="color" style="background-color:#009800" data-color-hex="#009800"></a> - <a class="color" style="background-color:#006b75" data-color-hex="#006b75"></a> - <a class="color" style="background-color:#207de5" data-color-hex="#207de5"></a> - <a class="color" style="background-color:#0052cc" data-color-hex="#0052cc"></a> - <a class="color" style="background-color:#5319e7" data-color-hex="#5319e7"></a> - </div> - <div class="tw-flex"> - <a class="color" style="background-color:#f6c6c7" data-color-hex="#f6c6c7"></a> - <a class="color" style="background-color:#fad8c7" data-color-hex="#fad8c7"></a> - <a class="color" style="background-color:#fef2c0" data-color-hex="#fef2c0"></a> - <a class="color" style="background-color:#bfe5bf" data-color-hex="#bfe5bf"></a> - <a class="color" style="background-color:#bfdadc" data-color-hex="#bfdadc"></a> - <a class="color" style="background-color:#c7def8" data-color-hex="#c7def8"></a> - <a class="color" style="background-color:#bfd4f2" data-color-hex="#bfd4f2"></a> - <a class="color" style="background-color:#d4c5f9" data-color-hex="#d4c5f9"></a> + <button type="button" class="ui button generate-random-color"> + {{svg "octicon-sync"}} + </button> + <div> + <div class="tw-flex"> + <a class="color" style="background-color:#e11d21" data-color-hex="#e11d21"></a> + <a class="color" style="background-color:#eb6420" data-color-hex="#eb6420"></a> + <a class="color" style="background-color:#fbca04" data-color-hex="#fbca04"></a> + <a class="color" style="background-color:#009800" data-color-hex="#009800"></a> + <a class="color" style="background-color:#006b75" data-color-hex="#006b75"></a> + <a class="color" style="background-color:#207de5" data-color-hex="#207de5"></a> + <a class="color" style="background-color:#0052cc" data-color-hex="#0052cc"></a> + <a class="color" style="background-color:#5319e7" data-color-hex="#5319e7"></a> + </div> + <div class="tw-flex"> + <a class="color" style="background-color:#f6c6c7" data-color-hex="#f6c6c7"></a> + <a class="color" style="background-color:#fad8c7" data-color-hex="#fad8c7"></a> + <a class="color" style="background-color:#fef2c0" data-color-hex="#fef2c0"></a> + <a class="color" style="background-color:#bfe5bf" data-color-hex="#bfe5bf"></a> + <a class="color" style="background-color:#bfdadc" data-color-hex="#bfdadc"></a> + <a class="color" style="background-color:#c7def8" data-color-hex="#c7def8"></a> + <a class="color" style="background-color:#bfd4f2" data-color-hex="#bfd4f2"></a> + <a class="color" style="background-color:#d4c5f9" data-color-hex="#d4c5f9"></a> + </div> </div> </div> diff --git a/templates/repo/issue/labels/label_edit_modal.tmpl b/templates/repo/issue/labels/label_edit_modal.tmpl index 6837d66dce..ec57de2f3f 100644 --- a/templates/repo/issue/labels/label_edit_modal.tmpl +++ b/templates/repo/issue/labels/label_edit_modal.tmpl @@ -49,7 +49,7 @@ </div> <div class="field"> <label for="color">{{ctx.Locale.Tr "repo.issues.label_color"}}</label> - <div class="column js-color-picker-input"> + <div class="color-picker-combo" data-global-init="initColorPicker"> <!-- the "#" is optional because backend NormalizeColor is able to handle it, API also accepts both formats, and it is easier for users to directly copy-paste a hex value --> <input name="color" value="#70c24a" placeholder="#c320f6" required pattern="^#?([\dA-Fa-f]{3}|[\dA-Fa-f]{6})$" maxlength="7"> {{template "repo/issue/label_precolors"}} diff --git a/web_src/css/base.css b/web_src/css/base.css index 529ddd5386..2b7a47edf1 100644 --- a/web_src/css/base.css +++ b/web_src/css/base.css @@ -1031,19 +1031,6 @@ table th[data-sortt-desc] .svg { min-height: 0; } -.precolors { - display: flex; - flex-direction: column; - justify-content: center; - margin-left: 1em; -} - -.precolors .color { - display: inline-block; - width: 15px; - height: 15px; -} - .ui.dropdown:not(.button) { line-height: var(--line-height-default); /* the dropdown doesn't have default line-height, use this to make the dropdown icon align with plain dropdown */ } diff --git a/web_src/css/features/colorpicker.css b/web_src/css/features/colorpicker.css index b7436783df..4c517e6348 100644 --- a/web_src/css/features/colorpicker.css +++ b/web_src/css/features/colorpicker.css @@ -1,15 +1,13 @@ -.js-color-picker-input { +.color-picker-combo { display: flex; - position: relative; + position: relative; /* to position the preview square */ } -.js-color-picker-input input { - padding-top: 8px !important; - padding-bottom: 8px !important; +.color-picker-combo input { padding-left: 32px !important; } -.js-color-picker-input .preview-square { +.color-picker-combo .preview-square { position: absolute; aspect-ratio: 1; height: 16px; @@ -22,7 +20,7 @@ background-size: 8px 8px; } -.js-color-picker-input .preview-square::after { +.color-picker-combo .preview-square::after { content: ""; position: absolute; width: 100%; @@ -31,6 +29,26 @@ background-color: currentcolor; } +.color-picker-combo .precolors { + display: flex; + margin-left: 1em; + align-items: center; + gap: 0.125em; +} + +.color-picker-combo .precolors .generate-random-color { + padding: 0; + width: 30px; + height: 30px; + min-height: 0; +} + +.color-picker-combo .precolors .color { + display: inline-block; + width: 15px; + height: 15px; +} + hex-color-picker { width: 180px; height: 120px; diff --git a/web_src/css/features/projects.css b/web_src/css/features/projects.css index 7fd5150970..25cb530f85 100644 --- a/web_src/css/features/projects.css +++ b/web_src/css/features/projects.css @@ -71,7 +71,7 @@ .card-attachment-images { display: inline-block; white-space: nowrap; - overflow: scroll; + overflow: auto; cursor: default; scroll-snap-type: x mandatory; text-align: center; @@ -85,6 +85,7 @@ scroll-snap-align: center; margin-right: 2px; aspect-ratio: 1; + object-fit: contain; } .card-attachment-images img:only-child { diff --git a/web_src/js/features/colorpicker.ts b/web_src/js/features/colorpicker.ts index b99e2f8c45..66d1fcb72a 100644 --- a/web_src/js/features/colorpicker.ts +++ b/web_src/js/features/colorpicker.ts @@ -1,18 +1,19 @@ import {createTippy} from '../modules/tippy.ts'; import type {DOMEvent} from '../utils/dom.ts'; +import {registerGlobalInitFunc} from '../modules/observer.ts'; export async function initColorPickers() { - const els = document.querySelectorAll<HTMLElement>('.js-color-picker-input'); - if (!els.length) return; - - await Promise.all([ - import(/* webpackChunkName: "colorpicker" */'vanilla-colorful/hex-color-picker.js'), - import(/* webpackChunkName: "colorpicker" */'../../css/features/colorpicker.css'), - ]); - - for (const el of els) { + let imported = false; + registerGlobalInitFunc('initColorPicker', async (el) => { + if (!imported) { + await Promise.all([ + import(/* webpackChunkName: "colorpicker" */'vanilla-colorful/hex-color-picker.js'), + import(/* webpackChunkName: "colorpicker" */'../../css/features/colorpicker.css'), + ]); + imported = true; + } initPicker(el); - } + }); } function updateSquare(el: HTMLElement, newValue: string): void { @@ -55,13 +56,20 @@ function initPicker(el: HTMLElement): void { }, }); - // init precolors + // init random color & precolors + const setSelectedColor = (color: string) => { + input.value = color; + input.dispatchEvent(new Event('input', {bubbles: true})); + updateSquare(square, color); + }; + el.querySelector('.generate-random-color').addEventListener('click', () => { + const newValue = `#${Math.floor(Math.random() * 0xFFFFFF).toString(16).padStart(6, '0')}`; + setSelectedColor(newValue); + }); for (const colorEl of el.querySelectorAll<HTMLElement>('.precolors .color')) { colorEl.addEventListener('click', (e: DOMEvent<MouseEvent, HTMLAnchorElement>) => { const newValue = e.target.getAttribute('data-color-hex'); - input.value = newValue; - input.dispatchEvent(new Event('input', {bubbles: true})); - updateSquare(square, newValue); + setSelectedColor(newValue); }); } } diff --git a/web_src/js/features/comp/LabelEdit.ts b/web_src/js/features/comp/LabelEdit.ts index 423440129c..3e27eac1c5 100644 --- a/web_src/js/features/comp/LabelEdit.ts +++ b/web_src/js/features/comp/LabelEdit.ts @@ -24,7 +24,7 @@ export function initCompLabelEdit(pageSelector: string) { const elIsArchivedField = elModal.querySelector('.label-is-archived-input-field'); const elIsArchivedInput = elModal.querySelector<HTMLInputElement>('.label-is-archived-input'); const elDescInput = elModal.querySelector<HTMLInputElement>('.label-desc-input'); - const elColorInput = elModal.querySelector<HTMLInputElement>('.js-color-picker-input input'); + const elColorInput = elModal.querySelector<HTMLInputElement>('.color-picker-combo input'); const syncModalUi = () => { const hasScope = nameHasScope(elNameInput.value); |