This commit is contained in:
Ling53666
2025-08-18 09:11:51 +08:00
commit 02554225da
2516 changed files with 133155 additions and 0 deletions

View File

@ -0,0 +1,108 @@
<import-sjs
from="./index.sjs"
name="sjs"
></import-sjs>
<view
a:if="{{mode === 'default'}}"
class="ant-grid ant-grid-columns-{{columns}} ant-grid-{{mode}} {{className || ''}}"
style="{{style || ''}}"
>
<block
a:for="{{items}}"
a:for-index="index"
a:for-item="item"
>
<view
data-item="{{item}}"
class="ant-grid-item ant-grid-item-{{gridItemLayout}} {{sjs.checkNeedVerticalSpace(items.length, index, columns) ? 'ant-grid-item-vertical-space' : ''}} ant-grid-item-columns-{{columns}} {{sjs.checkShowSplitLine(index, items.length, columns, mode, showDivider) ? 'ant-grid-item-line' : ''}}"
onTap="onTap"
onFirstAppear="onFirstAppear"
>
<view class="ant-grid-item-icon ant-grid-item-icon-{{item.iconStyle || iconStyle}}">
<slot
name="icon"
value="{{item}}"
index="{{index}}"
>
<image-icon
image="{{item.icon}}"
className="ant-grid-item-icon"
style="{{iconSize ? 'width:' + iconSize + 'px;height:' + iconSize + 'px;font-size:' + iconSize + 'px' : ''}}"
></image-icon>
</slot>
</view>
<view class="ant-grid-item-title">
<slot
name="title"
value="{{item}}"
index="{{index}}"
>
{{item.title}}
</slot>
</view>
<view class="ant-grid-item-description">
<slot
name="description"
value="{{item}}"
index="{{index}}"
>
{{item.description}}
</slot>
</view>
</view>
</block>
</view>
<ant-pagination
a:elif="{{mode === 'scroll'}}"
fillColor="{{paginationFillColor}}"
frontColor="{{paginationFrontColor}}"
className="{{className || ''}}"
style="{{style || ''}}"
>
<view class="ant-grid ant-grid-{{mode}}">
<block
a:for="{{items}}"
a:for-index="index"
a:for-item="item"
>
<view
data-item="{{item}}"
class="ant-grid-item ant-grid-item-{{gridItemLayout}} ant-grid-item-columns-scroll {{sjs.checkShowSplitLine(index, items.length, columns, mode, showDivider) ? 'ant-grid-item-line' : ''}}"
onTap="onTap"
onFirstAppear="onFirstAppear"
>
<view class="ant-grid-item-icon ant-grid-item-icon-{{item.iconStyle || iconStyle}}">
<slot
name="icon"
value="{{item}}"
index="{{index}}"
>
<image-icon
image="{{item.icon}}"
className="ant-grid-item-icon"
style="{{iconSize ? 'width:' + iconSize + 'px;height:' + iconSize + 'px;font-size:' + iconSize + 'px' : ''}}"
></image-icon>
</slot>
</view>
<view class="ant-grid-item-title">
<slot
name="title"
value="{{item}}"
index="{{index}}"
>
{{item.title}}
</slot>
</view>
<view class="ant-grid-item-description">
<slot
name="description"
value="{{item}}"
index="{{index}}"
>
{{item.description}}
</slot>
</view>
</view>
</block>
</view>
</ant-pagination>

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,12 @@
import { Component, triggerEvent } from '../_util/simply';
import { GridFunctionalProps } from './props';
Component(GridFunctionalProps, {
onTap: function (e) {
var item = e.target.dataset.item;
triggerEvent(this, 'tap', item);
},
onFirstAppear: function (e) {
var item = e.target.dataset.item;
triggerEvent(this, 'firstAppear', item);
}
});

View File

@ -0,0 +1,7 @@
{
"component": true,
"usingComponents": {
"image-icon": "../ImageIcon/index",
"ant-pagination": "../Pagination/index"
}
}

View File

@ -0,0 +1,102 @@
@import (reference) './variable.less';
.@{gridPrefix} {
padding: 24 * @rpx;
box-sizing: border-box;
&-columns-3 {
padding: 24 * @rpx 0;
}
&-default {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
&-scroll {
display: flex;
flex-wrap: nowrap;
align-items: flex-start;
}
&-item {
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
flex-shrink: 0;
position: relative;
&-line {
.hairline('right',@border-color);
}
&-vertical-space {
margin-bottom: @vertical-space;
}
&-columns-5 {
width: 20%;
}
&-columns-4 {
width: 25%;
}
&-columns-3 {
width: 33.3%;
}
&-columns-2 {
width: 50%;
}
&-horizontal {
justify-content: center;
text-align: left;
position: relative;
min-height: @icon-size;
padding-left: 80 * @rpx;
.@{gridPrefix}-item-img,
.@{gridPrefix}-item-icon {
position: absolute;
left: 0;
top: 0;
bottom: 0;
margin: auto;
}
.@{gridPrefix}-item-title {
margin-top: 0;
}
}
&-columns-scroll {
width: @columnsscroll-width;
}
&-icon {
&-circle {
border-radius: 50%;
overflow: hidden;
}
&-icon {
font-size: @icon-size;
}
&-image {
width: @icon-size;
height: @icon-size;
}
}
&-title {
font-size: 26 * @rpx;
color: @title-color;
line-height: 37 * @rpx;
width: 100%;
margin-top: 16 * @rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&-description {
font-size: @description-size;
color: @description-color;
line-height: 33 * @rpx;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&:empty {
display: none;
}
}
}
}

View File

@ -0,0 +1,25 @@
function checkNeedVerticalSpace(count, index, columns) {
if (count % columns === 0) {
return index < count - columns;
} else {
return index < columns * Math.floor(count / columns);
}
}
function checkShowSplitLine(index, count, columns, mode, showDivider) {
if (!showDivider) {
return false;
}
if (index === count - 1) {
return false;
}
if (mode === 'default') {
if ((index + 1) % columns === 0) {
return false;
}
}
return true;
}
export default {
checkNeedVerticalSpace: checkNeedVerticalSpace,
checkShowSplitLine: checkShowSplitLine
};

View File

@ -0,0 +1,79 @@
import { IBaseProps } from '../_util/base';
export interface IGridItem {
/**
* @description 主文案
*/
title: string;
/**
* @description 副文案
*/
description?: string;
/**
* @description 图标
*/
icon: string;
/**
* @desscription 图标样式
* @default 'normal'
*/
iconStyle: 'normal' | 'circle';
}
/**
* @description 宫格
*/
export interface IGridProps extends IBaseProps {
/**
* @desscription 图标样式
* @default 'normal'
*/
iconStyle: 'normal' | 'circle';
/**
* @description 图标尺寸单位px
*/
iconSize: number;
/**
* @description item布局。垂直/水平水平仅columns=2生效
* @default 'vertical'
*/
gridItemLayout: 'vertical' | 'horizontal';
/**
* @description 组合形式
* @default 'default'
*/
mode: 'default' | 'scroll';
/**
* @description 每行展示的元素个数
* @default 5
*/
columns: number;
/**
* @description 元素列表
*/
items: IGridItem[];
/**
* @description 是否展示分割线
*/
showDivider: boolean;
/**
* @description 分页符背景色
* @default '#ddd'
*/
paginationFillColor: string;
/**
* @description 分页符颜色
* @default '#1677ff'
*/
paginationFrontColor: string;
/**
* @description 点击事件
* @param item
*/
onTap?(item: IGridItem): void;
/**
* @description 当前元素首次可见面积达到50%时触发
* @param item
*/
onFirstAppear?(item: IGridItem): void;
}
export declare const GridDefaultProps: Partial<IGridProps>;
export declare const GridFunctionalProps: IGridProps;

View File

@ -0,0 +1,18 @@
export var GridDefaultProps = {
iconStyle: 'normal',
mode: 'default',
columns: 5,
gridItemLayout: 'vertical',
showDivider: false,
};
export var GridFunctionalProps = {
iconStyle: 'normal',
iconSize: null,
gridItemLayout: 'vertical',
mode: 'default',
columns: 5,
items: [],
showDivider: false,
paginationFrontColor: '',
paginationFillColor: '',
};

View File

@ -0,0 +1,18 @@
@import (reference) '../style/themes/index.less';
@import (reference) '../style/mixins/hairline.less';
@gridPrefix: ant-grid;
@icon-size: 56 * @rpx;
@title-color: @COLOR_TEXT_PRIMARY;
@description-size: 24 * @rpx;
@description-color: @COLOR_TEXT_ASSIST;
@vertical-space: 40 * @rpx;
@columnsscroll-width: 130 * @rpx;
@border-color: @COLOR_BORDER;