diff --git a/templates/repo/home_sidebar_bottom.tmpl b/templates/repo/home_sidebar_bottom.tmpl index d91adf1dd16..be3f324e74d 100644 --- a/templates/repo/home_sidebar_bottom.tmpl +++ b/templates/repo/home_sidebar_bottom.tmpl @@ -7,15 +7,15 @@ {{.NumReleases}} -
+
{{svg "octicon-tag"}}
- {{.LatestRelease.Title}} + {{.LatestRelease.Title}}
{{template "repo/release/label" (dict "Release" .LatestRelease "IsLatest" true)}}
-
{{DateUtils.TimeSince .LatestRelease.CreatedUnix}}
+
{{DateUtils.TimeSince .LatestRelease.CreatedUnix}}
{{end}} @@ -28,7 +28,7 @@
{{range .LanguageStats}} -
+
{{end}}
diff --git a/templates/repo/home_sidebar_top.tmpl b/templates/repo/home_sidebar_top.tmpl index c28f0e83067..690db11f801 100644 --- a/templates/repo/home_sidebar_top.tmpl +++ b/templates/repo/home_sidebar_top.tmpl @@ -63,7 +63,7 @@ {{svg "octicon-cross-reference"}} {{ctx.Locale.Tr "repo.cite_this_repo"}} {{end}} -
+
{{$fileSizeFormatted := FileSize .Repository.Size}}{{/* the formatted string is always "{val} {unit}" */}} {{$fileSizeFields := StringUtils.Split $fileSizeFormatted " "}} {{svg "octicon-database"}} {{ctx.Locale.PrettyNumber (index $fileSizeFields 0)}} {{index $fileSizeFields 1}} diff --git a/web_src/css/modules/tippy.css b/web_src/css/modules/tippy.css index 3c0d63f2fbf..10c57f85f0c 100644 --- a/web_src/css/modules/tippy.css +++ b/web_src/css/modules/tippy.css @@ -52,7 +52,7 @@ } .tippy-box[data-theme="tooltip"] .tippy-content { - padding: 0.5rem 1rem; + padding: 5px 10px; } .tippy-box[data-theme="tooltip"] .tippy-svg-arrow-inner, diff --git a/web_src/css/themes/theme-gitea-dark.css b/web_src/css/themes/theme-gitea-dark.css index f07d94cc635..bd0530cdb75 100644 --- a/web_src/css/themes/theme-gitea-dark.css +++ b/web_src/css/themes/theme-gitea-dark.css @@ -249,7 +249,7 @@ gitea-theme-meta-info { --color-reaction-hover-bg: var(--color-primary-light-4); --color-reaction-active-bg: var(--color-primary-light-5); --color-tooltip-text: #fafafa; - --color-tooltip-bg: #0b0b0cf0; + --color-tooltip-bg: #2b2e33; --color-nav-bg: #18191b; --color-nav-hover-bg: var(--color-secondary-light-1); --color-nav-text: var(--color-text); diff --git a/web_src/css/themes/theme-gitea-light.css b/web_src/css/themes/theme-gitea-light.css index 1bd7dd08483..fceb7d31f34 100644 --- a/web_src/css/themes/theme-gitea-light.css +++ b/web_src/css/themes/theme-gitea-light.css @@ -249,7 +249,7 @@ gitea-theme-meta-info { --color-reaction-hover-bg: var(--color-primary-light-5); --color-reaction-active-bg: var(--color-primary-light-6); --color-tooltip-text: #fbfdff; - --color-tooltip-bg: #000017f0; + --color-tooltip-bg: #25292e; --color-nav-bg: #f6f7fa; --color-nav-hover-bg: var(--color-secondary-light-1); --color-nav-text: var(--color-text); diff --git a/web_src/js/components/ActionRunJobView.vue b/web_src/js/components/ActionRunJobView.vue index ef4b591ec61..3831d7789bf 100644 --- a/web_src/js/components/ActionRunJobView.vue +++ b/web_src/js/components/ActionRunJobView.vue @@ -493,7 +493,7 @@ async function hashChangeListener() { diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue index a2ab0b3812c..6557133fe83 100644 --- a/web_src/js/components/RepoActionView.vue +++ b/web_src/js/components/RepoActionView.vue @@ -132,7 +132,7 @@ onBeforeUnmount(() => {
- + {{ backLink.prefix }} {{ backLink.name }} @@ -188,7 +188,7 @@ onBeforeUnmount(() => {
- + {{ locale.status[attempt.status] }} @@ -364,14 +364,10 @@ onBeforeUnmount(() => { gap: 4px; font-size: 13px; color: var(--color-text-light-1); + text-decoration: none; } .action-view-back:hover { - color: var(--color-primary); -} - -.action-view-back-name { - font-weight: var(--font-weight-bold); color: var(--color-text); } diff --git a/web_src/js/components/WorkflowGraph.vue b/web_src/js/components/WorkflowGraph.vue index 96e3448f251..dd2147340a3 100644 --- a/web_src/js/components/WorkflowGraph.vue +++ b/web_src/js/components/WorkflowGraph.vue @@ -434,6 +434,7 @@ function onNodeClick(job: GraphNode | ActionsJob, event: MouseEvent) { background: var(--color-console-bg); gap: var(--gap-block); flex-wrap: wrap; + border-bottom: 1px solid var(--color-secondary); } .graph-workflow-info { diff --git a/web_src/js/modules/tippy.ts b/web_src/js/modules/tippy.ts index a7df1c0485c..2a4ffd10359 100644 --- a/web_src/js/modules/tippy.ts +++ b/web_src/js/modules/tippy.ts @@ -12,10 +12,21 @@ type TippyOpts = { const visibleInstances = new Set(); const arrowSvg = html``; +// shrink tippy's default 3px arrow padding so the arrow can point at the center of +// narrow references like 16px icons with "start"/"end" placements +function arrowPadding({placement, reference}: {placement: Placement, reference: {width: number, height: number}}): number { + const isVertical = placement.startsWith('left') || placement.startsWith('right'); + const referenceLength = isVertical ? reference.height : reference.width; + return Math.max(0, Math.min(3, referenceLength / 2 - 8)); // 8 = half of arrow width +} + export function createTippy(target: Element, opts: TippyOpts = {}): Instance { // the callback functions should be destructured from opts, // because we should use our own wrapper functions to handle them, do not let the user override them const {onHide, onShow, onDestroy, role, theme, arrow, ...other} = opts; + // CSS theme, either "default", "tooltip", "menu", "box-with-header" or "bare" + const resolvedTheme = theme || role || 'default'; + const resolvedArrow = arrow ?? (resolvedTheme === 'bare' ? false : arrowSvg); const instance: Instance = tippy(target, { appendTo: document.body, @@ -44,12 +55,12 @@ export function createTippy(target: Element, opts: TippyOpts = {}): Instance { target.setAttribute('aria-controls', instance.popper.id); return onShow?.(instance); }, - arrow: arrow ?? (theme === 'bare' ? false : arrowSvg), + arrow: resolvedArrow, + popperOptions: {modifiers: [{name: 'arrow', options: {padding: arrowPadding}}]}, // HTML role attribute, ideally the default role would be "popover" but it does not exist role: role || 'menu', - // CSS theme, either "default", "tooltip", "menu", "box-with-header" or "bare" - theme: theme || role || 'default', - offset: [0, arrow ? 10 : 6], + theme: resolvedTheme, + offset: [0, resolvedArrow ? 10 : 6], plugins: [followCursor], ...other, } satisfies Partial); @@ -87,7 +98,7 @@ function attachTooltip(target: Element, content: Content | null = null): Instanc theme: 'tooltip', hideOnClick, allowHTML: target.getAttribute('data-tooltip-render') === 'html', - placement: target.getAttribute('data-tooltip-placement') as Placement || 'top-start', + placement: target.getAttribute('data-tooltip-placement') as Placement || 'top', followCursor: target.getAttribute('data-tooltip-follow-cursor') as Props['followCursor'] || false, ...((target.getAttribute('data-tooltip-interactive') === 'true') && {interactive: true, aria: {content: 'describedby', expanded: false}}), }; @@ -115,9 +126,14 @@ function switchTitleToTooltip(target: Element): void { * Some browsers like PaleMoon don't support "addEventListener('mouseenter', capture)" * The tippy by default uses "mouseenter" event to show, so we use "mouseover" event to switch to tippy */ -function lazyTooltipOnMouseHover(this: HTMLElement, e: Event): void { - (e.target as HTMLElement).removeEventListener('mouseover', lazyTooltipOnMouseHover, true); - attachTooltip(this); +function lazyTooltipOnMouseHover(e: Event): void { + const el = e.currentTarget as HTMLElement; + el.removeEventListener('mouseover', lazyTooltipOnMouseHover, true); + // Firefox skips enter/leave dispatch when the window had no such listeners at the time of the + // pointer crossing, so the new tippy misses its first "mouseenter". Show via a synthetic event, + // carrying over the cursor position for "followCursor" tooltips. + const {clientX, clientY} = e as MouseEvent; + attachTooltip(el)?.reference.dispatchEvent(new MouseEvent('mouseenter', {clientX, clientY})); } // Activate the tooltip for current element.