refactor(frontend): port pagination rules into BasePagination and drop Bulma import

The Bulma components/pagination partial is only used by BasePagination
and its two wrappers (Pagination.vue, PaginationEmit.vue); no other
component renders raw .pagination-* markup. Ports the rules we actually
use (base layout, item sizing, hover/focus/disabled states, is-current
styling, mobile/tablet breakpoints) into BasePagination's scoped styles,
using :deep() to reach slotted children. The theme override for
.pagination-link on .has-background containers moves into an unscoped
style block on the same component. Drops the now-unused @import.
This commit is contained in:
kolaente 2026-04-17 16:25:52 +02:00 committed by kolaente
parent 326874d94c
commit 5ea7853dd6
3 changed files with 156 additions and 12 deletions

View File

@ -82,22 +82,171 @@ const pages = computed(() => createPagination(props.totalPages, props.currentPag
</script>
<style lang="scss" scoped>
// Rules ported from bulma-css-variables/sass/components/pagination.sass.
// Slot content (.pagination-previous, .pagination-next, .pagination-link) is
// rendered by Pagination.vue / PaginationEmit.vue, so scoped attributes don't
// reach them we use :deep() to style across the slot boundary.
.pagination {
align-items: center;
display: flex;
font-size: $size-normal;
justify-content: center;
margin: -0.25rem;
padding-block-end: 1rem;
text-align: center;
}
.pagination-previous,
.pagination-next {
.pagination-list {
align-items: center;
display: flex;
flex-wrap: wrap;
justify-content: center;
text-align: center;
&, & li {
margin-block-start: 0;
}
li {
list-style: none;
}
}
:deep(.pagination-previous),
:deep(.pagination-next),
:deep(.pagination-link),
.pagination-ellipsis {
appearance: none;
align-items: center;
border: 1px solid transparent;
border-radius: $radius;
box-shadow: none;
display: inline-flex;
font-size: 1em;
block-size: 2.5em;
justify-content: center;
line-height: 1.5;
margin: 0.25rem;
padding: calc(0.5em - 1px) 0.5em;
position: relative;
text-align: center;
vertical-align: top;
-webkit-touch-callout: none;
user-select: none;
&:focus,
&:active {
outline: none;
}
&[disabled],
fieldset[disabled] & {
cursor: not-allowed;
}
}
:deep(.pagination-previous),
:deep(.pagination-next),
:deep(.pagination-link) {
border-color: var(--border);
color: var(--text-strong);
min-inline-size: 2.5em;
&:hover {
border-color: var(--link-hover-border);
color: var(--link-hover);
}
&:focus {
border-color: var(--link-focus-border);
}
&:active {
box-shadow: inset 0 1px 2px rgba($scheme-invert, 0.2);
}
&[disabled] {
background-color: var(--border);
border-color: var(--border);
box-shadow: none;
color: var(--text-light);
opacity: 0.5;
}
}
:deep(.pagination-previous),
:deep(.pagination-next) {
padding-inline: 0.75em;
white-space: nowrap;
&:not(:disabled):hover {
background: $scheme-main;
cursor: pointer;
}
}
.pagination-list {
&, & li {
margin-block-start: 0;
:deep(.pagination-link.is-current) {
background-color: var(--link);
border-color: var(--link);
color: var(--link-invert);
}
.pagination-ellipsis {
color: var(--grey-light);
pointer-events: none;
}
@media screen and (max-width: $tablet - 1px) {
.pagination {
flex-wrap: wrap;
}
:deep(.pagination-previous),
:deep(.pagination-next) {
flex-grow: 1;
flex-shrink: 1;
}
.pagination-list li {
flex-grow: 1;
flex-shrink: 1;
}
}
@media screen and (min-width: $tablet), print {
.pagination-list {
flex-grow: 1;
flex-shrink: 1;
}
:deep(.pagination-previous),
:deep(.pagination-next),
:deep(.pagination-link),
.pagination-ellipsis {
margin-block: 0;
}
.pagination {
margin-block: 0;
&.is-centered {
.pagination-list {
justify-content: center;
}
}
}
}
</style>
<style lang="scss">
// Unscoped: this rule relies on ancestors (.app-container.has-background /
// .link-share-container.has-background) that live outside BasePagination.
// Previously lived in styles/theme/background.scss.
.app-container.has-background .pagination-link:not(.is-current),
.link-share-container.has-background .pagination-link:not(.is-current) {
background: var(--grey-100);
}
</style>

View File

@ -51,7 +51,7 @@
//@import "bulma-css-variables/sass/components/message"; // not used
// @import "bulma-css-variables/sass/components/modal"; // not used; Modal.vue owns its own dialog-based styles
// @import "bulma-css-variables/sass/components/navbar"; // not used; ported into AppHeader.vue
@import "bulma-css-variables/sass/components/pagination";
// @import "bulma-css-variables/sass/components/pagination"; // ported into BasePagination.vue
// @import "bulma-css-variables/sass/components/panel"; // not used
// @import "bulma-css-variables/sass/components/tabs"; // not used

View File

@ -10,11 +10,6 @@
min-height: 100vh;
}
// FIXME: move to pagination component
.pagination-link:not(.is-current) {
background: var(--grey-100);
}
.box,
.card,
.switch-view,