Skip to content

Commit

Permalink
Merge pull request #55 from js-tool-pack/select
Browse files Browse the repository at this point in the history
Select
  • Loading branch information
mengxinssfd authored Sep 13, 2023
2 parents c223af2 + c7eee39 commit 3e03b51
Show file tree
Hide file tree
Showing 118 changed files with 9,025 additions and 2,482 deletions.
11 changes: 11 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ module.exports = {
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
},
parserOptions: {
sourceType: 'script',
},
},
{
files: ['**.test.ts', '**.test.tsx'],
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
'jsx-a11y/click-events-have-key-events': 'off',
'jsx-a11y/no-static-element-interactions': 'off',
},
},
],
env: {
Expand Down
5 changes: 5 additions & 0 deletions internal/playground/src/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ export const baseRouter = [
path: '/tag',
element: getDemos(import.meta.glob('~/tag/demo/*.tsx')),
},
{
name: 'select 选择器',
path: '/select',
element: getDemos(import.meta.glob('~/select/demo/*.tsx')),
},
/*insert target*/
];

Expand Down
34 changes: 20 additions & 14 deletions internal/playground/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,26 @@ export default defineConfig(() => {
cacheDir: `./.cache`,
resolve: {
alias: {
...pkgs.reduce((prev, cur) => {
prev['@pkg/' + cur] = Path.resolve(
__dirname,
`../../packages/${cur}/src`,
);
return prev;
}, {} as Record<string, string>),
...components.reduce((prev, cur) => {
prev['~/' + cur] = Path.resolve(
__dirname,
`../../packages/components/src/${cur}`,
);
return prev;
}, {} as Record<string, string>),
...pkgs.reduce(
(prev, cur) => {
prev['@pkg/' + cur] = Path.resolve(
__dirname,
`../../packages/${cur}/src`,
);
return prev;
},
{} as Record<string, string>,
),
...components.reduce(
(prev, cur) => {
prev['~/' + cur] = Path.resolve(
__dirname,
`../../packages/components/src/${cur}`,
);
return prev;
},
{} as Record<string, string>,
),
'@tool-pack/react-ui': Path.resolve(
__dirname,
'../../packages/react-ui/src',
Expand Down
86 changes: 43 additions & 43 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,66 +52,66 @@
"react-dom": "^18.2.0"
},
"devDependencies": {
"@commitlint/cli": "^17.6.5",
"@commitlint/config-conventional": "^17.6.5",
"@commitlint/cli": "^17.7.1",
"@commitlint/config-conventional": "^17.7.0",
"@mxssfd/dumi-theme-antd-style": "^0.27.5-beta.9",
"@rollup/plugin-json": "^6.0.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/jest-dom": "^6.1.2",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.4.3",
"@tool-pack/basic": "^0.1.1",
"@tool-pack/basic": "^0.1.2",
"@tool-pack/bom": "0.0.1-beta.0",
"@tool-pack/dom": "^0.0.13",
"@tool-pack/types": "^0.0.6",
"@tool-pack/types": "^0.0.9",
"@types/fs-extra": "^11.0.1",
"@types/jest": "^29.5.1",
"@types/node": "^16.18.34",
"@types/react": "^18.2.7",
"@types/react-dom": "^18.2.4",
"@types/testing-library__jest-dom": "^5.14.6",
"@typescript-eslint/eslint-plugin": "^5.59.8",
"@typescript-eslint/parser": "^5.59.8",
"@umijs/lint": "^4.0.0",
"@vitejs/plugin-react": "^4.0.0",
"autoprefixer": "^10.4.14",
"chalk": "^5.2.0",
"@types/jest": "^29.5.4",
"@types/node": "^20.5.6",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"@types/testing-library__jest-dom": "^5.14.9",
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@umijs/lint": "^4.0.78",
"@vitejs/plugin-react": "^4.0.4",
"autoprefixer": "^10.4.15",
"chalk": "^5.3.0",
"conventional-changelog-cli": "^3.0.0",
"cssnano": "^6.0.1",
"dumi": "^2.2.1",
"enquirer": "^2.3.6",
"eslint": "^8.41.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"esno": "^0.16.3",
"execa": "^7.1.1",
"father": "^4.1.0",
"dumi": "^2.2.6",
"enquirer": "^2.4.1",
"eslint": "^8.47.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"esno": "^0.17.0",
"execa": "^8.0.1",
"father": "^4.3.1",
"fs-extra": "^11.1.1",
"gh-pages": "^5.0.0",
"gh-pages": "^6.0.0",
"husky": "^8.0.3",
"lint-staged": "^13.2.2",
"npm-check-updates": "^16.10.12",
"postcss": "^8.4.26",
"lint-staged": "^14.0.1",
"npm-check-updates": "^16.13.1",
"postcss": "^8.4.28",
"postcss-cli": "^10.1.0",
"postcss-merge-rules-plus": "^2.0.0",
"prettier": "^2.8.8",
"prettier-plugin-organize-imports": "^3.0.0",
"prettier-plugin-packagejson": "^2.2.18",
"prettier": "^3.0.2",
"prettier-plugin-organize-imports": "^3.2.3",
"prettier-plugin-packagejson": "^2.4.5",
"react-scripts": "5.0.1",
"rollup": "^3.23.0",
"rollup-plugin-dts": "^5.3.0",
"rollup-plugin-typescript2": "^0.34.1",
"rollup": "^3.28.1",
"rollup-plugin-dts": "^6.0.0",
"rollup-plugin-typescript2": "^0.35.0",
"rxjs": "^7.8.1",
"sass": "^1.62.1",
"serve": "^14.2.0",
"stylelint": "^15.7.0",
"sass": "^1.66.1",
"serve": "^14.2.1",
"stylelint": "^15.10.3",
"stylelint-config-prettier": "^9.0.5",
"stylelint-config-standard": "^33.0.0",
"stylelint-config-standard-scss": "^9.0.0",
"stylelint-config-standard": "^34.0.0",
"stylelint-config-standard-scss": "^10.0.0",
"stylelint-order": "^6.0.3",
"stylelint-scss": "^5.0.1",
"tsc-alias": "^1.8.6",
"typescript": "^5.1.5",
"vite": "^4.3.9",
"stylelint-scss": "^5.1.0",
"tsc-alias": "^1.8.7",
"typescript": "^5.2.2",
"vite": "^4.4.9",
"yalc": "1.0.0-pre.53"
},
"browserslist": {
Expand Down
3 changes: 3 additions & 0 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"test": "react-scripts test --watchAll=false"
},
"jest": {
"testMatch": [
"<rootDir>/src/**/*.(spec|test).(ts|tsx)"
],
"moduleNameMapper": {
"^@pkg/(.+)$": "<rootDir>/../../packages/$1/src",
"^@tool-pack/react-ui$": "<rootDir>/../../packages/react-ui/src",
Expand Down
84 changes: 37 additions & 47 deletions packages/components/src/dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React, { useEffect, useRef, useState } from 'react';
import React, { useRef } from 'react';
import type { RequiredPart } from '@tool-pack/types';
import { getClassNames } from '@tool-pack/basic';
import type {
DropdownDivider,
DropdownOptionsItem,
DropdownDivider,
DropdownOption,
DropdownProps,
} from './dropdown.types';
import { Popover } from '~/popover';
import { Option } from '~/option';
import { getComponentClass } from '@pkg/shared';
import { DropdownInnerOption } from './DropdownInnerOption';
import { getComponentClass, useStateWithTrailClear } from '@pkg/shared';
import { Divider } from '~/divider';
import { DropdownOption } from './dropdown.types';

const defaultProps = {
placement: 'bottom-start',
Expand All @@ -34,22 +34,36 @@ export const Dropdown: React.FC<DropdownProps> = (props) => {
} = props as RequiredPart<DropdownProps, keyof typeof defaultProps>;
const boxRef = useRef<HTMLDivElement>(null);

const [show, setShow] = useState<boolean | undefined>();

useEffect(() => {
show !== undefined && setShow(undefined);
}, [show]);
useEffect(() => {
setShow(visible);
}, [visible]);
const [show, setShow] = useStateWithTrailClear(visible);

const name = 'dropdown';
const rootClass = getComponentClass(name);

const handleOptions = (
const Box = (
<>
{header && <div className={`${rootClass}__header`}>{header}</div>}
<div ref={boxRef} className={`${rootClass}__body`}>
<ul className={`${rootClass}__options`}>{handleOptions(options)}</ul>
</div>
{footer && <div className={`${rootClass}__footer`}>{footer}</div>}
</>
);

return (
<Popover
{...rest}
name={name}
showArrow={showArrow}
visible={show}
content={Box}>
{children}
</Popover>
);

function handleOptions(
options: DropdownOptionsItem[] = [],
parents: DropdownOption[] = [],
): React.ReactElement[] => {
): React.ReactElement[] {
return options.map((opt) => {
if (isDivider(opt)) {
const { key, type: _type, tag = 'li', ...rest } = opt;
Expand All @@ -64,7 +78,6 @@ export const Dropdown: React.FC<DropdownProps> = (props) => {
type,
label,
key,
tag,
children,
attrs: optAttrs = {},
...optRest
Expand All @@ -73,7 +86,7 @@ export const Dropdown: React.FC<DropdownProps> = (props) => {
if (type === 'group') {
return (
<li className={`${rootClass}__group`} key={key}>
<Option
<DropdownInnerOption
{...optRest}
tag="div"
attrs={{
Expand All @@ -83,7 +96,7 @@ export const Dropdown: React.FC<DropdownProps> = (props) => {
size={size}
readonly>
{label}
</Option>
</DropdownInnerOption>
<ul className={`${rootClass}__group-body`}>
{handleOptions(children, [...parents, opt])}
</ul>
Expand All @@ -103,15 +116,14 @@ export const Dropdown: React.FC<DropdownProps> = (props) => {
emit(opt, parents);
};
const option = (
<Option
<DropdownInnerOption
{...optRest}
tag={tag || 'li'}
key={key}
size={size}
expandable={children && !!children.length}
attrs={{ ...optAttrs, onClick }}>
{label}
</Option>
</DropdownInnerOption>
);

if (!children || optRest.disabled) return option;
Expand All @@ -138,33 +150,11 @@ export const Dropdown: React.FC<DropdownProps> = (props) => {
</Dropdown>
);
});
};

const Box = (
<>
{header && <div className={`${rootClass}__header`}>{header}</div>}
<div ref={boxRef} className={`${rootClass}__body`}>
<ul className={`${rootClass}__options`}>{handleOptions(options)}</ul>
</div>
{footer && <div className={`${rootClass}__footer`}>{footer}</div>}
</>
);

return (
<Popover
{...rest}
name={name}
showArrow={showArrow}
visible={show}
content={Box}>
{children}
</Popover>
);
}
function isDivider(opt: DropdownOptionsItem): opt is DropdownDivider {
return (opt as DropdownDivider).type === 'divider';
}
};

Dropdown.defaultProps = defaultProps;
Dropdown.displayName = 'Dropdown';

function isDivider(opt: DropdownOptionsItem): opt is DropdownDivider {
return (opt as DropdownDivider).type === 'divider';
}
42 changes: 42 additions & 0 deletions packages/components/src/dropdown/DropdownInnerOption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { DropdownOptionProps } from '~/dropdown/dropdown.types';
import { Option } from '~/option';
import { getComponentClass } from '@pkg/shared';
import { getClassNames } from '@tool-pack/basic';
import { Icon } from '~/icon';
import { Right as RightIcon } from '@pkg/icons';

const rootClass = getComponentClass('dropdown-option');
const defaultProps = {
tag: 'li',
} satisfies Partial<DropdownOptionProps>;

export const DropdownInnerOption: React.FC<DropdownOptionProps> =
React.forwardRef<HTMLElement, DropdownOptionProps>((props, ref) => {
const { expandable, children, extra, attrs = {}, ...rest } = props;
return (
<Option
{...rest}
ref={ref}
attrs={{
...attrs,
className: getClassNames(rootClass, attrs.className),
}}
extra={
(extra || expandable) && (
<>
{extra}
{expandable && (
<Icon className={`${rootClass}__expand`}>
<RightIcon />
</Icon>
)}
</>
)
}>
{children}
</Option>
);
});

DropdownInnerOption.defaultProps = defaultProps;
Loading

0 comments on commit 3e03b51

Please sign in to comment.