mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: Switch支持不同尺寸 (#4682)
This commit is contained in:
parent
be5df5e838
commit
672c5c7f96
@ -103,6 +103,30 @@ order: 51
|
||||
}
|
||||
```
|
||||
|
||||
## 不同尺寸
|
||||
|
||||
> 2.0.0 及以上版本
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "form",
|
||||
"api": "/api/mock2/form/saveForm",
|
||||
"body": [
|
||||
{
|
||||
"name": "switch",
|
||||
"type": "switch",
|
||||
"label": ""
|
||||
},
|
||||
{
|
||||
"name": "switch-sm",
|
||||
"type": "switch",
|
||||
"label": "",
|
||||
"size": "sm"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 属性表
|
||||
|
||||
除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外,还支持下面一些配置
|
||||
@ -114,6 +138,7 @@ order: 51
|
||||
| offText | `string / IconSchema` | | 关闭时开关显示的内容 |
|
||||
| trueValue | `boolean / string / number` | `true` | 标识真值 |
|
||||
| falseValue | `boolean / string / number` | `false` | 标识假值 |
|
||||
| size | `"sm" \| "md"` | `"md"` | 开关大小 |
|
||||
|
||||
IconSchema 配置
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
|
@ -1280,8 +1280,27 @@
|
||||
--Switch-onDisabled-bgColor: #ccc;
|
||||
--Switch-onDisabled-circle-BackgroundColor: var(--white);
|
||||
--Switch-onDisabled-color: #fff;
|
||||
--Switch-onHover-bgColor: var(--Switch-bgColor);
|
||||
--Switch-valueColor: var(--white);
|
||||
--Switch-width: #{px2rem(50px)};
|
||||
--Switch-slider-margin: #{px2rem(1px)};
|
||||
--Switch-slider-width: calc(
|
||||
var(--Switch-height) - var(--Switch-slider-margin) * 2
|
||||
);
|
||||
--Switch-slider-transition: margin-left var(--animation-duration);
|
||||
--Switch-text-marginRight: #{px2rem(8px)};
|
||||
--Switch-text-marginLeft: #{px2rem(25px)};
|
||||
--Switch-width--sm: #{px2rem(28px)};
|
||||
--Switch-height--sm: #{px2rem(16px)};
|
||||
--Switch-slider-width--sm: calc(
|
||||
var(--Switch-height--sm) - var(--Switch-slider-margin) * 2
|
||||
);
|
||||
--Switch-text-marginRight--sm: calc(
|
||||
var(--Switch-slider-margin) * 2 + var(--Switch-text-marginRight) / 2
|
||||
);
|
||||
--Switch-text-marginLeft--sm: calc(
|
||||
var(--Switch-slider-margin) * 2 + var(--Switch-text-marginLeft) / 2
|
||||
);
|
||||
|
||||
--Table--unsaved-heading-bg: #e8f0fe;
|
||||
--Table--unsaved-heading-color: #4285f4;
|
||||
|
@ -18,12 +18,13 @@
|
||||
}
|
||||
|
||||
.text {
|
||||
margin: 0 px2rem(7px) 0 px2rem(25px);
|
||||
margin: 0 var(--Switch-text-marginRight) 0 var(--Switch-text-marginLeft);
|
||||
color: var(--Switch-valueColor);
|
||||
text-indent: var(--gap-xs);
|
||||
text-transform: uppercase;
|
||||
font-size: var(--fontSizeSm);
|
||||
line-height: var(--Switch-height);
|
||||
vertical-align: super;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
transition: all var(--animation-duration);
|
||||
@ -40,27 +41,31 @@
|
||||
content: '';
|
||||
position: absolute;
|
||||
background: var(--white);
|
||||
width: calc(var(--Switch-height) - #{px2rem(2px)});
|
||||
top: px2rem(1px);
|
||||
bottom: px2rem(1px);
|
||||
left: px2rem(1px);
|
||||
width: var(--Switch-slider-width);
|
||||
top: var(--Switch-slider-margin);
|
||||
bottom: var(--Switch-slider-margin);
|
||||
left: var(--Switch-slider-margin);
|
||||
border-radius: 50%;
|
||||
transition: margin-left var(--animation-duration);
|
||||
transition: var(--Switch-slider-transition);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--Switch-onHover-bgColor);
|
||||
}
|
||||
|
||||
&.is-checked {
|
||||
background: var(--Switch-onActive-bgColor);
|
||||
|
||||
.slider::before {
|
||||
left: auto;
|
||||
right: px2rem(1px);
|
||||
right: var(--Switch-slider-margin);
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.text {
|
||||
color: var(--white);
|
||||
margin: 0 px2rem(25px) 0 px2rem(7px);
|
||||
margin: 0 var(--Switch-text-marginLeft) 0 var(--Switch-text-marginRight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +83,36 @@
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&--sm {
|
||||
height: var(--Switch-height--sm);
|
||||
min-width: var(--Switch-width--sm);
|
||||
|
||||
.text {
|
||||
line-height: var(--Switch-height--sm);
|
||||
margin: 0 var(--Switch-text-marginRight--sm) 0
|
||||
var(--Switch-text-marginLeft--sm);
|
||||
|
||||
> svg {
|
||||
margin-top: calc((var(--Switch-height--sm) - var(--fontSizeSm)) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
.slider::before {
|
||||
width: var(--Switch-slider-width--sm);
|
||||
}
|
||||
|
||||
&.is-checked {
|
||||
.slider::before {
|
||||
right: var(--Switch-slider-margin);
|
||||
}
|
||||
|
||||
.text {
|
||||
margin: 0 var(--Switch-text-marginLeft--sm) 0
|
||||
var(--Switch-text-marginRight--sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.#{$ns}Switch-option {
|
||||
|
@ -232,14 +232,19 @@ $L1: 0px 4px 6px 0px rgba(8, 14, 26, 0.06),
|
||||
--Switch-width: #{px2rem(44px)};
|
||||
--Switch-valueColor: #{$G11};
|
||||
--Switch-bgColor: #{$G7};
|
||||
--Switch-onActive-bgColor: #{$G6};
|
||||
--Switch-onActive-bgColor: var(--primary);
|
||||
--Switch-onHover-bgColor: #{$G6};
|
||||
--Switch-checked-bgColor: var(--primary);
|
||||
--Switch-checked-onHover-bgColor: #{$B7};
|
||||
--Switch-checked-onActive-bgColor: #{$B7};
|
||||
--Switch-onDisabled-bgColor: #{$B2};
|
||||
--Switch-onDisabled-color: #{$G11};
|
||||
// --Switch-onDisabled-circle-BackgroundColor: #fff;
|
||||
--Switch-slider-margin: #{px2rem(2px)};
|
||||
--Switch-slider-width: calc(
|
||||
var(--Switch-height) - var(--Switch-slider-margin) * 2
|
||||
);
|
||||
--Switch-slider-transition: all 0.5s ease;
|
||||
--Switch-text-margin: 0 px2rem(8px) 0 px2rem(25px);
|
||||
|
||||
--Calendar-icon-bottom: #{px2rem(-4px)};
|
||||
--Calendar-icon-width: #{px2rem(10px)};
|
||||
|
@ -1,54 +1,36 @@
|
||||
// 百度云舍主题:http://console.yunshe.design/docs/index
|
||||
|
||||
@import './cxd-variables';
|
||||
|
||||
@import './common';
|
||||
|
||||
.#{$ns}Switch {
|
||||
.text {
|
||||
margin: 0 px2rem(8px) 0 px2rem(25px);
|
||||
vertical-align: super;
|
||||
}
|
||||
.slider {
|
||||
&:before {
|
||||
width: calc(var(--Switch-height) - #{px2rem(4px)});
|
||||
top: px2rem(2px);
|
||||
bottom: px2rem(2px);
|
||||
left: px2rem(2px);
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
.slider::before {
|
||||
width: calc(var(--Switch-height) + #{px2rem(2px)});
|
||||
width: calc(var(--Switch-slider-width) + var(--Switch-slider-margin) * 2);
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: var(--Switch-onHover-bgColor);
|
||||
}
|
||||
|
||||
&.is-checked {
|
||||
background: var(--Switch-checked-bgColor);
|
||||
|
||||
.slider::before {
|
||||
right: auto;
|
||||
left: calc(
|
||||
100% - (var(--Switch-height) - #{px2rem(4px)}) - #{px2rem(2px)}
|
||||
);
|
||||
}
|
||||
|
||||
.text {
|
||||
margin: 0 px2rem(25px) 0 px2rem(8px);
|
||||
}
|
||||
&:hover {
|
||||
background: var(--Switch-checked-onHover-bgColor);
|
||||
}
|
||||
&:active {
|
||||
background: var(--Switch-checked-onActive-bgColor);
|
||||
|
||||
.slider::before {
|
||||
left: calc(
|
||||
100% - (var(--Switch-height) + #{px2rem(2px)}) - #{px2rem(2px)}
|
||||
right: calc(var(--Switch-slider-margin) * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--sm {
|
||||
&:active {
|
||||
.slider::before {
|
||||
width: calc(
|
||||
var(--Switch-slider-width--sm) + var(--Switch-slider-margin) * 2
|
||||
);
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,11 @@ import {ClassNamesFn, themeable} from 'amis-core';
|
||||
import {classPrefix, classnames} from '../themes/default';
|
||||
|
||||
const sizeMap = {
|
||||
md: 'i-switch-md',
|
||||
lg: 'i-switch-lg',
|
||||
middle: 'i-switch-md',
|
||||
large: 'i-switch-lg'
|
||||
sm: 'Switch--sm',
|
||||
md: 'Switch--md',
|
||||
middle: 'Switch--md',
|
||||
lg: 'Switch--lg',
|
||||
large: 'Switch--lg'
|
||||
};
|
||||
|
||||
const levelMap = {
|
||||
@ -23,7 +24,7 @@ const levelMap = {
|
||||
|
||||
interface SwitchProps {
|
||||
id?: string;
|
||||
size?: 'md' | 'lg' | 'middle' | 'large';
|
||||
size?: 'sm' | 'md' | 'lg' | 'middle' | 'large';
|
||||
level?: 'info' | 'primary' | 'danger';
|
||||
className?: string;
|
||||
classPrefix: string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Renderer:switch 1`] = `
|
||||
exports[`Renderer:Switch Switch basic props 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
|
||||
@ -16,7 +16,7 @@ exports[`Renderer:switch 1`] = `
|
||||
class="cxd-TplField"
|
||||
>
|
||||
<span>
|
||||
The form
|
||||
表单
|
||||
</span>
|
||||
</span>
|
||||
</h3>
|
||||
@ -110,6 +110,138 @@ exports[`Renderer:switch 1`] = `
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Renderer:Switch Switch size 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="cxd-Panel cxd-Panel--default cxd-Panel--form"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="cxd-Panel-heading"
|
||||
>
|
||||
<h3
|
||||
class="cxd-Panel-title"
|
||||
>
|
||||
<span
|
||||
class="cxd-TplField"
|
||||
>
|
||||
<span>
|
||||
表单
|
||||
</span>
|
||||
</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div
|
||||
class="cxd-Panel-body"
|
||||
>
|
||||
<form
|
||||
class="cxd-Form cxd-Form--normal"
|
||||
novalidate=""
|
||||
>
|
||||
<input
|
||||
style="display: none;"
|
||||
type="submit"
|
||||
/>
|
||||
<div
|
||||
class="cxd-Form-item cxd-Form-item--normal"
|
||||
data-role="form-item"
|
||||
>
|
||||
<label
|
||||
class="cxd-Form-label"
|
||||
>
|
||||
<span>
|
||||
<span
|
||||
class="cxd-TplField"
|
||||
>
|
||||
<span>
|
||||
开关
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
class="cxd-SwitchControl cxd-Form-control"
|
||||
>
|
||||
<label
|
||||
class="cxd-Switch cxd-Switch--sm"
|
||||
>
|
||||
<input
|
||||
theme="cxd"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="text"
|
||||
/>
|
||||
<span
|
||||
class="slider"
|
||||
/>
|
||||
</label>
|
||||
<span
|
||||
class="cxd-Switch-option"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
class="cxd-Panel-footerWrap"
|
||||
>
|
||||
<div
|
||||
class="cxd-Panel-btnToolbar cxd-Panel-footer"
|
||||
>
|
||||
<button
|
||||
class="cxd-Button cxd-Button--primary"
|
||||
type="submit"
|
||||
>
|
||||
<span>
|
||||
提交
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="resize-sensor"
|
||||
style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-expand"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; width: 10px; height: 10px;"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-shrink"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0; top: 0; width: 200%; height: 200%"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
|
@ -1,4 +1,3 @@
|
||||
import React = require('react');
|
||||
import {render, cleanup} from '@testing-library/react';
|
||||
import '../../../src';
|
||||
import {render as amisRender} from '../../../src';
|
||||
@ -10,39 +9,58 @@ afterEach(() => {
|
||||
clearStoresCache();
|
||||
});
|
||||
|
||||
test('Renderer:switch', async () => {
|
||||
const {container} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
title: 'The form',
|
||||
controls: [
|
||||
{
|
||||
name: 'switch',
|
||||
className: 'block',
|
||||
label: '开关',
|
||||
type: 'switch',
|
||||
addable: true,
|
||||
removeable: true,
|
||||
minLength: 1,
|
||||
maxLength: 4,
|
||||
addButtonText: '新增',
|
||||
draggable: true,
|
||||
draggableTip: '可通过拖动每行中的【交换】按钮进行顺序调整',
|
||||
value: true,
|
||||
trueValue: true,
|
||||
falseValue: false,
|
||||
disabled: false,
|
||||
option: 'switch',
|
||||
optionAtLeft: false
|
||||
}
|
||||
],
|
||||
submitText: null,
|
||||
actions: []
|
||||
},
|
||||
{},
|
||||
makeEnv()
|
||||
)
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
describe('Renderer:Switch', () => {
|
||||
test('Switch basic props', async () => {
|
||||
const {container} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
body: [
|
||||
{
|
||||
name: 'switch',
|
||||
className: 'block',
|
||||
label: '开关',
|
||||
type: 'switch',
|
||||
value: true,
|
||||
trueValue: true,
|
||||
falseValue: false,
|
||||
disabled: false,
|
||||
option: 'switch',
|
||||
optionAtLeft: false
|
||||
}
|
||||
],
|
||||
submitText: null,
|
||||
actions: []
|
||||
},
|
||||
{},
|
||||
makeEnv()
|
||||
)
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Switch size', async () => {
|
||||
const {container} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'form',
|
||||
body: [
|
||||
{
|
||||
name: 'switch',
|
||||
label: '开关',
|
||||
type: 'switch',
|
||||
size: 'sm'
|
||||
}
|
||||
]
|
||||
},
|
||||
{},
|
||||
makeEnv()
|
||||
)
|
||||
);
|
||||
|
||||
const SwitchDom = container.querySelector('.cxd-Switch--sm');
|
||||
|
||||
expect(SwitchDom).toBeTruthy();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -41,12 +41,16 @@ export interface SwitchControlSchema extends FormBaseControlSchema {
|
||||
* 关闭时显示的内容
|
||||
*/
|
||||
offText?: string | IconSchema;
|
||||
|
||||
/** 开关尺寸 */
|
||||
size?: 'sm' | 'md';
|
||||
}
|
||||
|
||||
export interface SwitchProps extends FormControlProps {
|
||||
option?: string;
|
||||
trueValue?: any;
|
||||
falseValue?: any;
|
||||
size?: 'sm';
|
||||
}
|
||||
|
||||
export type SwitchRendererEvent = 'change';
|
||||
@ -76,6 +80,7 @@ export default class SwitchControl extends React.Component<SwitchProps, any> {
|
||||
|
||||
render() {
|
||||
const {
|
||||
size,
|
||||
className,
|
||||
classPrefix: ns,
|
||||
classnames: cx,
|
||||
@ -112,6 +117,7 @@ export default class SwitchControl extends React.Component<SwitchProps, any> {
|
||||
offText={off}
|
||||
disabled={disabled}
|
||||
onChange={this.handleChange}
|
||||
size={size as any}
|
||||
/>
|
||||
|
||||
{optionAtLeft ? null : (
|
||||
|
Loading…
Reference in New Issue
Block a user