Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/panyushan'
Browse files Browse the repository at this point in the history
  • Loading branch information
panyushan-jade committed Jan 30, 2023
2 parents b5e4b8c + ea5bbaf commit 308de03
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 23 deletions.
42 changes: 21 additions & 21 deletions src/components/IconFont/icon.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,33 @@ import { storiesOf } from "@storybook/react";
// import { action } from "@storybook/addon-actions";
// import { withInfo } from '@storybook/addon-info'

import IconFont from "./index";
import Icon from "./index";

const IconFontComp = () => (
<div style={{ width: 500, display: "flex", justifyContent: "space-evenly" }}>
<IconFont type="icon-closefill" color="red" />
<IconFont type="icon-propertysafety-fill" color="red" />
<IconFont type="icon-mobile" />
<IconFont type="icon-folder-add" />
<IconFont type="icon-wifi" />
<IconFont type="icon-tag" />
<IconFont type="icon-arrowright" />
<IconFont type="icon-arrowup" />
<IconFont type="icon-arrowleft" />
<IconFont type="icon-arrowdown" />
<IconFont type="icon-YUAN" />
<IconFont type="icon-edit-square" />
<IconFont type="icon-deleteteam" />
<IconFont type="icon-transaction" />
<IconFont type="icon-folder-open-fill" />
<IconFont type="icon-dashboard-fill" />
<IconFont type="icon-customerservice-fill" />
<IconFont type="icon-small-dash" />
<IconFont type="icon-fullscreen" />
<Icon type="icon-closefill" color="red" />
<Icon type="icon-propertysafety-fill" color="red" />
<Icon type="icon-mobile" />
<Icon type="icon-folder-add" />
<Icon type="icon-wifi" />
<Icon type="icon-tag" />
<Icon type="icon-arrowright" />
<Icon type="icon-arrowup" />
<Icon type="icon-arrowleft" />
<Icon type="icon-arrowdown" />
<Icon type="icon-YUAN" />
<Icon type="icon-edit-square" />
<Icon type="icon-deleteteam" />
<Icon type="icon-transaction" />
<Icon type="icon-folder-open-fill" />
<Icon type="icon-dashboard-fill" />
<Icon type="icon-customerservice-fill" />
<Icon type="icon-small-dash" />
<Icon type="icon-fullscreen" />
</div>
);

const SpinIconFont = () => <IconFont type="icon-loading" spin />;
const SpinIconFont = () => <Icon type="icon-loading" spin />;

storiesOf("Icon图标", module)
.add("IconFont", IconFontComp)
Expand Down
4 changes: 2 additions & 2 deletions src/components/IconFont/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function createScript() {
* import { Icon } from 'jadedui'
* ~~~
*/
const IconFont: FC<IconFontProps> = (props) => {
const Icon: FC<IconFontProps> = (props) => {
const { type, color, spin = false, ...restProps } = props;
createScript();

Expand All @@ -51,4 +51,4 @@ const IconFont: FC<IconFontProps> = (props) => {
);
};

export default IconFont;
export default Icon;
72 changes: 72 additions & 0 deletions src/components/Rate/_style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
.dui-rate {
display: flex;

svg {
color: $rate-color-default;
font-size: 25px;
}

.dui-rate-star:not(:last-child) {
margin-right: 8px;
}

.dui-rate-star {
position: relative;
transition: all 0.2s;

.dui-rate-star-first {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
overflow: hidden;
opacity: 0;
color: $rate-color-default;
font-size: 25px;
}

.dui-rate-star-second {
color: $rate-color-default;
font-size: 25px;
}
}

.dui-rate-star:hover {
transform: scale(1.1);
}

.dui-rate-star-disabled:hover {
transform: none;
}

.dui-rate-star.ant-rate-star-half {
.dui-rate-star-first {
opacity: 1;
color: $rate-color;

svg {
color: $rate-color;
}
}
}

.dui-rate-star.ant-rate-star-full {
.dui-rate-star-first {
opacity: 0;
color: $rate-color-default;

svg {
color: $rate-color-default;
}
}

.dui-rate-star-second {
color: $rate-color;

svg {
color: $rate-color;
}
}
}
}
168 changes: 168 additions & 0 deletions src/components/Rate/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import React, { useEffect, useState } from "react";
import type { ReactNode } from "react";
import classnames from "classnames";
import Icon from "../IconFont";

export type OrientationType = "left" | "right" | "center";

export interface RateProps {
/** 自定义样式类名 */
className?: string;
/** 自定义样式对象 */
style?: React.CSSProperties;
/** 当前数,受控值 */
value?: number;
/** 默认值 */
defaultValue?: number;
/** 只读,无法进行交互 */
disabled?: boolean;
/** 自定义字符 */
character?: ReactNode | ((index: number) => ReactNode);
/** 选择时的回调 */
onChange?: (value: number) => void;
}

/**
* Rate 评分
* 对评价进行展示
* 对事物进行快速的评级操作
* ### 引用方法
*
* ~~~js
* import { Rate } from 'jadedui'
* ~~~
*/
const Rate: React.FC<RateProps> = (props) => {
const { className, value, defaultValue, character, disabled, onChange } =
props;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [ids, setIds] = useState<number[]>([0, 1, 2, 3, 4]);
const [rateValue, setRateValue] = useState<[number, number]>([-1, -1]);
// const [rateDefaultValue,setRateDefaultValue] = useState<[number,number]>([-1,-1]);
const [pos, setPos] = useState<any>({
curIndexLi: -1,
curIndexStar: -1,
isFocus: false,
});
const cls = ["ant-rate-star-half", "ant-rate-star-full"];
if (
(value && typeof value !== "number") ||
(defaultValue && typeof defaultValue !== "number")
) {
throw new Error("value or defaultValue must be a number!");
}

const initRate = () => {
if (value || defaultValue) {
const transValue = String(value || defaultValue).split(".");
const curIndexLi = Number(transValue[0]);
const curIndexStar = transValue[1]
? Number(transValue[1]) >= 5
? 0
: -1
: -1;
console.log("curIndexLi: ", curIndexLi);
console.log("curIndexStar: ", curIndexStar);
setRateValue([curIndexLi, curIndexStar]);
setPos({
curIndexLi,
curIndexStar,
isFocus: true,
});
}
};

useEffect(() => {
initRate();
}, [value]);

const onMouseFirstEnter = (d: number, curStar: number) => {
if (disabled) return;
const curIndex = ids.findIndex((id) => id == d);
setPos({
...pos,
curIndexLi: curIndex,
curIndexStar: curStar,
});
};

const renderClassNames = (key: number) => {
let classNames = "dui-rate-star";
if (disabled) classNames += " dui-rate-star-disabled";
if (pos.curIndexLi === -1) {
classNames += " dui-rate-star-zero";
} else {
if (key < pos.curIndexLi) {
classNames += " ant-rate-star-full";
return classNames;
}
if (key == pos.curIndexLi) {
classNames += " " + cls[pos.curIndexStar];
return classNames;
}
if (key > pos.curIndexLi) {
classNames += " dui-rate-star-zero";
}
}

return classNames;
};

const rateClickHandle = (type: string, key: number) => {
if (value || disabled) return;
onMouseFirstEnter(key, type === "first" ? 0 : 1);
setRateValue([key, type === "first" ? 0 : 1]);
setPos({
...pos,
isFocus: true,
});
onChange && onChange(type === "first" ? key + 0.5 : key + 1);
};

const onMouseLeave = () => {
if (disabled) return;
if (!pos.isFocus) {
onMouseFirstEnter(-1, -1);
} else {
onMouseFirstEnter(...rateValue);
}
};

const renderNode = (key: number) =>
typeof character === "function" ? character(key) : character;

return (
<ul
className={classnames("dui-rate", className)}
onMouseLeave={onMouseLeave}
>
{ids.map((key) => {
return (
<li className={renderClassNames(key)} key={key}>
<div
className="dui-rate-star-first"
onMouseEnter={() => onMouseFirstEnter(key, 0)}
onClick={() => rateClickHandle("first", key)}
>
{renderNode(key)}
</div>
<div
className="dui-rate-star-second"
onMouseEnter={() => onMouseFirstEnter(key, 1)}
onClick={() => rateClickHandle("second", key)}
>
{renderNode(key)}
</div>
</li>
);
})}
</ul>
);
};

Rate.defaultProps = {
character: <Icon type="icon-star" />,
disabled: false,
};

export default Rate;
28 changes: 28 additions & 0 deletions src/components/Rate/rate.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from "react";
import { storiesOf } from "@storybook/react";
// import { action } from "@storybook/addon-actions";
// import { withInfo } from '@storybook/addon-info'

import Rate from "./index";

const defaultRate = () => {
const onChange = (v: any) => {
console.log("v: ", v);
};
return <Rate onChange={onChange} />;
};

const characterRate = () => (
<>
<Rate character="好" />
<Rate character="A" />
<Rate character={() => <span></span>} />
</>
);

const disableRate = () => <Rate defaultValue={2.7} disabled />;

storiesOf("Rate 评分", module)
.add("Rate", defaultRate)
.add("只读 Rate", disableRate)
.add("自定义字符 Rate", characterRate);
1 change: 1 addition & 0 deletions src/styles/_reboot.scss
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ address {
ol,
ul {
padding-left: 2rem;
list-style: none;
}

ol,
Expand Down
4 changes: 4 additions & 0 deletions src/styles/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,7 @@ $alert-padding-x-right: 1rem !default;
$alert-font-color: #000000d9;
$alert-message-font-size: $font-size-base * 1.1 !default;
$alert-description-font-size: $font-size-base * 0.8 !default;

// Rate
$rate-color: $yellow !default;
$rate-color-default: $gray-200 !default;
3 changes: 3 additions & 0 deletions src/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@

//Divider
@import "../components/Divider/style";

//Rate
@import "../components/Rate/style";
1 change: 1 addition & 0 deletions todoList.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
- 图片水印
canvas、mutationObserver
- Flip 动画思路
- 滑动验证码

<!-- "build": "npm run clean && npm run build-ts && npm run build-css", -->

0 comments on commit 308de03

Please sign in to comment.