Skip to content

Commit

Permalink
improve(style): Multiple item background and border color for Select,…
Browse files Browse the repository at this point in the history
… TreeSelect and Cascader
  • Loading branch information
dengfuping committed Apr 11, 2024
1 parent ee8485f commit 7c3c296
Show file tree
Hide file tree
Showing 12 changed files with 280 additions and 46 deletions.
1 change: 1 addition & 0 deletions .dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export default defineConfig({
{
title: '数据录入',
children: [
{ title: 'Cascader 级联选择', link: '/components/cascader' },
{ title: 'Form 表单', link: '/components/form' },
{ title: 'Input 输入框', link: '/components/input' },
{ title: 'InputNumber 数字输入框', link: '/components/input-number' },
Expand Down
53 changes: 53 additions & 0 deletions packages/design/src/cascader/demo/basic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import { Cascader } from '@oceanbase/design';

interface Option {
value: string | number;
label: string;
children?: Option[];
}

const options: Option[] = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];

const onChange = (value: (string | number)[]) => {
console.log(value);
};

const App: React.FC = () => (
<Cascader options={options} onChange={onChange} placeholder="Please select" />
);

export default App;
65 changes: 65 additions & 0 deletions packages/design/src/cascader/demo/multiple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from 'react';
import { Cascader } from '@oceanbase/design';
import type { MultipleCascaderProps } from '@oceanbase/design/es/cascader';

interface Option {
value: string | number;
label: string;
children?: Option[];
disableCheckbox?: boolean;
}

const options: Option[] = [
{
label: 'Light',
value: 'light',
children: new Array(20)
.fill(null)
.map((_, index) => ({ label: `Number ${index}`, value: index })),
},
{
label: 'Bamboo',
value: 'bamboo',
children: [
{
label: 'Little',
value: 'little',
children: [
{
label: 'Toy Fish',
value: 'fish',
disableCheckbox: true,
},
{
label: 'Toy Cards',
value: 'cards',
},
{
label: 'Toy Bird',
value: 'bird',
},
],
},
],
},
];

const onChange: MultipleCascaderProps<Option>['onChange'] = value => {
console.log(value);
};

const App: React.FC = () => (
<Cascader
style={{ width: '100%' }}
options={options}
onChange={onChange}
multiple
maxTagCount="responsive"
defaultValue={[
['light', 0],
['light', 1],
]}
/>
);

export default App;
21 changes: 21 additions & 0 deletions packages/design/src/cascader/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: Cascader 级联选择
nav:
title: 基础组件
path: /components
demo:
cols: 2
---

- 🔥 完全继承 antd [Cascader](https://ant.design/components/cascader-cn) 的能力和 API,可无缝切换。
- 💄 定制主题和样式,符合 OceanBase Design 设计规范。

## 代码演示

<!-- prettier-ignore -->
<code src="./demo/basic.tsx" title="基本"></code>
<code src="./demo/multiple.tsx" title="多选"></code>

## API

- 详见 antd InputNumber 文档: https://ant.design/components/input-number-cn
39 changes: 39 additions & 0 deletions packages/design/src/select/demo/multiple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { Select, Space } from '@oceanbase/design';
import type { SelectProps } from '@oceanbase/design';

const options: SelectProps['options'] = [];

for (let i = 10; i < 36; i++) {
options.push({
label: i.toString(36) + i,
value: i.toString(36) + i,
});
}

const handleChange = (value: string[]) => {
console.log(`selected ${value}`);
};

const App: React.FC = () => (
<Space style={{ width: '100%' }} direction="vertical">
<Select
mode="multiple"
allowClear
style={{ width: '100%' }}
defaultValue={['a10', 'c12']}
onChange={handleChange}
options={options}
/>
<Select
mode="multiple"
disabled
style={{ width: '100%' }}
defaultValue={['a10', 'c12']}
onChange={handleChange}
options={options}
/>
</Space>
);

export default App;
79 changes: 79 additions & 0 deletions packages/design/src/select/demo/variant.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react';
import { Flex, Select } from '@oceanbase/design';

const App: React.FC = () => (
<Flex gap={12} vertical>
<Flex gap={8}>
<Select
placeholder="Outlined"
style={{ flex: 1 }}
options={[
{ value: 'jack', label: 'Jack' },
{ value: 'lucy', label: 'Lucy' },
{ value: 'Yiminghe', label: 'yiminghe' },
]}
/>
<Select
mode="multiple"
defaultValue={['lucy']}
placeholder="Outlined"
style={{ flex: 1 }}
options={[
{ value: 'jack', label: 'Jack' },
{ value: 'lucy', label: 'Lucy' },
{ value: 'Yiminghe', label: 'yiminghe' },
]}
/>
</Flex>
<Flex gap={8}>
<Select
placeholder="Filled"
variant="filled"
style={{ flex: 1 }}
options={[
{ value: 'jack', label: 'Jack' },
{ value: 'lucy', label: 'Lucy' },
{ value: 'Yiminghe', label: 'yiminghe' },
]}
/>
<Select
mode="multiple"
defaultValue={['lucy']}
placeholder="Filled"
variant="filled"
style={{ flex: 1 }}
options={[
{ value: 'jack', label: 'Jack' },
{ value: 'lucy', label: 'Lucy' },
{ value: 'Yiminghe', label: 'yiminghe' },
]}
/>
</Flex>
<Flex gap={8}>
<Select
placeholder="Borderless"
variant="borderless"
style={{ flex: 1 }}
options={[
{ value: 'jack', label: 'Jack' },
{ value: 'lucy', label: 'Lucy' },
{ value: 'Yiminghe', label: 'yiminghe' },
]}
/>
<Select
mode="multiple"
defaultValue={['lucy']}
placeholder="Borderless"
variant="borderless"
style={{ flex: 1 }}
options={[
{ value: 'jack', label: 'Jack' },
{ value: 'lucy', label: 'Lucy' },
{ value: 'Yiminghe', label: 'yiminghe' },
]}
/>
</Flex>
</Flex>
);

export default App;
4 changes: 3 additions & 1 deletion packages/design/src/select/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ demo:

<!-- prettier-ignore -->
<code src="./demo/basic.tsx" title="基本使用"></code>
<code src="./demo/custom-tag-render.tsx" title="自定义标签样式" description="允许自定义选择标签的样式"></code>
<code src="./demo/multiple.tsx" title="多选"></code>
<code src="./demo/tags.tsx" title="标签" description="标签式选择,支持输入任意内容"></code>
<code src="./demo/variant.tsx" title="多种展示形式" description="支持 `outlined`、`filled` 和 `borderless` 三种形态。"></code>
<code src="./demo/custom-tag-render.tsx" title="自定义标签样式" description="允许自定义选择标签的样式"></code>

- 详见 antd Select 文档: https://ant.design/components/select-cn/
20 changes: 1 addition & 19 deletions packages/design/src/select/style/index.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { FullToken, GenerateStyle } from 'antd/es/theme/internal';
import { genComponentStyleHook } from '../../_util/genComponentStyleHook';
import { getWeakenBorderColor } from '../../_util/getWeakenBorderColor';

export type SelectToken = FullToken<'Select'>;

const getMultipleBorderColor = (token: SelectToken) => {
const { componentCls, colorBorder } = token;
return {
[`${componentCls}-selection-item`]: {
borderColor: getWeakenBorderColor(colorBorder),
},
};
};

export const genSelectStyle: GenerateStyle<SelectToken> = (token: SelectToken): CSSObject => {
const { componentCls } = token;

return {
[`${componentCls}`]: {
['&-multiple']: getMultipleBorderColor(token),
['&-multiple&-lg']: getMultipleBorderColor(token),
['&-multiple&-sm']: getMultipleBorderColor(token),
},
};
return {};
};

export default (prefixCls: string) => {
Expand Down
3 changes: 1 addition & 2 deletions packages/design/src/tag/style/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ const genTagPresetStatusStyle = (
};

const genPresetStyle = (token: TagToken) =>
genPresetColor(token, (colorKey, { textColor, lightBorderColor }) => {
genPresetColor(token, (colorKey, { lightBorderColor }) => {
return {
[`${token.componentCls}${token.componentCls}-${colorKey}`]: {
color: textColor,
borderColor: getTagBorderColor(lightBorderColor),
},
};
Expand Down
9 changes: 9 additions & 0 deletions packages/design/src/theme/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ const defaultTheme: ThemeConfig = {
InputNumber: {
handleVisible: true,
},
Select: {
// work for all multiple select component, including Select, TreeSelect and Cascader and so on
multipleItemBg: '#F8FAFE',
multipleItemBorderColor: '#cdd5e466',
multipleItemBorderColorDisabled: '#cdd5e466',
},
Tag: {
colorBorder: '#cdd5e466',
},
Table: {
cellPaddingBlock: 12,
cellPaddingBlockMD: 8,
Expand Down
2 changes: 1 addition & 1 deletion packages/design/src/tree-select/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TreeSelect as AntTreeSelect } from 'antd';
import type { TreeSelectProps as AntTreeSelectProps } from 'antd/es/tree-select';
import { TreeNode as AntTreeNode } from 'rc-tree-select';
import type { TreeNode as AntTreeNode } from 'rc-tree-select';
import type { BaseSelectRef } from 'rc-select';
import classNames from 'classnames';
import React, { useContext } from 'react';
Expand Down
30 changes: 7 additions & 23 deletions packages/design/src/tree-select/style/index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,18 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { FullToken, GenerateStyle } from 'antd/es/theme/internal';
import { genComponentStyleHook } from '../../_util/genComponentStyleHook';
import { getWeakenBorderColor } from '../../_util/getWeakenBorderColor';

export type SelectToken = FullToken<'Select'>;
export type TreeSelectToken = FullToken<'TreeSelect'>;

const getMultipleBorderColor = (token: SelectToken) => {
const { componentCls, colorBorder } = token;
return {
[`${componentCls}-selection-item`]: {
borderColor: getWeakenBorderColor(colorBorder),
},
};
};

export const genSelectStyle: GenerateStyle<SelectToken> = (token: SelectToken): CSSObject => {
const { componentCls } = token;

return {
[`${componentCls}`]: {
['&-multiple']: getMultipleBorderColor(token),
['&-multiple&-lg']: getMultipleBorderColor(token),
['&-multiple&-sm']: getMultipleBorderColor(token),
},
};
export const genTreeSelectStyle: GenerateStyle<TreeSelectToken> = (
token: TreeSelectToken
): CSSObject => {
return {};
};

export default (prefixCls: string) => {
const useStyle = genComponentStyleHook('Select', (token: SelectToken) => {
return [genSelectStyle(token)];
const useStyle = genComponentStyleHook('TreeSelect', (token: TreeSelectToken) => {
return [genTreeSelectStyle(token)];
});
return useStyle(prefixCls);
};

0 comments on commit 7c3c296

Please sign in to comment.