@fe-free/core 2.5.6 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @fe-free/core
2
2
 
3
+ ## 2.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - feat: slider
8
+
9
+ ### Patch Changes
10
+
11
+ - @fe-free/tool@2.6.0
12
+
13
+ ## 2.5.7
14
+
15
+ ### Patch Changes
16
+
17
+ - feat: crud
18
+ - @fe-free/tool@2.5.7
19
+
3
20
  ## 2.5.6
4
21
 
5
22
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/core",
3
- "version": "2.5.6",
3
+ "version": "2.6.0",
4
4
  "description": "",
5
5
  "main": "./src/index.ts",
6
6
  "author": "",
@@ -41,7 +41,7 @@
41
41
  "remark-gfm": "^4.0.1",
42
42
  "vanilla-jsoneditor": "^0.23.1",
43
43
  "zustand": "^4.5.4",
44
- "@fe-free/tool": "2.5.6"
44
+ "@fe-free/tool": "2.6.0"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@ant-design/pro-components": "2.8.9",
@@ -41,6 +41,8 @@ function CRUDOfPureComponent(props: CRUDOfPureProps, ref: React.ForwardedRef<CRU
41
41
  <div
42
42
  className={classNames('fec-crud-of-pure', {
43
43
  'fec-crud-of-pure-no-search': noSearch,
44
+ // 先这样实现
45
+ 'fec-crud-of-pure-no-toolbar': !props.actions.includes('create'),
44
46
  })}
45
47
  >
46
48
  <CRUD
@@ -4,7 +4,7 @@
4
4
  }
5
5
 
6
6
  .ant-pro-query-filter.ant-pro-query-filter {
7
- padding: 8px 16px;
7
+ padding: 16px;
8
8
  }
9
9
 
10
10
  .ant-pro-card .ant-pro-card-body {
@@ -40,12 +40,18 @@
40
40
  }
41
41
 
42
42
  .ant-pro-table-list-toolbar-container {
43
- padding-block: 0 8px;
43
+ padding-block: 0 16px;
44
44
  }
45
45
 
46
46
  &.fec-crud-of-pure-no-search {
47
47
  .ant-pro-table-list-toolbar-container {
48
- padding-block-start: 8px;
48
+ padding-block-start: 16px;
49
+ }
50
+ }
51
+
52
+ &.fec-crud-of-pure-no-toolbar {
53
+ .ant-pro-table-list-toolbar-container {
54
+ padding-block: 0;
49
55
  }
50
56
  }
51
57
  }
package/src/index.ts CHANGED
@@ -43,6 +43,8 @@ export type { InfiniteListProps } from './infinite_list';
43
43
  export { Markdown } from './markdown';
44
44
  export { PageLayout } from './page_layout';
45
45
  export { routeTool } from './route';
46
+ export { NumberSlider, PercentageSlider } from './slider';
47
+ export type { NumberSliderProps, PercentageSliderProps } from './slider';
46
48
  export { Table } from './table';
47
49
  export type { TableProps } from './table';
48
50
  export { Tabs } from './tabs';
@@ -0,0 +1,124 @@
1
+ import { InputNumber, Slider } from 'antd';
2
+ import classNames from 'classnames';
3
+ import { useCallback, useMemo } from 'react';
4
+ import './style.scss';
5
+
6
+ interface NumberSliderProps {
7
+ /** 默认 0 */
8
+ value?: number;
9
+ onChange: (value: number) => void;
10
+ /** 默认 0 */
11
+ min?: number;
12
+ /** 默认 100 */
13
+ max?: number;
14
+ /** 默认 1 */
15
+ step?: number;
16
+ /** 输入框的数值精度,默认 0 */
17
+ precision?: number;
18
+ }
19
+
20
+ function NumberSlider(props: NumberSliderProps) {
21
+ const { value = 0, onChange, min = 0, max = 100, step = 1, precision = 0 } = props;
22
+ return (
23
+ <div className="flex gap-2">
24
+ <div className="flex-1">
25
+ <Slider
26
+ value={value}
27
+ onChange={onChange}
28
+ min={min}
29
+ max={max}
30
+ step={step}
31
+ marks={{
32
+ [min]: min,
33
+ [value]: value,
34
+ [max]: max,
35
+ }}
36
+ />
37
+ </div>
38
+ <div>
39
+ <InputNumber
40
+ value={value}
41
+ onChange={(v) => onChange(v ?? 0)}
42
+ min={min}
43
+ max={max}
44
+ step={step}
45
+ precision={precision}
46
+ />
47
+ </div>
48
+ </div>
49
+ );
50
+ }
51
+
52
+ interface PercentageSliderProps {
53
+ /** 百分占比数组 */
54
+ value: number[];
55
+ onChange: (value: number[]) => void;
56
+ /** 默认 0 */
57
+ min?: number;
58
+ /** 默认 100 */
59
+ max?: number;
60
+ /** 默认 1 */
61
+ step?: number;
62
+ className?: string;
63
+ }
64
+
65
+ function PercentageSlider(props: PercentageSliderProps) {
66
+ const { value, onChange, min = 0, max = 100, step = 1, className } = props;
67
+
68
+ const sliderValue = useMemo(() => {
69
+ let sum = min;
70
+ return value
71
+ .map((v) => {
72
+ sum += v;
73
+ return sum;
74
+ })
75
+ .slice(0, -1);
76
+ }, [value, min]);
77
+
78
+ const handleChange = useCallback(
79
+ (newValue: number[]) => {
80
+ const result = [...newValue, max].map((v, i) => v - (newValue[i - 1] || min));
81
+ onChange(result);
82
+ },
83
+ [max, min, onChange],
84
+ );
85
+
86
+ const marks = useMemo(() => {
87
+ const result = {
88
+ [min]: min,
89
+ [max]: max,
90
+ };
91
+
92
+ [...sliderValue, max].forEach((v, i) => {
93
+ const m = value[i] / 2 + (sliderValue[i - 1] || min);
94
+ result[m] = value[i];
95
+ // result[v] = value[i];
96
+ });
97
+
98
+ return result;
99
+ }, [min, max, sliderValue, value]);
100
+
101
+ return (
102
+ <Slider
103
+ value={sliderValue}
104
+ onChange={handleChange}
105
+ min={min}
106
+ max={max}
107
+ step={step}
108
+ range
109
+ marks={marks}
110
+ styles={{
111
+ rail: {
112
+ backgroundColor: '#91caff',
113
+ },
114
+ track: {
115
+ backgroundColor: 'transparent',
116
+ },
117
+ }}
118
+ className={classNames('fec-slider', className)}
119
+ />
120
+ );
121
+ }
122
+
123
+ export { NumberSlider, PercentageSlider };
124
+ export type { NumberSliderProps, PercentageSliderProps };
@@ -0,0 +1,32 @@
1
+ import { NumberSlider } from '@fe-free/core';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+ import { useState } from 'react';
4
+
5
+ const meta: Meta<typeof NumberSlider> = {
6
+ title: '@fe-free/core/NumberSlider',
7
+ component: NumberSlider,
8
+ tags: ['autodocs'],
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<typeof NumberSlider>;
14
+
15
+ function Render(args: Story['args']) {
16
+ const [value, setValue] = useState(0);
17
+ return <NumberSlider value={value} onChange={setValue} {...args} />;
18
+ }
19
+
20
+ export const Basic: Story = {
21
+ args: {},
22
+ render: Render,
23
+ };
24
+
25
+ export const One: Story = {
26
+ args: {
27
+ max: 1,
28
+ step: 0.1,
29
+ precision: 1,
30
+ },
31
+ render: Render,
32
+ };
@@ -0,0 +1,23 @@
1
+ import { PercentageSlider } from '@fe-free/core';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+ import { useState } from 'react';
4
+
5
+ const meta: Meta<typeof PercentageSlider> = {
6
+ title: '@fe-free/core/PercentageSlider',
7
+ component: PercentageSlider,
8
+ tags: ['autodocs'],
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<typeof PercentageSlider>;
14
+
15
+ function Render(args: Story['args']) {
16
+ const [value, setValue] = useState([10, 30, 60]);
17
+ return <PercentageSlider value={value} onChange={setValue} {...args} />;
18
+ }
19
+
20
+ export const Basic: Story = {
21
+ args: {},
22
+ render: Render,
23
+ };
@@ -0,0 +1,16 @@
1
+ .fec-slider {
2
+ .ant-slider-step {
3
+ .ant-slider-dot {
4
+ visibility: hidden;
5
+
6
+ &:first-child,
7
+ &:last-child {
8
+ visibility: visible;
9
+ }
10
+ }
11
+ }
12
+
13
+ .ant-slider-mark-text {
14
+ color: inherit !important;
15
+ }
16
+ }