feat:编辑页响应式样式修改
This commit is contained in:
@@ -55,6 +55,16 @@
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
/*
|
||||
* 主内容区不足 1360px 时,采集面板移至编辑卡片下方;大于等于该宽度时
|
||||
* 保持两列。断点依据除菜单栏外的实际内容宽度,不依赖浏览器窗口宽度。
|
||||
*/
|
||||
@container (max-width: 1199px) {
|
||||
.editor-workspace {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* 区块卡片公共外框 */
|
||||
.editor-section.ant-card {
|
||||
border: 1px solid #e9e7ef;
|
||||
@@ -69,6 +79,52 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/*
|
||||
* 01 / 02 / 04 共用的横向表单:Label 与控件列作为最大 780px 的整体居中。
|
||||
* 宽度充足时控件不超过 680px;卡片变窄时先吃掉两侧留白,再收缩控件列。
|
||||
* 容器查询以卡片实际宽度为准,不受左侧菜单或采集面板布局的间接影响。
|
||||
*/
|
||||
.editor-horizontal-section.ant-card {
|
||||
container-type: inline-size;
|
||||
}
|
||||
.editor-horizontal-section .ant-form-item-row {
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
}
|
||||
.editor-horizontal-section .ant-form-item-label {
|
||||
flex: 0 0 100px !important;
|
||||
max-width: 100px !important;
|
||||
}
|
||||
.editor-horizontal-section .ant-form-item-control {
|
||||
flex: 0 1 min(680px, calc(100% - 100px)) !important;
|
||||
width: auto;
|
||||
max-width: min(680px, calc(100% - 100px)) !important;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 100px 标签列与包装尺寸输入组在 480px 以下已没有足够可读空间;此时才
|
||||
* 切换为纵向表单。该断点读取卡片宽度,非浏览器窗口宽度。
|
||||
*/
|
||||
@container (max-width: 479px) {
|
||||
.editor-horizontal-section .ant-form-item-row {
|
||||
flex-direction: column;
|
||||
row-gap: 4px;
|
||||
}
|
||||
.editor-horizontal-section .ant-form-item-row > .ant-form-item-label {
|
||||
flex: 0 0 auto !important;
|
||||
max-width: 100% !important;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.editor-horizontal-section .ant-form-item-row > .ant-form-item-control {
|
||||
flex: 1 1 auto !important;
|
||||
width: 100%;
|
||||
max-width: 100% !important;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表单栅格(主要信息与其它区块使用) */
|
||||
.editor-form-grid {
|
||||
display: grid;
|
||||
@@ -123,12 +179,6 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@media (max-width: 1180px) {
|
||||
/* 窄屏:采集面板移到主编辑列下方 */
|
||||
.editor-workspace {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* ≤700px:整张表单切换为纵向布局(标签在上、控件在下)。
|
||||
* 更宽时保持"标签 | 控件"同行,随宽度缩小优先压缩控件长度
|
||||
@@ -136,17 +186,23 @@
|
||||
* labelCol/wrapperCol 以内联样式注入 flex,故此处需要 !important 覆盖。
|
||||
*/
|
||||
@media (max-width: 700px) {
|
||||
.product-editor .ant-form-item-row {
|
||||
.product-editor .editor-section:not(.editor-horizontal-section) .ant-form-item-row {
|
||||
flex-direction: column;
|
||||
row-gap: 4px;
|
||||
}
|
||||
.product-editor .ant-form-item-row > .ant-form-item-label {
|
||||
.product-editor
|
||||
.editor-section:not(.editor-horizontal-section)
|
||||
.ant-form-item-row
|
||||
> .ant-form-item-label {
|
||||
flex: 0 0 auto !important;
|
||||
max-width: 100% !important;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.product-editor .ant-form-item-row > .ant-form-item-control {
|
||||
.product-editor
|
||||
.editor-section:not(.editor-horizontal-section)
|
||||
.ant-form-item-row
|
||||
> .ant-form-item-control {
|
||||
flex: 1 1 auto !important;
|
||||
width: 100%;
|
||||
max-width: 100% !important;
|
||||
|
||||
@@ -889,7 +889,7 @@ const ProductEditPage = () => {
|
||||
form={form}
|
||||
layout="horizontal"
|
||||
labelAlign="right"
|
||||
labelCol={{ flex: '190px' }}
|
||||
labelCol={{ flex: '0 0 100px' }}
|
||||
wrapperCol={{ flex: '0 1 680px' }}
|
||||
onFinish={save}
|
||||
requiredMark
|
||||
|
||||
@@ -171,8 +171,8 @@
|
||||
aspect-ratio: 3 / 4;
|
||||
object-fit: cover;
|
||||
}
|
||||
@media (max-width: 1180px) {
|
||||
/* 窄屏下面板退化为工作区下方整行,不再固定高度 */
|
||||
@container (max-width: 1199px) {
|
||||
/* 主内容区不足 1360px 时,面板退化为工作区下方整行,不再固定高度。 */
|
||||
.editor-aside {
|
||||
position: static;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ export function ProductAttributeSection({
|
||||
setDictionarySearches({});
|
||||
}, [selectedCategoryId]);
|
||||
return (
|
||||
<Card className="editor-section" bordered={false}>
|
||||
<Card className="editor-section editor-horizontal-section" bordered={false}>
|
||||
<SectionTitle
|
||||
number="02"
|
||||
title="产品属性"
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@media (max-width: 860px) {
|
||||
/* 包装尺寸跟随主要信息卡片的实际宽度,和表单 Label 的换行阈值保持一致。 */
|
||||
@container (max-width: 479px) {
|
||||
.package-dimensions-controls {
|
||||
width: 100%;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
@@ -68,7 +68,7 @@ export function ProductMainInfoSection({
|
||||
onCategorySearch,
|
||||
}: Props) {
|
||||
return (
|
||||
<Card className="editor-section" bordered={false}>
|
||||
<Card className="editor-section editor-horizontal-section" bordered={false}>
|
||||
<SectionTitle
|
||||
number="01"
|
||||
title="主要信息"
|
||||
|
||||
@@ -10,7 +10,7 @@ type Props = {
|
||||
/** 「04 其它」区块:货源链接与备注;已上架 SKU 仅保存 Atlas 草稿,不回写平台商品。 */
|
||||
export function ProductOtherSection({ canOpenSupplyUrl, platformName, onOpenSupplyUrl }: Props) {
|
||||
return (
|
||||
<Card className="editor-section" bordered={false}>
|
||||
<Card className="editor-section editor-horizontal-section" bordered={false}>
|
||||
<div className="editor-section-heading" style={{ marginBottom: 8 }}>
|
||||
<div>
|
||||
<Typography.Title level={4}>
|
||||
|
||||
@@ -98,10 +98,12 @@
|
||||
font-weight: 500;
|
||||
}
|
||||
.sku-card-field {
|
||||
flex: 1 1 120px;
|
||||
/* 三个可编辑字段在同一行时,输入框允许收缩至 100px 后才换行。 */
|
||||
flex: 1 1 100px;
|
||||
min-width: 100px;
|
||||
}
|
||||
.sku-price-field {
|
||||
flex: 1 1 130px;
|
||||
flex: 1 1 100px;
|
||||
}
|
||||
.sku-card-field > span,
|
||||
.sku-card-value > span {
|
||||
@@ -157,34 +159,59 @@
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* 展开区:左侧采集图片、右侧规格面板 */
|
||||
/* 展开区:图片与规格使用同层级面板,宽度不足时再改为上下排列。 */
|
||||
.sku-card-expanded {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.08fr) minmax(390px, 0.92fr);
|
||||
gap: 32px;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(360px, 1fr);
|
||||
gap: 20px;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid #f0edf3;
|
||||
}
|
||||
.sku-media-panel,
|
||||
.sku-spec-panel {
|
||||
padding: 18px;
|
||||
border: 1px solid #eeeaf3;
|
||||
border-radius: 10px;
|
||||
background: #fcfbfd;
|
||||
}
|
||||
.sku-media-panel h5.ant-typography,
|
||||
.sku-spec-panel h5.ant-typography {
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
.sku-media-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
align-items: start;
|
||||
}
|
||||
.sku-media-item {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
/* 每张图片框固定为 3:4;实际图片使用 contain,完整居中展示。 */
|
||||
aspect-ratio: 3 / 4;
|
||||
align-self: start;
|
||||
overflow: hidden;
|
||||
border: 1px solid #ece8f0;
|
||||
border-radius: 8px;
|
||||
background: #f5f3f7;
|
||||
}
|
||||
.sku-media-item--main {
|
||||
grid-column: span 2;
|
||||
grid-row: span 2;
|
||||
}
|
||||
.sku-media-main-badge {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 6px;
|
||||
z-index: 1;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
background: rgb(64 57 79 / 72%);
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
}
|
||||
.sku-media-item .ant-btn {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
@@ -200,24 +227,28 @@
|
||||
height: 100%;
|
||||
}
|
||||
.sku-media-item img {
|
||||
display: block;
|
||||
object-fit: contain;
|
||||
object-position: center;
|
||||
}
|
||||
.sku-media-empty {
|
||||
.sku-media-picker.ant-btn {
|
||||
display: flex;
|
||||
grid-column: 1 / -1;
|
||||
min-height: 190px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
aspect-ratio: 3 / 4;
|
||||
align-self: start;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px dashed #d9d4df;
|
||||
border-radius: 8px;
|
||||
color: #90889c;
|
||||
font-size: 13px;
|
||||
}
|
||||
.sku-media-picker--empty {
|
||||
grid-column: span 2;
|
||||
grid-row: span 2;
|
||||
}
|
||||
.sku-spec-panel {
|
||||
padding: 18px 18px 6px;
|
||||
border: 1px solid #eeeaf3;
|
||||
border-radius: 10px;
|
||||
background: #fcfbfd;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
.sku-spec-panel .ant-form-item {
|
||||
margin-bottom: 16px;
|
||||
|
||||
@@ -354,7 +354,7 @@ export function ProductVariantSection({
|
||||
</Typography.Title>
|
||||
{imageCandidates.length ? (
|
||||
<div className="sku-media-grid">
|
||||
{imageCandidates.map((candidate) => {
|
||||
{imageCandidates.map((candidate, imageIndex) => {
|
||||
// 仅"转存成功"的候选可直接勾选;
|
||||
// 其余按转存状态展示对应按钮。
|
||||
const selectable =
|
||||
@@ -368,9 +368,14 @@ export function ProductVariantSection({
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className={`sku-media-item ${selected ? 'selected' : ''}`}
|
||||
className={`sku-media-item ${imageIndex === 0 ? 'sku-media-item--main' : ''} ${selected ? 'selected' : ''}`}
|
||||
key={candidate.id}
|
||||
>
|
||||
{imageIndex === 0 && (
|
||||
<span className="sku-media-main-badge">
|
||||
主图
|
||||
</span>
|
||||
)}
|
||||
<Image
|
||||
src={
|
||||
candidate.source_url
|
||||
@@ -428,10 +433,23 @@ export function ProductVariantSection({
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{/* 仅提供素材选择入口的视觉占位,实际选择流程后续接入。 */}
|
||||
<Button
|
||||
className="sku-media-picker"
|
||||
type="dashed"
|
||||
>
|
||||
选择图片
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="sku-media-empty">
|
||||
暂无采集图片
|
||||
<div className="sku-media-grid">
|
||||
{/* 没有采集图片时仍保留选择素材的入口。 */}
|
||||
<Button
|
||||
className="sku-media-picker sku-media-picker--empty"
|
||||
type="dashed"
|
||||
>
|
||||
选择图片
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user