first commit
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
:: BASE_DOC ::
|
||||
|
||||
## API
|
||||
|
||||
### Stepper Props
|
||||
|
||||
name | type | default | description | required
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | CSS(Cascading Style Sheets) | N
|
||||
disable-input | Boolean | false | \- | N
|
||||
disabled | Boolean | undefined | \- | N
|
||||
input-width | Number | - | \- | N
|
||||
integer | Boolean | true | \- | N
|
||||
max | Number | 100 | \- | N
|
||||
min | Number | 0 | \- | N
|
||||
size | String | medium | options: small/medium/large。Typescript:`SizeEnum`。[see more ts definition](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/common/common.ts) | N
|
||||
step | Number | 1 | \- | N
|
||||
theme | String | normal | stylish。options: normal/filled/outline | N
|
||||
value | String / Number | 0 | `v-model:value` is supported | N
|
||||
default-value | String / Number | 0 | uncontrolled property | N
|
||||
|
||||
### Stepper Events
|
||||
|
||||
name | params | description
|
||||
-- | -- | --
|
||||
blur | `(context: { type: string \| number })` | \-
|
||||
change | `(context: { value: string \| number })` | \-
|
||||
focus | `(context: { value: string \| number })` | \-
|
||||
overlimit | `(context: {type: 'minus' \| 'plus'})` | \-
|
||||
|
||||
### Stepper External Classes
|
||||
|
||||
className | Description
|
||||
-- | --
|
||||
t-class | \-
|
||||
t-class-input | \-
|
||||
t-class-minus | \-
|
||||
t-class-plus | \-
|
||||
|
||||
### CSS Variables
|
||||
|
||||
The component provides the following CSS variables, which can be used to customize styles.
|
||||
Name | Default Value | Description
|
||||
-- | -- | --
|
||||
--td-stepper-input-disabled-bg | @bg-color-component-disabled | -
|
||||
--td-stepper-input-disabled-color | @text-color-disabled | -
|
||||
--td-stepper-border-color | @component-border | -
|
||||
--td-stepper-border-radius | @radius-small | -
|
||||
--td-stepper-input-color | @text-color-primary | -
|
||||
90
uni_modules/tdesign-uniapp/components/stepper/README.md
Normal file
90
uni_modules/tdesign-uniapp/components/stepper/README.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Stepper 步进器
|
||||
description: 用于数量的增减。
|
||||
spline: form
|
||||
isComponent: true
|
||||
---
|
||||
|
||||
|
||||
## 引入
|
||||
|
||||
可在 `main.ts` 或在需要使用的页面或组件中引入。
|
||||
|
||||
```js
|
||||
import TStepper from '@tdesign/uniapp/stepper/stepper.vue';
|
||||
```
|
||||
|
||||
### 组件类型
|
||||
|
||||
基础步进器
|
||||
|
||||
{{ base }}
|
||||
|
||||
### 组件状态
|
||||
|
||||
最大最小状态
|
||||
|
||||
{{ min-max }}
|
||||
|
||||
禁用状态
|
||||
|
||||
{{ status }}
|
||||
|
||||
### 组件样式
|
||||
|
||||
步进器样式
|
||||
|
||||
{{ theme }}
|
||||
|
||||
步进器尺寸
|
||||
|
||||
{{ size }}
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### Stepper Props
|
||||
|
||||
名称 | 类型 | 默认值 | 描述 | 必传
|
||||
-- | -- | -- | -- | --
|
||||
custom-style | Object | - | 自定义样式 | N
|
||||
disable-input | Boolean | false | 禁用输入框 | N
|
||||
disabled | Boolean | undefined | 禁用全部操作 | N
|
||||
input-width | Number | - | 输入框宽度,默认单位 `px` | N
|
||||
integer | Boolean | true | 是否整型 | N
|
||||
max | Number | 100 | 最大值 | N
|
||||
min | Number | 0 | 最小值 | N
|
||||
size | String | medium | 组件尺寸。可选项:small/medium/large。TS 类型:`SizeEnum`。[通用类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/packages/uniapp-components/common/common.ts) | N
|
||||
step | Number | 1 | 步长 | N
|
||||
theme | String | normal | 组件风格。可选项:normal/filled/outline | N
|
||||
value | String / Number | 0 | 值。支持语法糖 `v-model:value` | N
|
||||
default-value | String / Number | 0 | 值。非受控属性 | N
|
||||
|
||||
### Stepper Events
|
||||
|
||||
名称 | 参数 | 描述
|
||||
-- | -- | --
|
||||
blur | `(context: { type: string \| number })` | 输入框失去焦点时触发
|
||||
change | `(context: { value: string \| number })` | 数值发生变更时触发
|
||||
focus | `(context: { value: string \| number })` | 输入框聚焦时触发
|
||||
overlimit | `(context: {type: 'minus' \| 'plus'})` | 数值超出限制时触发
|
||||
|
||||
### Stepper External Classes
|
||||
|
||||
类名 | 描述
|
||||
-- | --
|
||||
t-class | 根节点样式类
|
||||
t-class-input | 输入框样式类
|
||||
t-class-minus | 左侧递减号样式类
|
||||
t-class-plus | 右侧递增号样式类
|
||||
|
||||
### CSS Variables
|
||||
|
||||
组件提供了下列 CSS 变量,可用于自定义样式。
|
||||
名称 | 默认值 | 描述
|
||||
-- | -- | --
|
||||
--td-stepper-input-disabled-bg | @bg-color-component-disabled | -
|
||||
--td-stepper-input-disabled-color | @text-color-disabled | -
|
||||
--td-stepper-border-color | @component-border | -
|
||||
--td-stepper-border-radius | @radius-small | -
|
||||
--td-stepper-input-color | @text-color-primary | -
|
||||
88
uni_modules/tdesign-uniapp/components/stepper/props.ts
Normal file
88
uni_modules/tdesign-uniapp/components/stepper/props.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdStepperProps } from './type';
|
||||
export default {
|
||||
/** 禁用输入框 */
|
||||
disableInput: Boolean,
|
||||
/** 禁用全部操作 */
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** 输入框宽度,默认单位 `px` */
|
||||
inputWidth: {
|
||||
type: Number,
|
||||
},
|
||||
/** 是否整型 */
|
||||
integer: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/** 最大值 */
|
||||
max: {
|
||||
type: Number,
|
||||
default: 100,
|
||||
},
|
||||
/** 最小值 */
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
/** 组件尺寸 */
|
||||
size: {
|
||||
type: String,
|
||||
default: 'medium' as TdStepperProps['size'],
|
||||
validator(val: TdStepperProps['size']): boolean {
|
||||
if (!val) return true;
|
||||
return ['small', 'medium', 'large'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 步长 */
|
||||
step: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
/** 组件风格 */
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'normal' as TdStepperProps['theme'],
|
||||
validator(val: TdStepperProps['theme']): boolean {
|
||||
if (!val) return true;
|
||||
return ['normal', 'filled', 'outline'].includes(val);
|
||||
},
|
||||
},
|
||||
/** 值 */
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: 0 as TdStepperProps['value'],
|
||||
},
|
||||
/** 值,非受控属性 */
|
||||
defaultValue: {
|
||||
type: [String, Number],
|
||||
default: 0 as TdStepperProps['defaultValue'],
|
||||
},
|
||||
/** 输入框失去焦点时触发 */
|
||||
onBlur: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 数值发生变更时触发 */
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 输入框聚焦时触发 */
|
||||
onFocus: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
/** 数值超出限制时触发 */
|
||||
onOverlimit: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
105
uni_modules/tdesign-uniapp/components/stepper/stepper.css
Normal file
105
uni_modules/tdesign-uniapp/components/stepper/stepper.css
Normal file
@@ -0,0 +1,105 @@
|
||||
.t-stepper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--td-stepper-input-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
|
||||
}
|
||||
.t-stepper__input {
|
||||
margin: 0 8rpx;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
height: inherit;
|
||||
min-height: inherit;
|
||||
}
|
||||
.t-stepper__minus,
|
||||
.t-stepper__plus {
|
||||
padding: 8rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-stepper__input,
|
||||
.t-stepper__minus-icon,
|
||||
.t-stepper__plus-icon {
|
||||
color: inherit;
|
||||
}
|
||||
.t-stepper__input--normal,
|
||||
.t-stepper__input--filled,
|
||||
.t-stepper__input--outline {
|
||||
height: inherit;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.t-stepper--small {
|
||||
height: 40rpx;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
.t-stepper--medium {
|
||||
height: 48rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.t-stepper--large {
|
||||
height: 56rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.t-stepper__input--small {
|
||||
width: 68rpx;
|
||||
}
|
||||
.t-stepper__input--medium {
|
||||
height: 48rpx;
|
||||
width: 76rpx;
|
||||
}
|
||||
.t-stepper__input--large {
|
||||
width: 90rpx;
|
||||
}
|
||||
.t-stepper__icon--small {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.t-stepper__icon--medium {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.t-stepper__icon--large {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
.t-stepper__minus--outline,
|
||||
.t-stepper__plus--outline {
|
||||
border: 2rpx solid var(--td-stepper-border-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
}
|
||||
.t-stepper__input--outline {
|
||||
border: none;
|
||||
border-top: 2rpx solid var(--td-stepper-border-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
border-bottom: 2rpx solid var(--td-stepper-border-color, var(--td-component-border, var(--td-gray-color-4, #dcdcdc)));
|
||||
}
|
||||
.t-stepper__minus--outline,
|
||||
.t-stepper__minus--filled {
|
||||
border-radius: 0;
|
||||
border-top-left-radius: var(--td-stepper-border-radius, var(--td-radius-small, 6rpx));
|
||||
border-bottom-left-radius: var(--td-stepper-border-radius, var(--td-radius-small, 6rpx));
|
||||
}
|
||||
.t-stepper__plus--outline,
|
||||
.t-stepper__plus--filled {
|
||||
border-radius: 0;
|
||||
border-top-right-radius: var(--td-stepper-border-radius, var(--td-radius-small, 6rpx));
|
||||
border-bottom-right-radius: var(--td-stepper-border-radius, var(--td-radius-small, 6rpx));
|
||||
}
|
||||
.t-stepper__minus--filled,
|
||||
.t-stepper__plus--filled {
|
||||
background-color: var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3));
|
||||
}
|
||||
.t-stepper__input--filled {
|
||||
background-color: var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3));
|
||||
margin: 0 8rpx;
|
||||
}
|
||||
.t-stepper__input--filled .t-stepper__input {
|
||||
margin: 0;
|
||||
}
|
||||
.t-stepper--normal-disabled {
|
||||
color: var(--td-stepper-input-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
}
|
||||
.t-stepper--filled-disabled,
|
||||
.t-stepper--outline-disabled {
|
||||
color: var(--td-stepper-input-disabled-color, var(--td-text-color-disabled, var(--td-font-gray-4, rgba(0, 0, 0, 0.26))));
|
||||
background-color: var(--td-stepper-input-disabled-bg, var(--td-bg-color-component-disabled, var(--td-gray-color-2, #eeeeee)));
|
||||
}
|
||||
223
uni_modules/tdesign-uniapp/components/stepper/stepper.vue
Normal file
223
uni_modules/tdesign-uniapp/components/stepper/stepper.vue
Normal file
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<view
|
||||
:style="tools._style([customStyle])"
|
||||
:class="classPrefix + ' ' + classPrefix + '--' + size + ' ' + tClass"
|
||||
>
|
||||
<view
|
||||
:class="
|
||||
classPrefix +'__minus ' +
|
||||
classPrefix + '__minus--' + theme +
|
||||
' ' + classPrefix + '__icon--' + size +
|
||||
' ' + (disabled || disableMinus || currentValue <= min ? classPrefix + '--' + theme + '-disabled' : '') +
|
||||
' ' + tClassMinus
|
||||
"
|
||||
:aria-label="'减少' + step"
|
||||
aria-role="button"
|
||||
:aria-disabled="disabled || disableMinus || currentValue <= min"
|
||||
@click.stop.prevent="minusValue"
|
||||
>
|
||||
<t-icon name="remove" />
|
||||
</view>
|
||||
<view :class="classPrefix + '__input--' + theme + ' ' + (disabled || disableInput ? classPrefix + '--' + theme + '-disabled' : '')">
|
||||
<input
|
||||
:style="inputWidth ? 'width:' + inputWidth + 'px;' : ''"
|
||||
:class="classPrefix + '__input ' + classPrefix + '__input--' + size + ' ' + tClassInput"
|
||||
:disabled="disabled || disableInput"
|
||||
:type="integer ? 'number' : 'digit'"
|
||||
:value="currentValue"
|
||||
@input="handleInput"
|
||||
@focus="handleFocus"
|
||||
@blur="handleBlur"
|
||||
>
|
||||
</view>
|
||||
<view
|
||||
:class="
|
||||
classPrefix + '__plus ' +
|
||||
classPrefix + '__plus--' + theme +
|
||||
' ' + classPrefix + '__icon--' + size +
|
||||
' ' + (disabled || disablePlus || currentValue >= max ? classPrefix + '--' + theme + '-disabled' : '') +
|
||||
' ' + tClassPlus
|
||||
"
|
||||
:aria-label="'增加' + step"
|
||||
aria-role="button"
|
||||
:aria-disabled="disabled || disablePlus || currentValue >= max"
|
||||
@click.stop.prevent="plusValue"
|
||||
>
|
||||
<t-icon name="add" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TIcon from '../icon/icon';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import { coalesce } from '../common/utils';
|
||||
import props from './props';
|
||||
import tools from '../common/utils.wxs';
|
||||
|
||||
|
||||
const name = `${prefix}-stepper`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
controlledProps: [
|
||||
{
|
||||
key: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
],
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
`${prefix}-class-input`,
|
||||
`${prefix}-class-minus`,
|
||||
`${prefix}-class-plus`,
|
||||
],
|
||||
components: {
|
||||
TIcon,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentValue: 0,
|
||||
classPrefix: name,
|
||||
prefix,
|
||||
tools,
|
||||
disablePlus: false,
|
||||
disableMinus: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(v) {
|
||||
this.preValue = Number(v);
|
||||
this.updateCurrentValue(this.format(this.preValue));
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const { value, defaultValue, min } = this;
|
||||
const cur = coalesce(value, defaultValue);
|
||||
|
||||
this.updateCurrentValue(cur ? Number(cur) : min);
|
||||
},
|
||||
methods: {
|
||||
isDisabled(type) {
|
||||
const { min, max, disabled } = this;
|
||||
const { currentValue } = this;
|
||||
if (disabled) {
|
||||
return true;
|
||||
}
|
||||
if (type === 'minus' && currentValue <= min) {
|
||||
return true;
|
||||
}
|
||||
if (type === 'plus' && currentValue >= max) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
getLen(num) {
|
||||
const numStr = num.toString();
|
||||
return numStr.indexOf('.') === -1 ? 0 : numStr.split('.')[1].length;
|
||||
},
|
||||
|
||||
add(a, b) {
|
||||
const maxLen = Math.max(this.getLen(a), this.getLen(b));
|
||||
const base = 10 ** maxLen;
|
||||
return Math.round(a * base + b * base) / base;
|
||||
},
|
||||
|
||||
format(value) {
|
||||
const { min, max, step } = this;
|
||||
const len = Math.max(this.getLen(step), this.getLen(value));
|
||||
// 超过边界取边界值
|
||||
return Math.max(Math.min(max, value, Number.MAX_SAFE_INTEGER), min, Number.MIN_SAFE_INTEGER).toFixed(len);
|
||||
},
|
||||
|
||||
setValue(value) {
|
||||
const newValue = Number(this.format(value));
|
||||
|
||||
this.updateCurrentValue(newValue);
|
||||
|
||||
if (this.preValue === newValue) return;
|
||||
|
||||
this.preValue = newValue;
|
||||
this._trigger('change', { value: newValue });
|
||||
},
|
||||
|
||||
minusValue() {
|
||||
if (this.isDisabled('minus')) {
|
||||
this.$emit('overlimit', { type: 'minus' });
|
||||
return false;
|
||||
}
|
||||
const { currentValue, step } = this;
|
||||
this.setValue(this.add(currentValue, -step));
|
||||
},
|
||||
|
||||
plusValue() {
|
||||
if (this.isDisabled('plus')) {
|
||||
this.$emit('overlimit', { type: 'plus' });
|
||||
return false;
|
||||
}
|
||||
const { currentValue, step } = this;
|
||||
this.setValue(this.add(currentValue, step));
|
||||
},
|
||||
|
||||
filterIllegalChar(value) {
|
||||
const v = String(value).replace(/[^0-9.]/g, '');
|
||||
const indexOfDot = v.indexOf('.');
|
||||
if (this.integer && indexOfDot !== -1) {
|
||||
return v.split('.')[0];
|
||||
}
|
||||
|
||||
if (!this.integer && indexOfDot !== -1 && indexOfDot !== v.lastIndexOf('.')) {
|
||||
return v.split('.', 2).join('.');
|
||||
}
|
||||
|
||||
return v;
|
||||
},
|
||||
|
||||
updateCurrentValue(value) {
|
||||
this.currentValue = value;
|
||||
},
|
||||
|
||||
handleFocus(e) {
|
||||
const { value } = e.detail;
|
||||
|
||||
this.$emit('focus', { value });
|
||||
},
|
||||
|
||||
handleInput(e) {
|
||||
const { value } = e.detail;
|
||||
// 允许输入空值
|
||||
if (value === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
const formatted = this.filterIllegalChar(value);
|
||||
const newValue = this.format(formatted);
|
||||
|
||||
this.updateCurrentValue(this.integer ? newValue : formatted);
|
||||
|
||||
if (this.integer || /\.\d+/.test(formatted)) {
|
||||
this.setValue(formatted);
|
||||
}
|
||||
},
|
||||
|
||||
handleBlur(e) {
|
||||
const { value: rawValue } = e.detail;
|
||||
const value = this.format(rawValue);
|
||||
|
||||
this.setValue(value);
|
||||
this.$emit('blur', { value });
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './stepper.css';
|
||||
</style>
|
||||
79
uni_modules/tdesign-uniapp/components/stepper/type.ts
Normal file
79
uni_modules/tdesign-uniapp/components/stepper/type.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { SizeEnum } from '../common/common';
|
||||
|
||||
export interface TdStepperProps {
|
||||
/**
|
||||
* 禁用输入框
|
||||
* @default false
|
||||
*/
|
||||
disableInput?: boolean;
|
||||
/**
|
||||
* 禁用全部操作
|
||||
*/
|
||||
disabled?: boolean;
|
||||
/**
|
||||
* 输入框宽度,默认单位 `px`
|
||||
*/
|
||||
inputWidth?: number;
|
||||
/**
|
||||
* 是否整型
|
||||
* @default true
|
||||
*/
|
||||
integer?: boolean;
|
||||
/**
|
||||
* 最大值
|
||||
* @default 100
|
||||
*/
|
||||
max?: number;
|
||||
/**
|
||||
* 最小值
|
||||
* @default 0
|
||||
*/
|
||||
min?: number;
|
||||
/**
|
||||
* 组件尺寸
|
||||
* @default medium
|
||||
*/
|
||||
size?: SizeEnum;
|
||||
/**
|
||||
* 步长
|
||||
* @default 1
|
||||
*/
|
||||
step?: number;
|
||||
/**
|
||||
* 组件风格
|
||||
* @default normal
|
||||
*/
|
||||
theme?: 'normal' | 'filled' | 'outline';
|
||||
/**
|
||||
* 值
|
||||
* @default 0
|
||||
*/
|
||||
value?: string | number;
|
||||
/**
|
||||
* 值,非受控属性
|
||||
* @default 0
|
||||
*/
|
||||
defaultValue?: string | number;
|
||||
/**
|
||||
* 输入框失去焦点时触发
|
||||
*/
|
||||
onBlur?: (context: { type: string | number }) => void;
|
||||
/**
|
||||
* 数值发生变更时触发
|
||||
*/
|
||||
onChange?: (context: { value: string | number }) => void;
|
||||
/**
|
||||
* 输入框聚焦时触发
|
||||
*/
|
||||
onFocus?: (context: { value: string | number }) => void;
|
||||
/**
|
||||
* 数值超出限制时触发
|
||||
*/
|
||||
onOverlimit?: (context: { type: 'minus' | 'plus' }) => void;
|
||||
}
|
||||
Reference in New Issue
Block a user