Fix mobile content padding to match desktop margins
- Add page-padding-y-mobile gap after title bar offset - Align mobile padding calculations with desktop behavior - Update all tab position rules (top, bottom, responsive) - Add CSS variables for mobile spacing control 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -144,6 +144,10 @@ export function SwipeTabs<T extends string | number>({
|
|||||||
setContainerHeight((prev) => (prev === nextHeight ? prev : nextHeight));
|
setContainerHeight((prev) => (prev === nextHeight ? prev : nextHeight));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleTabsMetrics = useCallback(() => {
|
||||||
|
updateHeight();
|
||||||
|
}, [updateHeight]);
|
||||||
|
|
||||||
const measureWidth = useCallback(() => {
|
const measureWidth = useCallback(() => {
|
||||||
const width = containerRef.current?.getBoundingClientRect().width || 0;
|
const width = containerRef.current?.getBoundingClientRect().width || 0;
|
||||||
if (width && width !== widthRef.current) {
|
if (width && width !== widthRef.current) {
|
||||||
@@ -192,6 +196,14 @@ export function SwipeTabs<T extends string | number>({
|
|||||||
};
|
};
|
||||||
}, [displayIndex, updateHeight]);
|
}, [displayIndex, updateHeight]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (typeof window === 'undefined') return undefined;
|
||||||
|
window.addEventListener('tabs:metrics', handleTabsMetrics);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('tabs:metrics', handleTabsMetrics);
|
||||||
|
};
|
||||||
|
}, [handleTabsMetrics]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
if (rafRef.current) {
|
if (rafRef.current) {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ const TabsScroller = forwardRef<HTMLDivElement, TabsScrollerProps>(
|
|||||||
const [showRight, setShowRight] = useState(false);
|
const [showRight, setShowRight] = useState(false);
|
||||||
const heightRef = useRef(0);
|
const heightRef = useRef(0);
|
||||||
const pillHeightRef = useRef(0);
|
const pillHeightRef = useRef(0);
|
||||||
|
const sliderHeightRef = useRef(0);
|
||||||
|
|
||||||
const dragRef = useRef({
|
const dragRef = useRef({
|
||||||
pointerId: null as number | null,
|
pointerId: null as number | null,
|
||||||
@@ -76,12 +77,27 @@ const TabsScroller = forwardRef<HTMLDivElement, TabsScrollerProps>(
|
|||||||
node.dataset.hasActions = hasActionsValue;
|
node.dataset.hasActions = hasActionsValue;
|
||||||
const container = node.closest('.page-tabs-container, .admin-tabs-container');
|
const container = node.closest('.page-tabs-container, .admin-tabs-container');
|
||||||
const mainContent = node.closest('.main-content');
|
const mainContent = node.closest('.main-content');
|
||||||
let containerHeight = 0;
|
|
||||||
if (container instanceof HTMLElement) {
|
if (container instanceof HTMLElement) {
|
||||||
container.dataset.hasTabs = hasTabsValue;
|
container.dataset.hasTabs = hasTabsValue;
|
||||||
container.dataset.hasActions = hasActionsValue;
|
container.dataset.hasActions = hasActionsValue;
|
||||||
|
}
|
||||||
|
const sliderHeight = Math.ceil(node.getBoundingClientRect().height);
|
||||||
|
let containerHeight = 0;
|
||||||
|
if (container instanceof HTMLElement) {
|
||||||
containerHeight = Math.ceil(container.getBoundingClientRect().height);
|
containerHeight = Math.ceil(container.getBoundingClientRect().height);
|
||||||
}
|
}
|
||||||
|
if (sliderHeight && sliderHeight !== sliderHeightRef.current) {
|
||||||
|
sliderHeightRef.current = sliderHeight;
|
||||||
|
if (typeof document !== 'undefined') {
|
||||||
|
document.documentElement.style.setProperty('--tabs-slider-height', `${sliderHeight}px`);
|
||||||
|
}
|
||||||
|
if (mainContent instanceof HTMLElement) {
|
||||||
|
mainContent.style.setProperty('--tabs-slider-height', `${sliderHeight}px`);
|
||||||
|
}
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
window.dispatchEvent(new Event('tabs:metrics'));
|
||||||
|
}
|
||||||
|
}
|
||||||
const firstTabButton = node.querySelector('.page-tab-btn, .admin-tab-btn');
|
const firstTabButton = node.querySelector('.page-tab-btn, .admin-tab-btn');
|
||||||
if (firstTabButton instanceof HTMLElement) {
|
if (firstTabButton instanceof HTMLElement) {
|
||||||
const pillHeight = Math.ceil(firstTabButton.getBoundingClientRect().height);
|
const pillHeight = Math.ceil(firstTabButton.getBoundingClientRect().height);
|
||||||
@@ -133,6 +149,7 @@ const TabsScroller = forwardRef<HTMLDivElement, TabsScrollerProps>(
|
|||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
updateOverflow();
|
updateOverflow();
|
||||||
|
scheduleOverflowUpdate();
|
||||||
const node = sliderRef.current;
|
const node = sliderRef.current;
|
||||||
if (!node) return undefined;
|
if (!node) return undefined;
|
||||||
const container = node.closest('.page-tabs-container, .admin-tabs-container');
|
const container = node.closest('.page-tabs-container, .admin-tabs-container');
|
||||||
|
|||||||
@@ -444,6 +444,9 @@ label,
|
|||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.main-content {
|
.main-content {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
|
--page-padding-y-mobile-gap: var(--space-3);
|
||||||
|
--page-padding-y-mobile-bottom-gap: 0;
|
||||||
|
--tabs-slider-height-fallback: calc(var(--tab-pill-height, 44px) + 8px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Override collapsed state margin on mobile */
|
/* Override collapsed state margin on mobile */
|
||||||
@@ -564,27 +567,19 @@ label,
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-content {
|
.page-content,
|
||||||
padding: var(--page-padding-y-mobile) var(--page-padding-x-mobile);
|
|
||||||
padding-top: var(--title-bar-offset, var(--title-bar-height, 0px));
|
|
||||||
}
|
|
||||||
|
|
||||||
.admin-tab-content {
|
.admin-tab-content {
|
||||||
padding: var(--page-padding-y-mobile) var(--page-padding-x-mobile);
|
padding: var(--page-padding-y-mobile) var(--page-padding-x-mobile);
|
||||||
padding-top: var(--title-bar-offset, var(--title-bar-height, 0px));
|
padding-top: calc(var(--title-bar-offset, 0px) + var(--page-padding-y-mobile-gap, var(--page-padding-y-mobile)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Small mobile - further reduce spacing */
|
/* Small mobile - further reduce spacing */
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.page-content {
|
.page-content,
|
||||||
padding: var(--page-padding-y-mobile) var(--page-padding-x-mobile);
|
|
||||||
padding-top: var(--title-bar-offset, var(--title-bar-height, 0px));
|
|
||||||
}
|
|
||||||
|
|
||||||
.admin-tab-content {
|
.admin-tab-content {
|
||||||
padding: var(--page-padding-y-mobile) var(--page-padding-x-mobile);
|
padding: var(--page-padding-y-mobile) var(--page-padding-x-mobile);
|
||||||
padding-top: var(--title-bar-offset, var(--title-bar-height, 0px));
|
padding-top: calc(var(--title-bar-offset, 0px) + var(--page-padding-y-mobile-gap, var(--page-padding-y-mobile)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -840,8 +835,9 @@ label,
|
|||||||
[data-tab-position='top'] .main-content[data-has-tabs='true'] .admin-tab-content,
|
[data-tab-position='top'] .main-content[data-has-tabs='true'] .admin-tab-content,
|
||||||
[data-tab-position='top'] .main-content[data-has-actions='true'] .admin-tab-content {
|
[data-tab-position='top'] .main-content[data-has-actions='true'] .admin-tab-content {
|
||||||
padding-top: calc(
|
padding-top: calc(
|
||||||
var(--title-bar-offset, var(--title-bar-height, 0px)) +
|
var(--title-bar-offset, 0px) +
|
||||||
var(--tabs-bar-height, 72px)
|
var(--tabs-bar-height, 72px) +
|
||||||
|
var(--page-padding-y-mobile-gap, var(--page-padding-y-mobile))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -893,13 +889,11 @@ label,
|
|||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .page-content,
|
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .page-content {
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .admin-tab-swipe {
|
|
||||||
padding-top: var(--page-padding-y);
|
padding-top: var(--page-padding-y);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .page-content,
|
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .page-content,
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .admin-tab-swipe,
|
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .admin-tab-content {
|
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .admin-tab-content {
|
||||||
padding-bottom: calc(
|
padding-bottom: calc(
|
||||||
var(--page-padding-y) +
|
var(--page-padding-y) +
|
||||||
@@ -929,17 +923,16 @@ label,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Mobile padding for bottom position */
|
/* Mobile padding for bottom position */
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .page-content,
|
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .page-content {
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .admin-tab-swipe {
|
padding-top: calc(var(--title-bar-offset, 0px) + var(--page-padding-y-mobile-gap, var(--page-padding-y-mobile)));
|
||||||
padding-top: var(--title-bar-offset, var(--title-bar-height, 0px));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .page-content,
|
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .page-content,
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .admin-tab-swipe,
|
|
||||||
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .admin-tab-content {
|
[data-tab-position='bottom'] .main-content[data-has-tabs='true'] .admin-tab-content {
|
||||||
padding-bottom: calc(
|
padding-bottom: calc(
|
||||||
var(--page-padding-y-mobile) +
|
var(--page-padding-y-mobile-bottom-gap, 0px) +
|
||||||
var(--tabs-bar-height, calc(72px + env(safe-area-inset-bottom, 0px)))
|
var(--tabs-slider-height, var(--tabs-slider-height-fallback, 52px)) +
|
||||||
|
env(safe-area-inset-bottom, 0px)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -971,17 +964,16 @@ label,
|
|||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-tab-position='responsive'] .main-content[data-has-tabs='true'] .page-content,
|
[data-tab-position='responsive'] .main-content[data-has-tabs='true'] .page-content {
|
||||||
[data-tab-position='responsive'] .main-content[data-has-tabs='true'] .admin-tab-swipe {
|
padding-top: calc(var(--title-bar-offset, 0px) + var(--page-padding-y-mobile-gap, var(--page-padding-y-mobile)));
|
||||||
padding-top: var(--title-bar-offset, var(--title-bar-height, 0px));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-tab-position='responsive'] .main-content[data-has-tabs='true'] .page-content,
|
[data-tab-position='responsive'] .main-content[data-has-tabs='true'] .page-content,
|
||||||
[data-tab-position='responsive'] .main-content[data-has-tabs='true'] .admin-tab-swipe,
|
|
||||||
[data-tab-position='responsive'] .main-content[data-has-tabs='true'] .admin-tab-content {
|
[data-tab-position='responsive'] .main-content[data-has-tabs='true'] .admin-tab-content {
|
||||||
padding-bottom: calc(
|
padding-bottom: calc(
|
||||||
var(--page-padding-y-mobile) +
|
var(--page-padding-y-mobile-bottom-gap, 0px) +
|
||||||
var(--tabs-bar-height, calc(72px + env(safe-area-inset-bottom, 0px)))
|
var(--tabs-slider-height, var(--tabs-slider-height-fallback, 52px)) +
|
||||||
|
env(safe-area-inset-bottom, 0px)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1269,6 +1269,10 @@
|
|||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-section:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Appearance Grid Mobile Overrides */
|
/* Appearance Grid Mobile Overrides */
|
||||||
.appearance-grid {
|
.appearance-grid {
|
||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user