diff --git a/packages/amis-core/src/utils/helper.ts b/packages/amis-core/src/utils/helper.ts index 0a384d699a0..fa5f9cf2bb8 100644 --- a/packages/amis-core/src/utils/helper.ts +++ b/packages/amis-core/src/utils/helper.ts @@ -2460,6 +2460,7 @@ export function formateCheckThemeCss(themeCss: any, type: string) { if (!themeCss) { return {}; } + const className = themeCss[`${type}ClassName`] || {}; const controlClassName = themeCss[`${type}ControlClassName`] || {}; const defaultControlThemeCss: any = {}; diff --git a/packages/amis-editor/src/plugin/Steps.tsx b/packages/amis-editor/src/plugin/Steps.tsx index 0d077c59d54..664f2bea960 100644 --- a/packages/amis-editor/src/plugin/Steps.tsx +++ b/packages/amis-editor/src/plugin/Steps.tsx @@ -4,7 +4,11 @@ import {registerEditorPlugin} from 'amis-editor-core'; import {BasePlugin} from 'amis-editor-core'; import {getSchemaTpl} from 'amis-editor-core'; - +import { + inputStepStateTpl, + inputSwitchStateTpl +} from '../renderer/style-control/helper'; +import {StepStatus} from 'amis-ui'; export class StepsPlugin extends BasePlugin { static id = 'StepsPlugin'; // 关联渲染器名字 @@ -39,7 +43,6 @@ export class StepsPlugin extends BasePlugin { previewSchema = { ...this.scaffold }; - panelTitle = 'Steps'; panelBody = [ getSchemaTpl('tabs', [ @@ -136,6 +139,35 @@ export class StepsPlugin extends BasePlugin { } ] }, + { + name: '__editorStateStep', + type: 'select', + label: '步骤状态', + value: 'Default', + clearable: true, + options: [ + { + label: '常规', + value: 'Default' + }, + { + label: '完成', + value: 'Finish' + }, + { + label: '进行中', + value: 'Process' + }, + { + label: '等待', + value: 'Wait' + }, + { + label: '出错', + value: 'Error' + } + ] + }, getSchemaTpl('switch', { name: 'iconPosition', label: '图标文字垂直展示', @@ -143,6 +175,144 @@ export class StepsPlugin extends BasePlugin { }) ] }, + getSchemaTpl('theme:base', { + label: '基本样式', + name: 'themeCss.base' + }), + getSchemaTpl('collapseGroup', [ + { + title: '图标样式', + body: [ + ...inputSwitchStateTpl('themeCss.iconControlClassName', {}, [ + getSchemaTpl('switch', { + name: 'themeCss.iconControlClassName.display', + label: '隐藏图标', + trueValue: 'none' + }) + ]), + ...inputSwitchStateTpl( + 'themeCss.iconControlClassName', + { + hiddenOn: + 'themeCss.iconControlClassNameFinish.display ==="none"' + + '||' + + 'themeCss.iconControlClassNameDefault.display ==="none"' + + '||' + + 'themeCss.iconControlClassNameProcess.display ==="none"' + + '||' + + 'themeCss.iconControlClassNameWait.display ==="none"' + + '||' + + 'themeCss.iconControlClassNameError.display ==="none"' + }, + [ + getSchemaTpl('theme:select', { + label: '尺寸', + name: 'themeCss.iconControlClassName.iconSize' + }), + getSchemaTpl('theme:colorPicker', { + label: '颜色', + name: 'themeCss.iconControlClassName.backgroundColor', + labelMode: 'input' + }) + ] + ) + ] + } + ]), + getSchemaTpl('collapseGroup', [ + { + title: '标题样式', + body: [ + ...inputSwitchStateTpl('themeCss.titleControlClassName', {}, [ + getSchemaTpl('switch', { + name: 'themeCss.titleControlClassName.display', + label: '隐藏标题', + trueValue: 'none' + }) + ]), + ...inputStepStateTpl('themeCss.titleControlClassName', '', { + hideFont: false, + hiddenOn: + 'themeCss.titleControlClassNameFinish.display ==="none"' + + '||' + + 'themeCss.titleControlClassNameDefault.display ==="none"' + + '||' + + 'themeCss.titleControlClassNameProcess.display ==="none"' + + '||' + + 'themeCss.titleControlClassNameWait.display ==="none"' + + '||' + + 'themeCss.titleControlClassNameError.display ==="none"' + }) + ] + } + ]), + getSchemaTpl('collapseGroup', [ + { + title: '副标题样式', + body: [ + ...inputSwitchStateTpl( + 'themeCss.subTitleControlClassName', + {}, + [ + getSchemaTpl('switch', { + name: 'themeCss.subTitleControlClassName.display', + label: '隐藏副标题', + trueValue: 'none' + }) + ] + ), + ...inputStepStateTpl('themeCss.subTitleControlClassName', '', { + hideFont: false, + hiddenOn: + 'themeCss.subTitleControlClassNameFinish.display ==="none"' + + '||' + + 'themeCss.subTitleControlClassNameDefault.display ==="none"' + + '||' + + 'themeCss.subTitleControlClassNameProcess.display ==="none"' + + '||' + + 'themeCss.subTitleControlClassNameWait.display ==="none"' + + '||' + + 'themeCss.subTitleControlClassNameError.display ==="none"' + }) + ] + } + ]), + getSchemaTpl('collapseGroup', [ + { + title: '描述样式', + body: [ + ...inputSwitchStateTpl( + 'themeCss.descriptionControlClassName', + {}, + [ + getSchemaTpl('switch', { + name: 'themeCss.descriptionControlClassName.display', + label: '隐藏描述', + trueValue: 'none' + }) + ] + ), + ...inputStepStateTpl( + 'themeCss.descriptionControlClassName', + '', + { + hideFont: false, + hiddenOn: + 'themeCss.descriptionControlClassNameFinish.display ==="none"' + + '||' + + 'themeCss.descriptionControlClassNameDefault.display ==="none"' + + '||' + + 'themeCss.descriptionControlClassNameProcess.display ==="none"' + + '||' + + 'themeCss.descriptionControlClassNameWait.display ==="none"' + + '||' + + 'themeCss.descriptionControlClassNameError.display ==="none"' + } + ) + ] + } + ]), + getSchemaTpl('theme:cssCode'), getSchemaTpl('style:classNames', {isFormItem: false}) ]) } diff --git a/packages/amis-editor/src/renderer/style-control/helper.tsx b/packages/amis-editor/src/renderer/style-control/helper.tsx index 00e8e293743..06c40179cea 100644 --- a/packages/amis-editor/src/renderer/style-control/helper.tsx +++ b/packages/amis-editor/src/renderer/style-control/helper.tsx @@ -20,6 +20,105 @@ interface InputStateOptions { borderToken?: (state: string) => string | object; } +export const inputSwitchStateTpl = ( + className: string, + options?: InputStateOptions, + body?: any[] +) => { + const stateOptions = [ + { + label: '常规', + value: 'Default' + }, + { + label: '完成', + value: 'Finish' + }, + { + label: '进行中', + value: 'Process' + }, + { + label: '等待', + value: 'Wait' + }, + { + label: '出错', + value: 'Error' + } + ]; + const hiddenOnCondition = options?.hiddenOn + ? ` && !(${options.hiddenOn})` + : ''; + const res: any = [ + ...stateOptions.map((item: any) => { + return { + type: 'container', + visibleOn: + `\${__editorStateStep == '${item.value}'` + + (item.value === 'Default' ? ` || !__editorStateStep` : '') + + hiddenOnCondition + + `}`, + body: body?.map((b: any) => ({ + ...b, + name: b.name.replace(/name/gi, (match: any) => match + item.value) + })) + }; + }) + ]; + return res; +}; +export const inputStepStateTpl = ( + className: string, + token: string, + options?: InputStateOptions, + body?: any[] +) => { + const stateOptions = options?.state || [ + { + label: '常规', + value: 'Default' + }, + { + label: '完成', + value: 'Finish' + }, + { + label: '进行中', + value: 'Process' + }, + { + label: '等待', + value: 'Wait' + }, + { + label: '出错', + value: 'Error' + } + ]; + const hiddenOnCondition = options?.hiddenOn + ? ` && !(${options.hiddenOn})` + : ''; + const res: any = [ + ...stateOptions.map((item: any) => { + return { + type: 'container', + visibleOn: + `\${__editorStateStep == '${item.value}'` + + (item.value === 'Default' ? ` || !__editorStateStep` : '') + + hiddenOnCondition + + `}`, + body: inputStateFunc( + 'default', + className + item.value, + item.token || token, + options + ) + }; + }) + ]; + return res; +}; export const inputStateTpl = ( className: string, token: string = '', @@ -87,7 +186,6 @@ export const inputStateFunc = ( token = `${token}-${cssTokenState}`; } } - return [ !options?.hideFont && getSchemaTpl('theme:font', { diff --git a/packages/amis-ui/scss/_properties.scss b/packages/amis-ui/scss/_properties.scss index 51873ee173e..912bf1f772e 100644 --- a/packages/amis-ui/scss/_properties.scss +++ b/packages/amis-ui/scss/_properties.scss @@ -630,7 +630,10 @@ $Table-strip-bg: transparent; --Pagination-padding: 0 #{px2rem(8px)}; --Pagination-padding-sm: 0 #{px2rem(4px)}; --Pagination-light-color: var(--colors-neutral-text-4); + --Pagination-border: var(--borderWidth) var(--borders-style-2) + var(--colors-neutral-line-7); + --Panel--default-bg: var(--colors-neutral-fill-11); --Panel--default-badgeBg: var(--colors-neutral-fill-3); --Panel--default-badgeColor: var(--colors-neutral-fill-10); diff --git a/packages/amis-ui/scss/components/_pagination.scss b/packages/amis-ui/scss/components/_pagination.scss index 072f23ca8e9..72e6a62e2bd 100644 --- a/packages/amis-ui/scss/components/_pagination.scss +++ b/packages/amis-ui/scss/components/_pagination.scss @@ -65,7 +65,9 @@ border-radius: var(--borderRadius); } } + &-simple { + color: var(--Pagination-light-color); > ul > li { &:hover, &:focus { @@ -267,7 +269,6 @@ .#{$ns}Pagination-item { margin-left: px2rem(4px); - > li { > a, > span { @@ -280,7 +281,7 @@ .#{$ns}Pagination-inputGroup, .#{$ns}Pagination-simplego { - height: var(--Pagination-height-sm); + height: var(--Pagination-height); &-input { min-width: px2rem(40px); width: px2rem(40px); @@ -302,7 +303,6 @@ } } } - .#{$ns}Pagination-perpage { margin-left: px2rem(4px); padding: 0 px2rem(6px); @@ -310,3 +310,96 @@ vertical-align: baseline; } } +@include media-breakpoint-down(sm) { + .#{$ns}Pagination-wrap-size--sm { + .#{$ns}Pagination-item { + display: flex; + justify-content: center; + gap: px2rem(16px); + > li { + > a, + > span { + border: var(--borderWidth) solid var(--borderColor); + padding: var(--Pagination-padding); + min-width: var(--Pagination-minWidth); + height: var(--Pagination-height); + line-height: var(--Pagination-height); + border-radius: var(--borderRadius); + } + &.disabled { + > a, + > span { + opacity: 0.5; + cursor: not-allowed; + } + } + + } + + .#{$ns}Pagination-inputGroup, + .#{$ns}Pagination-simplego { + &-input { + border: none; + padding: 0; + margin-left: 0; + } + &-right { + border: none; + } + } + } + } + .#{$ns}Pagination-wrap-size--md { + .#{$ns}Pagination-item { + display: flex; + justify-content: space-between; + > li { + > a, + > span { + border: var(--Pagination-border); + border-radius: var(--borderRadius); + } + &.disabled { + > a, + > span { + opacity: 0.5; + cursor: not-allowed; + } + } + } + + .#{$ns}Pagination-inputGroup, + .#{$ns}Pagination-simplego { + &-input { + border: none; + } + &-right { + border: none; + } + } + } + } + .#{$ns}Pagination { + &-simplego { + display: inline-flex; + flex-wrap: nowrap; + align-items: center; + height: var(--Pagination-height); + } + input { + display: inline-block; + min-width: var(--Pagination-minWidth); + width: px2rem(32px); + height: var(--Pagination-height); + line-height: var(--Pagination-height); + font-size: var(--fontSizeSm); + margin-right: 0; + padding: 0; + &:focus, + &:hover { + outline: none; + border-color: var(--primary); + } + } + } +} diff --git a/packages/amis-ui/scss/components/_steps.scss b/packages/amis-ui/scss/components/_steps.scss index de4a77d90a8..526d3264557 100644 --- a/packages/amis-ui/scss/components/_steps.scss +++ b/packages/amis-ui/scss/components/_steps.scss @@ -407,13 +407,27 @@ .#{$ns}Steps-mobile.#{$ns}Steps--horizontal { .#{$ns}StepsItem { + overflow: visible; &-container { + &Tail:after { + display: none; + } &Wrapper { + transform: translateX(px2rem(-5px)); .#{$ns}StepsItem-body { .#{$ns}StepsItem-title { + flex-direction: column; + justify-content: center; + align-items: center; &::after { display: none !important; } + span { + left: 0; + } + } + .#{$ns}StepsItem-description { + min-width: px2rem(140px); } } @@ -429,6 +443,7 @@ &Icon { position: relative; display: block; + margin-left: px2rem(40px); &:after { content: ''; @@ -436,8 +451,8 @@ right: 0; top: px2rem(15px); height: 1px; - left: px2rem(40px); - width: 99999px; + left: px2rem(35px); + width: px2rem(80px); background-color: var(--Steps-line-bg); } } diff --git a/packages/amis-ui/src/components/Pagination.tsx b/packages/amis-ui/src/components/Pagination.tsx index 6278081a200..67f566a4251 100644 --- a/packages/amis-ui/src/components/Pagination.tsx +++ b/packages/amis-ui/src/components/Pagination.tsx @@ -119,6 +119,13 @@ export interface BasicPaginationProps { size?: string; onPageChange?: (page: number, perPage?: number, dir?: string) => void; + + /** + * 按钮类型 + * + * @default 'icon' + */ + buttonType?: string; } export interface PaginationProps extends BasicPaginationProps, @@ -144,7 +151,8 @@ export class Pagination extends React.Component< perPage: 10, perPageAvailable: [10, 20, 50, 100], ellipsisPageGap: 5, - size: 'md' + size: 'md', + buttonType: 'icon' }; state = { @@ -171,7 +179,8 @@ export class Pagination extends React.Component< componentWillReceiveProps(nextProps: PaginationProps) { if ( - this.props.mode === 'simple' && + // 原本作用在simple上的样式和部分方法变成了normal的,这里需要重置内部状态 + this.props.mode !== 'simple' && nextProps.activePage !== Number(this.state.internalPageNum) ) { this.setState({internalPageNum: String(nextProps.activePage)}); @@ -185,7 +194,6 @@ export class Pagination extends React.Component< if (disabled) { return; } - onPageChange?.(_page, perPage, dir); } @@ -400,16 +408,17 @@ export class Pagination extends React.Component< mobileUI, size, translate: __, + buttonType, testIdBuilder } = this.props; let maxButtons = this.props.maxButtons; const {pageNum, perPage, internalPageNum} = this.state; const lastPage = this.getLastPage(); - let simplePager: React.ReactNode = null; - // 简洁模式 - if (mode === 'simple') { - simplePager = ( + let basePager: React.ReactNode = null; + // 非简洁模式 + if ((mode !== 'simple' && mobileUI) || (mode === 'simple' && !mobileUI)) { + basePager = (