Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge #9

Merged
merged 4 commits into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
},
"homepage": "https://sunshineLixun.github.io/pro-components",
"scripts": {
"clean": "rimraf -rf packages/*/{node_modules,dist,es,lib} && rimraf node_modules",
"commit": "git-cz",
"build": "pnpm run build --filter ./packages",
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "TIMING=1 eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
Expand Down Expand Up @@ -41,16 +43,19 @@
"@vue/eslint-config-typescript": "^10.0.0",
"@vue/test-utils": "^2.0.0-rc.20",
"@vue/tsconfig": "^0.1.3",
"ant-design-vue": "^3.2.15",
"commitizen": "^4.2.5",
"eslint": "^8.13.0",
"eslint-plugin-vue": "^8.6.0",
"gh-pages": "^4.0.0",
"jsdom": "^19.0.0",
"prettier": "^2.6.2",
"rimraf": "^3.0.2",
"typescript": "~4.5.5",
"vite": "^3.1.3",
"vitest": "^0.5.9",
"vue": "^3.2.38",
"vue-tsc": "^0.34.7"
"vite": "^2.9.14",
"vitest": "^0.27.2",
"vue": "^3.2.45",
"vue-tsc": "^1.0.24"
},
"lint-staged": {
"*.{js,ts,vue,json}": [
Expand All @@ -63,5 +68,10 @@
"@algolia/client-search"
]
}
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
}
}
10 changes: 2 additions & 8 deletions packages/pro-field/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@
"dependencies": {
"@ant-design/icons-vue": "^6.1.0",
"@types/lodash-es": "^4.17.6",
"ant-design-vue": "^3.2.12",
"dayjs": "^1.11.5",
"vue": "^3.2.39",
"vue-router": "^4.1.5"
"dayjs": "^1.11.5"
},
"devDependencies": {
"@ant-design-vue/pro-utils": "workspace:^0.0.0",
Expand All @@ -54,10 +51,7 @@
"jsdom": "^19.0.0",
"less": "^4.1.2",
"prettier": "^2.6.2",
"typescript": "~4.5.5",
"vite": "^2.9.5",
"vitest": "^0.5.9",
"vue-tsc": "^0.34.7"
"vue-router": "^4.1.5"
},
"contributors": [
"sunshineLixun <1261142605@qq.com>"
Expand Down
87 changes: 87 additions & 0 deletions packages/pro-field/src/components/Radio/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {
defineComponent,
type App,
DefineComponent,
Plugin,
computed,
} from "vue";
import { fieldRadioProps, FieldRadioProps } from "./types";
import { Radio } from "ant-design-vue";
import { getSlot, VueText, objToMap } from "@ant-design-vue/pro-utils";
import { proFieldParsingText } from "../Select";

export const slots = ["renderExtraFooter", "suffixIcon", "clearIcon"];

const FieldRadio = defineComponent({
name: "FieldRadio",
inheritAttrs: false,
props: fieldRadioProps,
slots,
setup(props, { slots }) {
const render = getSlot(
slots,
props.fieldProps as Record<string, any>,
"render"
) as Function;
const renderFormItem = getSlot(
slots,
props.fieldProps as Record<string, any>,
"renderFormItem"
) as Function;
const children = getSlot(
slots,
props.fieldProps as Record<string, any>,
"default"
);

return () => {
const { mode, text, valueEnum, fieldProps = {} } = props;
const { options } = fieldProps;

if (mode === "read") {
const optionsValueEnum = options?.length
? options?.reduce((pre: any, cur: any) => {
return { ...pre, [cur.value ?? ""]: cur.label };
}, {})
: undefined;
const dom = (
<>
{proFieldParsingText(
text as VueText,
objToMap(valueEnum || optionsValueEnum)
)}
</>
);

if (render) {
return render(text, { mode, ...fieldProps }, dom) || null;
}
return dom;
}

if (mode === "edit") {
const dom = (
<Radio.Group
{...fieldProps}
options={options}
v-slots={{
default: children,
}}
/>
);
if (renderFormItem) {
return renderFormItem(text, { mode, ...fieldProps }, dom);
}
return dom;
}
return null;
};
},
});

FieldRadio.install = (app: App) => {
app.component(FieldRadio.name, FieldRadio);
return app;
};

export default FieldRadio as DefineComponent<FieldRadioProps> & Plugin;
12 changes: 12 additions & 0 deletions packages/pro-field/src/components/Radio/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ExtractPropTypes, PropType } from "vue";
import type { RadioGroupProps } from "ant-design-vue/es/radio/Group";
import { proFieldFC } from "../typings";

export const fieldRadioProps = {
...proFieldFC,
fieldProps: {
type: Object as PropType<RadioGroupProps>,
},
};

export type FieldRadioProps = Partial<ExtractPropTypes<typeof fieldRadioProps>>;
143 changes: 122 additions & 21 deletions packages/pro-field/src/components/Select/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,67 @@
import { defineComponent, type App, DefineComponent, Plugin, PropType, ExtractPropTypes } from 'vue';
import { getSlot, type ProFieldRequestData } from '@ant-design-vue/pro-utils';
import { Spin } from 'ant-design-vue';
import renderEmpty from 'ant-design-vue/es/config-provider/renderEmpty';
import SearchSelect from './SearchSelect';
import type { SearchSelectProps } from './SearchSelect/types';
import { proFieldFC } from '../typings';
import { useFetchData } from './hooks/useFetchData';
import {
defineComponent,
computed,
type App,
DefineComponent,
Plugin,
PropType,
ExtractPropTypes,
Fragment,
} from "vue";
import {
getSlot,
objToMap,
type ProFieldRequestData,
ProFieldValueEnumType,
ProSchemaValueEnumObj,
VueNode,
} from "@ant-design-vue/pro-utils";
import { Spin, Space } from "ant-design-vue";
import renderEmpty from "ant-design-vue/es/config-provider/renderEmpty";
import SearchSelect from "./SearchSelect";
import type { SearchSelectProps } from "./SearchSelect/types";
import { proFieldFC } from "../typings";
import { useFetchData } from "./hooks/useFetchData";

export const proFieldParsingText = (
text: string | number | (string | number)[],
valueEnumParams: ProFieldValueEnumType,
key?: number | string
): VueNode => {
if (Array.isArray(text)) {
return (
// Space暂时还不支出split属性
<Space key={key} size={2} wrap>
{text.map((value, index) =>
// @ts-ignore
proFieldParsingText(value, valueEnumParams, index)
)}
</Space>
);
}

const valueEnum = objToMap(valueEnumParams);

if (!valueEnum.has(text) && !valueEnum.has(`${text}`)) {
// @ts-ignore
return text?.label || text;
}

const domText = (valueEnum.get(text) || valueEnum.get(`${text}`)) as {
text: VueNode;
color?: string;
};

if (!domText) {
// @ts-ignore
return <Fragment key={key}>{text?.label || text}</Fragment>;
}

// 什么都没有使用 text
return (
<Fragment key={key}>{domText.text || (domText as any as VueNode)}</Fragment>
);
};

export const fieldSelectProps = {
...proFieldFC,
Expand All @@ -15,30 +71,71 @@ export const fieldSelectProps = {
// 请求
request: {
type: Function as PropType<ProFieldRequestData>,
},
}
};
export type FieldSelectProps = Partial<ExtractPropTypes<typeof fieldSelectProps>>;
export type FieldSelectProps = Partial<
ExtractPropTypes<typeof fieldSelectProps>
>;

const FieldSelect = defineComponent({
inheritAttrs: false,
props: fieldSelectProps,
slots: ['render', 'renderFormItem'],
slots: ["render", "renderFormItem"],
setup(props, { slots }) {
const { defaultKeyWords, loading, options } = useFetchData(props);
return () => {
const { mode, text, fieldProps } = props;
const render = getSlot(slots, props, 'render') as any;
const renderFormItem = getSlot(slots, props, 'renderFormItem') as any;

if (mode === 'read') {
const dom = <>{text}</>;
const optionsValueEnum = computed(() => {
if (props.mode !== "read") return;

const {
label: labelPropsName = "label",
value: valuePropsName = "value",
options: optionsPropsName = "options",
} = (props.fieldProps || {}).fieldNames || {};

const valuesMap = new Map();

const traverseOptions = (_options: SearchSelectProps['options']) => {
if (!_options?.length) {
return valuesMap;
}
const length = _options.length;
let i = 0;
while (i < length) {
const cur = _options[i++];
valuesMap.set(cur[valuePropsName], cur[labelPropsName]);
traverseOptions(cur[optionsPropsName]);
}
return valuesMap;
};

return traverseOptions(options.value);
});


return () => {
const { mode, text, valueEnum, fieldProps } = props;
const render = getSlot(slots, props, "render") as any;
const renderFormItem = getSlot(slots, props, "renderFormItem") as any;

if (mode === "read") {
const dom = (
<>
{proFieldParsingText(
text as string | string[],
objToMap(
valueEnum || optionsValueEnum.value
) as unknown as ProSchemaValueEnumObj
)}
</>
);
if (render) {
return render(text, { mode, fieldProps }, dom) || null;
}
return dom;
}
if (mode === 'edit' || mode === 'update') {
const hasChildren = typeof fieldProps?.default === 'function';
if (mode === "edit" || mode === "update") {
const hasChildren = typeof fieldProps?.default === "function";
const renderDom = (
<SearchSelect
style={{
Expand All @@ -49,10 +146,14 @@ const FieldSelect = defineComponent({
options={hasChildren ? undefined : options.value}
default={hasChildren ? fieldProps?.default : undefined}
fetchData={(value) => (defaultKeyWords.value = value)}
resetData={() => (defaultKeyWords.value = '')}
resetData={() => (defaultKeyWords.value = "")}
v-slots={{
notFoundContent: () => {
return loading.value ? <Spin size={'small'} /> : fieldProps?.notFoundContent || renderEmpty('Select');
return loading.value ? (
<Spin size={"small"} />
) : (
fieldProps?.notFoundContent || renderEmpty("Select")
);
},
}}
/>
Expand Down
4 changes: 2 additions & 2 deletions packages/pro-field/src/components/TimePicker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const FieldTimePicker = defineComponent({
'renderExtraFooter'
);

const render = getSlot(slots, props.fieldProps as Record<string, any>, 'render') as any;
const renderFormItem = getSlot(slots, props.fieldProps as Record<string, any>, 'renderFormItem') as any;
const render = getSlot(slots, props.fieldProps as Record<string, any>, 'render') as Function;
const renderFormItem = getSlot(slots, props.fieldProps as Record<string, any>, 'renderFormItem') as Function;

return () => {
const { mode, text, fieldProps } = props;
Expand Down
Loading