feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { tokenMapToStr } from '../../utils/token-map-to-str';
|
||||
import { type ResponsiveTokenMap } from '../../types';
|
||||
import { type ScreenRange } from '../../constant';
|
||||
|
||||
interface ResponsiveBoxProps {
|
||||
contents: React.ReactNode[]; // array of content
|
||||
colReverse?: boolean; // direction is col or col-reverse
|
||||
rowReverse?: boolean; // direction is row or row-reverse
|
||||
gaps?: ResponsiveTokenMap<ScreenRange>;
|
||||
}
|
||||
export const ResponsiveBox = ({
|
||||
contents = [],
|
||||
colReverse = false,
|
||||
rowReverse = false,
|
||||
gaps,
|
||||
}: ResponsiveBoxProps) => (
|
||||
<div
|
||||
className={classNames(
|
||||
'w-full flex overflow-hidden',
|
||||
colReverse
|
||||
? 'flex-col-reverse sm:flex-col-reverse'
|
||||
: 'flex-col sm:flex-col',
|
||||
rowReverse
|
||||
? 'md:flex-row-reverse lg:flex-row-reverse'
|
||||
: 'md:flex-row lg:flex-row',
|
||||
gaps && tokenMapToStr(gaps, 'gap'),
|
||||
)}
|
||||
>
|
||||
{contents}
|
||||
</div>
|
||||
);
|
||||
|
||||
export const ResponsiveBox2 = ({
|
||||
contents = [],
|
||||
colReverse = false,
|
||||
rowReverse = false,
|
||||
gaps,
|
||||
}: ResponsiveBoxProps) => (
|
||||
<div
|
||||
className={classNames(
|
||||
'w-full flex overflow-hidden',
|
||||
colReverse ? 'flex-col-reverse' : 'flex-col',
|
||||
rowReverse ? 'lg:flex-row-reverse' : 'lg:flex-row',
|
||||
gaps && tokenMapToStr(gaps, 'gap'),
|
||||
)}
|
||||
>
|
||||
{contents}
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { tokenMapToStr } from '../../utils/token-map-to-str';
|
||||
import { type ResponsiveTokenMap } from '../../types';
|
||||
import { type ScreenRange } from '../../constant';
|
||||
|
||||
import styles from './responsive.module.less';
|
||||
|
||||
interface ResponsiveListProps<T> {
|
||||
dataSource: T[];
|
||||
renderItem: (item: T, index: number) => React.ReactNode;
|
||||
|
||||
className?: string;
|
||||
emptyContent?: React.ReactNode;
|
||||
|
||||
footer?: React.ReactNode;
|
||||
|
||||
gridCols?: ResponsiveTokenMap<ScreenRange>; // 响应式列数
|
||||
gridGapXs?: ResponsiveTokenMap<ScreenRange>; // 响应式X轴gap
|
||||
gridGapYs?: ResponsiveTokenMap<ScreenRange>; // 响应式Y轴gap
|
||||
}
|
||||
|
||||
// 通过tailwind动态根据媒体查询设置List列数
|
||||
export const ResponsiveList = <T extends object>({
|
||||
dataSource,
|
||||
renderItem,
|
||||
|
||||
className,
|
||||
emptyContent,
|
||||
footer,
|
||||
|
||||
gridCols = {
|
||||
sm: 1,
|
||||
md: 2,
|
||||
lg: 3,
|
||||
xl: 4,
|
||||
},
|
||||
gridGapXs,
|
||||
gridGapYs,
|
||||
}: ResponsiveListProps<T>) => (
|
||||
<div className={classNames('flex flex-col justify-items-center', className)}>
|
||||
<div
|
||||
className={classNames(
|
||||
'w-full grid justify-content-center responsive-list-container',
|
||||
gridCols && tokenMapToStr(gridCols, 'grid-cols'),
|
||||
gridGapXs && tokenMapToStr(gridGapXs, 'gap-x'),
|
||||
gridGapYs && tokenMapToStr(gridGapYs, 'gap-y'),
|
||||
styles['grid-cols-1'],
|
||||
)}
|
||||
>
|
||||
{dataSource.length
|
||||
? dataSource.map((data, idx) => renderItem(data, idx))
|
||||
: emptyContent}
|
||||
</div>
|
||||
{footer}
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
@media (max-width: 640px) {
|
||||
.grid-cols-1 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user