aio-range 1.0.0 → 1.0.1

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/index.css CHANGED
@@ -0,0 +1,190 @@
1
+ .ai-range {
2
+ display: flex;
3
+ position: relative;
4
+ user-select: none;
5
+ }
6
+
7
+
8
+ .aio-input-range-value {
9
+ width: 100%;
10
+ overflow: visible;
11
+ }
12
+
13
+ .ai-range-horizontal {
14
+ height: 48px;
15
+ align-items: center;
16
+ width: 100%;
17
+ }
18
+
19
+ .ai-range-horizontal .ai-range-groove {
20
+ height: 1px;
21
+ width: 100%;
22
+ background: #ddd;
23
+ }
24
+
25
+ .ai-range-vertical {
26
+ width: 48px;
27
+ height: 240px;
28
+ justify-content: center;
29
+ margin: 12px 0;
30
+ }
31
+
32
+ .ai-range-vertical .ai-range-groove {
33
+ width: 1px;
34
+ height: 100%;
35
+ background: #ddd;
36
+ }
37
+
38
+ .ai-range-reverse {
39
+ direction: rtl;
40
+ }
41
+
42
+ .ai-range-round {
43
+ border-radius: 100%;
44
+ justify-content: center;
45
+ align-items: center;
46
+ height: unset;
47
+ }
48
+
49
+ .ai-range-value-container {
50
+ display: flex;
51
+ align-items: center;
52
+ width: 0;
53
+ height: 0;
54
+ justify-content: center;
55
+ overflow: visible;
56
+ position: absolute;
57
+ z-index: 10;
58
+ }
59
+
60
+ .ai-range-round .ai-range-value-container {
61
+ justify-content: flex-end;
62
+ }
63
+
64
+ .aio-input-handle {
65
+ position: absolute;
66
+ width: 0;
67
+ height: 0;
68
+ }
69
+
70
+ .ai-range-label-container {
71
+ position: absolute;
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ width: 0;
76
+ height: 0;
77
+ }
78
+
79
+ .ai-range-round .ai-range-label-container {
80
+ justify-content: flex-end;
81
+ }
82
+
83
+ .ai-range-labels {
84
+ position: absolute;
85
+ }
86
+
87
+ .ai-range-horizontal .ai-range-labels {
88
+ width: 100%;
89
+ height: 100%;
90
+ }
91
+
92
+ .ai-range-vertical .ai-range-labels {
93
+ width: 100%;
94
+ height: 100%;
95
+ }
96
+
97
+ .ai-range-label {
98
+ position: absolute;
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ font-size: 12px;
103
+ }
104
+
105
+ .ai-range-label>* {
106
+ position: absolute;
107
+ }
108
+
109
+ .ai-range-value {
110
+ padding: 0 16px;
111
+ }
112
+
113
+ .ai-range-point-container {
114
+ position: absolute;
115
+ display: flex;
116
+ align-items: center;
117
+ justify-content: center;
118
+ width: 0;
119
+ height: 0;
120
+ }
121
+
122
+ .ai-range-point-container>* {
123
+ position: absolute;
124
+ }
125
+
126
+ .ai-range-point {
127
+ height: 2em;
128
+ width: 2em;
129
+ font-size: 0.8em;
130
+ border-radius: 48px;
131
+ background: #0069ff;
132
+ color: #fff;
133
+ display: flex;
134
+ align-items: center;
135
+ justify-content: center;
136
+ }
137
+
138
+ .ai-range-range {
139
+ position: absolute;
140
+ }
141
+
142
+ .ai-range-scale-container {
143
+ position: absolute;
144
+ display: flex;
145
+ align-items: center;
146
+ justify-content: center;
147
+ width: 0;
148
+ height: 0;
149
+ }
150
+
151
+ .ai-range-round .ai-range-scale-container {
152
+ justify-content: flex-end;
153
+ }
154
+
155
+ .ai-range-scale {
156
+ position: absolute;
157
+ display: flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+ background: #999;
161
+ font-size: 12px;
162
+ width: 1px;
163
+ height: 6px;
164
+
165
+ }
166
+
167
+ .ai-range-round .ai-range-scale {
168
+ height: 2px;
169
+ width: 6px;
170
+ left: 6px;
171
+ }
172
+
173
+ .ai-range-vertical .ai-range-scale {
174
+ height: 2px;
175
+ width: 6px;
176
+ }
177
+
178
+ .ai-range-fill {
179
+ background: #0069ff;
180
+ position: absolute;
181
+ z-index: 10;
182
+ }
183
+
184
+ .ai-range-horizontal .ai-range-fill {
185
+ height: 4px;
186
+ }
187
+
188
+ .ai-range-vertical .ai-range-fill {
189
+ width: 4px;
190
+ }
package/index.d.ts ADDED
@@ -0,0 +1,157 @@
1
+ import { FC, ReactNode } from "react";
2
+ import './index.css';
3
+ export type AI_RangeContext = {
4
+ rangeHook: ReturnType<typeof useRange>;
5
+ };
6
+ type AI_sbp = (size: number, half?: boolean) => number;
7
+ type AI_rbs = (range: I_range) => {
8
+ thickness: number;
9
+ color: string;
10
+ roundCap: boolean;
11
+ offset: number;
12
+ className?: string;
13
+ from: number;
14
+ to: number;
15
+ };
16
+ export type AI_label = {
17
+ list?: number[];
18
+ start?: number;
19
+ end?: number;
20
+ step?: number;
21
+ dynamic?: boolean;
22
+ autoHide?: boolean;
23
+ zIndex?: number;
24
+ setting: (value: number, p: {
25
+ angle: number;
26
+ disabled: boolean;
27
+ }) => AI_labelItem;
28
+ };
29
+ export type AI_labelItem = {
30
+ offset?: number;
31
+ fixAngle?: boolean;
32
+ html?: ReactNode;
33
+ config?: {
34
+ thickness: number;
35
+ height: number;
36
+ color: string;
37
+ };
38
+ };
39
+ export type I_range = {
40
+ thickness: number;
41
+ offset: number;
42
+ color?: string;
43
+ roundCap?: boolean;
44
+ full?: boolean;
45
+ className?: string;
46
+ from: number;
47
+ to: number;
48
+ style?: any;
49
+ };
50
+ export type I_Range = {
51
+ value?: any;
52
+ start?: number;
53
+ end?: number;
54
+ max?: number;
55
+ min?: number;
56
+ step?: number;
57
+ onChange?: (v: any) => void;
58
+ multiple?: boolean;
59
+ text?: ReactNode;
60
+ style?: any;
61
+ attrs?: any;
62
+ className?: string;
63
+ disabled?: boolean;
64
+ reverse?: boolean;
65
+ size?: number;
66
+ vertical?: boolean;
67
+ rotate?: number;
68
+ round?: number;
69
+ grooveAttrs?: {
70
+ [key: string]: any;
71
+ };
72
+ labels?: AI_label[];
73
+ ranges?: I_range[];
74
+ rangeOption?: {
75
+ pointHtml?: (p: {
76
+ index: number;
77
+ value: number;
78
+ disabled: boolean;
79
+ angle: number;
80
+ }) => ReactNode | false | undefined;
81
+ pointOffset?: (p: {
82
+ index: number;
83
+ value: number;
84
+ disabled: boolean;
85
+ angle: number;
86
+ }) => number | undefined;
87
+ disabled?: (value: number) => boolean;
88
+ fill?: (startPoint: {
89
+ index: number;
90
+ value: number;
91
+ }, endPoint: {
92
+ index: number;
93
+ value: number;
94
+ }) => {
95
+ thickness?: number;
96
+ color?: string;
97
+ className?: string;
98
+ style?: any;
99
+ } | false | undefined;
100
+ handle?: (p: {
101
+ index: number;
102
+ value: number;
103
+ disabled: boolean;
104
+ angle: number;
105
+ }) => {
106
+ widthPercent?: number;
107
+ heightPercent?: number;
108
+ color?: string;
109
+ offset?: number;
110
+ sharp?: boolean;
111
+ } | undefined;
112
+ };
113
+ };
114
+ type I_Range_default = I_Range & {
115
+ start: number;
116
+ end: number;
117
+ step: number;
118
+ min: number;
119
+ max: number;
120
+ size: number;
121
+ labels: AI_label[];
122
+ rotate: number;
123
+ ranges: I_range[];
124
+ };
125
+ declare const AIORange: FC<I_Range>;
126
+ export default AIORange;
127
+ export type I_RangeLabelItem = {
128
+ label: AI_label;
129
+ itemValue: number;
130
+ };
131
+ declare const useRange: (PROPS: I_Range) => {
132
+ values: number[];
133
+ getValues: (value: any) => number[];
134
+ getSide: () => "left" | "right" | "bottom" | "top";
135
+ fixAngle: (angle: number) => number;
136
+ getValueByAngle: (angle: number) => number;
137
+ mainDom: any;
138
+ isValueDisabled: (value: number) => boolean;
139
+ rootProps: I_Range_default;
140
+ getArc: (rc: I_range) => {
141
+ thickness: number;
142
+ color: string;
143
+ roundCap: boolean;
144
+ full: boolean;
145
+ radius: number;
146
+ className?: string;
147
+ from: number;
148
+ to: number;
149
+ };
150
+ getAngleByValue: (value: number, ang?: number) => number;
151
+ getRectByStr: AI_rbs;
152
+ sbp: AI_sbp;
153
+ getXPByValue: (value: number) => number;
154
+ getValueByXP: (xp: number) => number;
155
+ getXPByX: (x: number) => number;
156
+ getGroove: () => import("react/jsx-runtime").JSX.Element;
157
+ };
package/index.js CHANGED
@@ -0,0 +1,618 @@
1
+ import { createElement as _createElement } from "react";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { createContext, createRef, useContext, useEffect, useRef, useState } from "react";
4
+ import * as UT from 'aio-utils';
5
+ import { $ } from 'aio-deps';
6
+ import './index.css';
7
+ const RangeContext = createContext({});
8
+ const RangeProvider = ({ value, children }) => _jsx(RangeContext.Provider, { value: value, children: children });
9
+ const useRangeProvider = () => useContext(RangeContext);
10
+ const AIORange = (props) => {
11
+ const rangeHook = useRange(props);
12
+ function getRootClassName() {
13
+ let c = 'ai-range';
14
+ if (props.round) {
15
+ c += ` ai-range-round`;
16
+ }
17
+ else {
18
+ c += props.vertical ? ` ai-range-vertical` : ` ai-range-horizontal`;
19
+ }
20
+ if (props.className) {
21
+ c += ' ' + props.className;
22
+ }
23
+ if (props.reverse) {
24
+ c += ` ai-range-reverse`;
25
+ }
26
+ return c;
27
+ }
28
+ function getRootStyle() {
29
+ let { style } = props;
30
+ let res;
31
+ if (props.round) {
32
+ res = { width: props.size, height: props.size };
33
+ }
34
+ return Object.assign(Object.assign({}, res), style);
35
+ }
36
+ function getRootProps() {
37
+ let { attrs = {} } = props;
38
+ let rootStyle = getRootStyle();
39
+ return UT.AddToAttrs(attrs, { className: getRootClassName(), style: rootStyle, attrs: { ref: rangeHook.mainDom } });
40
+ }
41
+ function root_node() {
42
+ const { labels } = rangeHook.rootProps;
43
+ return (_jsxs("div", Object.assign({}, getRootProps(), { children: [rangeHook.getGroove(), props.text !== undefined && _jsx("div", { className: 'ai-range-text', children: props.text }, 'rangetext'), !props.round &&
44
+ _jsxs(_Fragment, { children: [_jsx(AIRangeRects, {}, 'rangeRects'), _jsx(RangeFills, {}, 'rangeFills')] }), _jsx(RangeSvg, {}), labels.map((label, i) => _jsx(RangeLabel, { label: label }, i)), _jsx(RangeValues, {})] })));
45
+ }
46
+ return (_jsx(RangeProvider, { value: { rangeHook }, children: root_node() }));
47
+ };
48
+ export default AIORange;
49
+ const RangeValues = () => {
50
+ const { rangeHook } = useRangeProvider();
51
+ return (_jsx(_Fragment, { children: rangeHook.values.map((itemValue, i) => {
52
+ return _jsx(RangeValue, { index: i, itemValue: itemValue }, 'rangecontainervalue' + i);
53
+ }) }));
54
+ };
55
+ const RangeValue = (props) => {
56
+ let { rangeHook } = useRangeProvider();
57
+ let { itemValue, index } = props;
58
+ let { round } = rangeHook.rootProps;
59
+ let angle = rangeHook.fixAngle(rangeHook.getAngleByValue(itemValue));
60
+ function containerProps() {
61
+ let style;
62
+ if (!round) {
63
+ style = { [rangeHook.getSide()]: rangeHook.getXPByValue(itemValue) + '%' };
64
+ }
65
+ else {
66
+ style = { transform: `rotate(${angle}deg)` };
67
+ }
68
+ return { className: 'ai-range-value-container', draggable: false, style };
69
+ }
70
+ const disabled = rangeHook.isValueDisabled(itemValue);
71
+ return (_jsxs("div", Object.assign({}, containerProps(), { children: [_jsx(RangeHandle, { disabled: disabled, value: itemValue, index: index, angle: angle }), _jsx(AIRangePoint, { disabled: disabled, value: itemValue, index: index, angle: angle })] })));
72
+ };
73
+ const RangeSvg = () => {
74
+ const { rangeHook } = useRangeProvider();
75
+ const { round, ranges, size } = rangeHook.rootProps;
76
+ if (!round || !ranges.length) {
77
+ return null;
78
+ }
79
+ return (_jsx("svg", { style: { position: 'absolute', left: 0, top: 0 }, width: size, height: size, children: ranges.map((range, i) => _jsx(RangeArc, { range: range }, 'rangecirclearc' + i)) }));
80
+ };
81
+ const AIRangeRects = () => {
82
+ const { rangeHook } = useRangeProvider();
83
+ const { ranges = [] } = rangeHook.rootProps;
84
+ return (_jsx(_Fragment, { children: ranges.map((range, i) => _jsx(RangeRect, { range: range }, 'range' + i)) }));
85
+ };
86
+ const RangeFills = () => {
87
+ let { rangeHook } = useRangeProvider();
88
+ let { start, round, rangeOption = {} } = rangeHook.rootProps;
89
+ if (round) {
90
+ return null;
91
+ }
92
+ const { fill } = rangeOption;
93
+ const values = rangeHook.values;
94
+ let limit = values.length === 1 ? [start, values[0]] : [...values];
95
+ const fillHtmls = [];
96
+ for (let i = 1; i < limit.length; i++) {
97
+ const startPoint = { index: i - 1, value: limit[i - 1] };
98
+ const endPoint = { index: i, value: limit[i] };
99
+ let res = !fill ? { thickness: 4 } : fill(startPoint, endPoint);
100
+ if (res === false) {
101
+ continue;
102
+ }
103
+ res = res || { thickness: 4 };
104
+ const { thickness = 4, style, className: fillClassName, color } = res;
105
+ let from = limit[startPoint.index];
106
+ let to = limit[endPoint.index];
107
+ let className = 'ai-range-fill';
108
+ if (fillClassName) {
109
+ className += ' ' + fillClassName;
110
+ }
111
+ fillHtmls.push(_jsx(RangeRect, { range: { thickness, color, from, to, className, style, offset: 0 } }, 'fill' + i));
112
+ }
113
+ return _jsx(_Fragment, { children: fillHtmls });
114
+ };
115
+ const RangeRect = ({ range }) => {
116
+ let { rangeHook } = useRangeProvider();
117
+ let { color, from, to, className, style, offset, thickness, roundCap } = range;
118
+ className = UT.classListToString(['ai-range-range', range.className]);
119
+ const { vertical, reverse } = rangeHook.rootProps;
120
+ let startSide = rangeHook.getXPByValue(from), endSide = rangeHook.getXPByValue(to);
121
+ let Style = Object.assign({ [vertical ? 'height' : 'width']: (endSide - startSide) + '%', [vertical ? 'width' : 'height']: range.thickness, [vertical ? (reverse ? 'bottom' : 'top') : (reverse ? 'right' : 'left')]: startSide + '%', [vertical ? 'left' : 'top']: `calc(50% - ${(thickness / 2) + offset}px)`, borderRadius: roundCap ? 48 : 0, background: color }, style);
122
+ return _jsx("div", { className: className, style: Style });
123
+ };
124
+ const RangeArc = ({ range }) => {
125
+ let { rangeHook } = useRangeProvider();
126
+ let { size, reverse } = rangeHook.rootProps;
127
+ const { thickness, color, radius, roundCap, full, from, to } = rangeHook.getArc(range);
128
+ let a, b;
129
+ let x = size / 2, y = size / 2;
130
+ if (full) {
131
+ a = 0;
132
+ b = 360;
133
+ }
134
+ else {
135
+ let startAngle = rangeHook.fixAngle(rangeHook.getAngleByValue(from) + 90);
136
+ let endAngle = rangeHook.fixAngle(rangeHook.getAngleByValue(to) + 90);
137
+ if (endAngle === 0) {
138
+ endAngle = 360;
139
+ }
140
+ a = startAngle;
141
+ b = endAngle;
142
+ if (reverse) {
143
+ b = startAngle;
144
+ a = endAngle;
145
+ }
146
+ }
147
+ return _jsx("path", { d: UT.svgArc(x, y, radius, a, b), stroke: color, strokeWidth: thickness, fill: 'transparent', strokeLinecap: roundCap ? 'round' : undefined, className: range.className }, `from${from}to${to}`);
148
+ };
149
+ const RangeHandle = (props) => {
150
+ let { rangeHook } = useRangeProvider();
151
+ let { index } = props;
152
+ let { rangeOption = {}, round } = rangeHook.rootProps;
153
+ if (!round || !rangeOption.handle) {
154
+ return null;
155
+ }
156
+ const { handle: handleFn } = rangeOption;
157
+ const handle = handleFn(props);
158
+ if (!handle) {
159
+ return null;
160
+ }
161
+ let { sharp = false, widthPercent = 10, heightPercent = 90, color = '#000', offset = 0 } = handle;
162
+ let width = rangeHook.sbp(heightPercent, true);
163
+ let height = rangeHook.sbp(widthPercent, true) * 2;
164
+ function getStyle() {
165
+ if (sharp) {
166
+ return {
167
+ [width < 0 ? 'borderRight' : 'borderLeft']: `${Math.abs(width)}px solid ${color}`,
168
+ borderTop: `${height / 2}px solid transparent`,
169
+ borderBottom: `${height / 2}px solid transparent`,
170
+ left: rangeHook.sbp(offset)
171
+ };
172
+ }
173
+ else {
174
+ return { width, height, left: offset, background: color };
175
+ }
176
+ }
177
+ let PROPS = UT.AddToAttrs({}, { className: 'aio-input-handle', style: getStyle(), attrs: { draggable: false } });
178
+ return (_createElement("div", Object.assign({}, PROPS, { key: 'rangehandle' + index })));
179
+ };
180
+ const RangeLabel = (props) => {
181
+ let { rangeHook } = useRangeProvider();
182
+ let { label } = props;
183
+ let { zIndex, dynamic, step, list = [] } = label;
184
+ let { round, start, end, reverse, vertical } = rangeHook.rootProps;
185
+ let [def] = useState(getDef);
186
+ function getDef() { return RENDER(true); }
187
+ function getList() {
188
+ let res = [];
189
+ if (step) {
190
+ let { start: lstart = start, end: lend = end } = label;
191
+ for (let i = lstart; i <= lend; i += step) {
192
+ res.push(i);
193
+ }
194
+ }
195
+ for (let i = 0; i < list.length; i++) {
196
+ if (res.indexOf(list[i]) === -1) {
197
+ res.push(list[i]);
198
+ }
199
+ }
200
+ return res;
201
+ }
202
+ function updateLabels() {
203
+ if (round || !label.autoHide || vertical) {
204
+ return;
205
+ }
206
+ let container = $(rangeHook.mainDom.current);
207
+ let labels = container.find(`.ai-range-label`);
208
+ if (!labels.length) {
209
+ return;
210
+ }
211
+ let firstLabel = labels.eq(0);
212
+ let firstLabelHProp = firstLabel.attr('data-rotated') === 'yes' ? 'height' : 'width';
213
+ let end = firstLabel.offset().left + (!reverse ? firstLabel[firstLabelHProp]() : 0);
214
+ for (let i = 1; i < labels.length; i++) {
215
+ let label = labels.eq(i);
216
+ let hProp = label.attr('data-rotated') === 'yes' ? 'height' : 'width';
217
+ label.css({ display: 'flex' });
218
+ let left = label.offset().left;
219
+ let width = label[hProp]();
220
+ let right = left + width;
221
+ if (!reverse) {
222
+ if (left < end + 5) {
223
+ label.css({ display: 'none' });
224
+ }
225
+ else {
226
+ end = left + width;
227
+ }
228
+ }
229
+ else {
230
+ if (right > end - 5) {
231
+ label.css({ display: 'none' });
232
+ }
233
+ else {
234
+ end = left;
235
+ }
236
+ }
237
+ }
238
+ }
239
+ useEffect(() => { $(window).on('resize', updateLabels); }, []);
240
+ useEffect(() => { updateLabels(); });
241
+ function RENDER(init) {
242
+ if (!init && !dynamic) {
243
+ return def;
244
+ }
245
+ return (_jsx("div", { className: 'ai-range-labels', style: { zIndex }, children: getList().map((itemValue) => _jsx(RangeLabelItem, { label: label, itemValue: itemValue }, itemValue)) }));
246
+ }
247
+ return _jsx(_Fragment, { children: RENDER(false) });
248
+ };
249
+ const RangeLabelItem = (props) => {
250
+ let { rangeHook } = useRangeProvider();
251
+ let { label, itemValue } = props;
252
+ let { round, vertical, size } = rangeHook.rootProps;
253
+ let angle;
254
+ if (round) {
255
+ angle = rangeHook.fixAngle(rangeHook.getAngleByValue(itemValue));
256
+ }
257
+ let disabled = rangeHook.isValueDisabled(itemValue);
258
+ function getContainerStyle(distance) {
259
+ if (round) {
260
+ return { transform: `rotate(${angle}deg)` };
261
+ }
262
+ else {
263
+ return Object.assign({ [rangeHook.getSide()]: rangeHook.getXPByValue(itemValue) + '%' }, distance);
264
+ }
265
+ }
266
+ function getTextStyle(item, distance) {
267
+ let res = {};
268
+ if (round) {
269
+ res = Object.assign(Object.assign({}, res), distance);
270
+ if (item.fixAngle) {
271
+ res = Object.assign(Object.assign({}, res), { transform: `rotate(${-angle}deg)` });
272
+ }
273
+ }
274
+ return Object.assign({ width: 0, height: 0 }, res);
275
+ }
276
+ function getDetails() {
277
+ let item = label.setting(itemValue, { disabled, angle });
278
+ let { offset = 0, html = '', config } = item;
279
+ let distance = { [round || vertical ? 'left' : 'top']: size * offset / 100 / 2 };
280
+ if (round) {
281
+ distance.left = size * offset / 100 / 2;
282
+ }
283
+ else if (vertical) {
284
+ distance.left = `calc(50% + ${offset || 0}px)`;
285
+ }
286
+ else {
287
+ distance.top = `calc(50% + ${offset || 0}px)`;
288
+ }
289
+ let containerStyle = getContainerStyle(distance);
290
+ let containerProps = { className: 'ai-range-label-container', style: containerStyle, draggable: false };
291
+ let textProps = UT.AddToAttrs({}, { className: ['ai-range-label'], style: getTextStyle(item, distance), attrs: { draggable: false } });
292
+ if (config) {
293
+ html = (_jsx("div", { className: "msf", style: {
294
+ [!!round && !vertical ? 'height' : 'width']: size * config.thickness / 100,
295
+ [!!round && !vertical ? 'width' : 'height']: size * config.height / 100,
296
+ //transform:`translate${!!round && !vertical?'Y':'X'}${-size * config.thickness / 200}`,
297
+ background: config.color
298
+ } }));
299
+ }
300
+ return { html, textProps, containerProps };
301
+ }
302
+ let { html, textProps, containerProps } = getDetails();
303
+ return (_jsx("div", Object.assign({}, containerProps, { children: _jsx("div", Object.assign({}, textProps, { children: html })) })));
304
+ };
305
+ const AIRangePoint = (props) => {
306
+ let { rangeHook } = useRangeProvider();
307
+ const { size, vertical, rangeOption = {}, round } = rangeHook.rootProps;
308
+ function getContainerStyle(offset) {
309
+ let containerStyle;
310
+ if (round) {
311
+ containerStyle = { left: size / 2 + offset, transform: `rotate(${-props.angle}deg)` };
312
+ }
313
+ else {
314
+ containerStyle = { [vertical ? 'left' : 'top']: offset };
315
+ }
316
+ return containerStyle;
317
+ }
318
+ function handleZIndex(index) {
319
+ let containers = $(rangeHook.mainDom.current).find(`.ai-range-value-container`);
320
+ containers.css({ zIndex: 10 });
321
+ containers.eq(index).css({ zIndex: 100 });
322
+ }
323
+ const { pointHtml = (() => _jsx("div", { className: 'ai-range-point', children: props.value })), pointOffset = (() => 0) } = rangeOption;
324
+ const point = pointHtml(props);
325
+ if (point === false) {
326
+ return null;
327
+ }
328
+ const offset = pointOffset(props) || 0;
329
+ return (_jsx("div", { style: getContainerStyle(offset), className: 'ai-range-point-container', draggable: false, "data-index": props.index, onMouseDown: () => handleZIndex(props.index), children: point }, 'rangepoint' + props.index));
330
+ };
331
+ const useRange = (PROPS) => {
332
+ const getProps = () => {
333
+ const { start = 0, end = 100, min = start, max = end, step = 1, size = 72, labels = [], rotate = 0, ranges = [] } = PROPS;
334
+ return Object.assign(Object.assign({}, PROPS), { start, end, min, max, step, size, labels, rotate, ranges });
335
+ };
336
+ const props = getProps();
337
+ const propsRef = useRef(props);
338
+ propsRef.current = props;
339
+ let [temp] = useState({ start: 0, index: false });
340
+ const [mainDom] = useState(createRef());
341
+ const [values, setValues] = useState([]);
342
+ const { vertical, reverse, start = 0, end = 100, min = start, max = end, step = 1, rotate = 0, round, size = 72, ranges = [], grooveAttrs } = props;
343
+ useEffect(() => {
344
+ if (!props.onChange || props.disabled === true) {
345
+ return;
346
+ }
347
+ clearTimeout(temp.timeOut);
348
+ temp.timeOut = setTimeout(() => {
349
+ new UT.Swip({
350
+ reverseX: !!props.reverse,
351
+ //vertical condition
352
+ reverseY: !!props.reverse && !!props.vertical,
353
+ dom: () => $(mainDom.current),
354
+ start: (p) => {
355
+ const { disabled } = propsRef.current;
356
+ if (disabled === true) {
357
+ return false;
358
+ }
359
+ let { event } = p;
360
+ if (event.target !== null) {
361
+ let index = UT.GetAttr($(event.target), 'data-index');
362
+ temp.index = index === null ? false : +index;
363
+ temp.start = [...values];
364
+ }
365
+ return [0, 0];
366
+ },
367
+ move: (p) => {
368
+ let { change, mousePosition } = p;
369
+ if (change) {
370
+ changeHandle({ dx: change.dx, dy: change.dy, deltaCenterAngle: change.deltaCenterAngle, centerAngle: mousePosition.centerAngle });
371
+ }
372
+ },
373
+ onClick: function (p) {
374
+ const { disabled } = propsRef.current;
375
+ if (disabled) {
376
+ return;
377
+ }
378
+ click(p.mousePosition);
379
+ }
380
+ });
381
+ }, 100);
382
+ }, [changeHandle]);
383
+ function click(mousePosition) {
384
+ if (props.disabled === true || temp.index !== false) {
385
+ return;
386
+ }
387
+ let clickedValue;
388
+ //vertical condition
389
+ if (props.round) {
390
+ clickedValue = getValueByAngle(mousePosition.centerAngle);
391
+ }
392
+ else {
393
+ clickedValue = getValueByXP(mousePosition[props.vertical ? 'yp' : 'xp']);
394
+ }
395
+ if (clickedValue < values[values.length - 1] && clickedValue > values[0]) {
396
+ return;
397
+ }
398
+ if (clickedValue < values[0]) {
399
+ change1Unit(-1);
400
+ }
401
+ else {
402
+ change1Unit(1);
403
+ }
404
+ }
405
+ function changeHandle(obj) {
406
+ if (props.disabled === true) {
407
+ return;
408
+ }
409
+ let newValue = getChangedValue(obj);
410
+ changeValue(newValue);
411
+ }
412
+ function isValueDisabled(value) {
413
+ const { rangeOption = {} } = props;
414
+ const { disabled: d = () => false } = rangeOption;
415
+ return d(value);
416
+ }
417
+ function getChangedValue(obj) {
418
+ let { dx, dy, deltaCenterAngle, centerAngle } = obj;
419
+ let startValue = [...temp.start];
420
+ let index = temp.index;
421
+ //agar faghat yek point darim har koja mousedown shod farz kon rooye oon point mousedown karde im
422
+ if (startValue.length === 1 && index === false) {
423
+ index = 0;
424
+ }
425
+ let res;
426
+ if (index === false) {
427
+ let deltaValue;
428
+ if (props.round) {
429
+ let v = deltaCenterAngle * (props.end - props.start) / 360;
430
+ v = Math.round(v / props.step) * props.step;
431
+ deltaValue = v;
432
+ }
433
+ else {
434
+ deltaValue = Math.round(getValueByXP(getXPByX(props.vertical ? dy : dx)) / props.step) * props.step;
435
+ }
436
+ let newValue = moveAll(startValue, deltaValue, true);
437
+ res = !isValueValid(newValue) ? values : newValue;
438
+ }
439
+ else {
440
+ let { before, after } = getIndexLimit(index);
441
+ let newUnitValue;
442
+ if (props.round) {
443
+ newUnitValue = Math.round(getValueByAngle(centerAngle) / props.step) * props.step;
444
+ }
445
+ else {
446
+ let deltaValue = Math.round(getValueByXP(getXPByX(props.vertical ? dy : dx)) / props.step) * props.step;
447
+ newUnitValue = startValue[index] + deltaValue;
448
+ }
449
+ if (newUnitValue > after) {
450
+ newUnitValue = after;
451
+ }
452
+ if (newUnitValue < before) {
453
+ newUnitValue = before;
454
+ }
455
+ if (isValueDisabled(newUnitValue)) {
456
+ newUnitValue = values[index];
457
+ }
458
+ startValue[index] = newUnitValue;
459
+ res = startValue;
460
+ }
461
+ return res;
462
+ }
463
+ function change1Unit(dir) {
464
+ let newValue = [...values];
465
+ let lastValue = JSON.stringify(newValue);
466
+ newValue = moveAll(newValue, dir * props.step);
467
+ while (!isValueValid(newValue) && JSON.stringify(newValue) !== lastValue) {
468
+ lastValue = JSON.stringify(newValue);
469
+ newValue = moveAll(newValue, dir * props.step);
470
+ }
471
+ changeValue(newValue);
472
+ }
473
+ function changeValue(newValue) {
474
+ if (!props.onChange || props.disabled === true) {
475
+ return;
476
+ }
477
+ newValue = getValues(newValue);
478
+ props.onChange(!!props.multiple ? newValue : newValue[0]);
479
+ }
480
+ function isValueValid(value) {
481
+ for (let i = 0; i < value.length; i++) {
482
+ if (isValueDisabled(value[i])) {
483
+ return false;
484
+ }
485
+ }
486
+ return true;
487
+ }
488
+ function getIndexLimit(index) {
489
+ let before, after;
490
+ if (index === 0) {
491
+ before = props.start;
492
+ }
493
+ else {
494
+ before = values[index - 1];
495
+ }
496
+ if (index === values.length - 1) {
497
+ after = props.end;
498
+ }
499
+ else {
500
+ after = values[index + 1];
501
+ }
502
+ return { before, after };
503
+ }
504
+ function moveAll(newValue, offset, ifFailedReturnOriginalValue) {
505
+ let res = newValue.map((o) => o + offset);
506
+ if (res[0] < props.start || res[res.length - 1] > props.end) {
507
+ return ifFailedReturnOriginalValue ? values : newValue;
508
+ }
509
+ return res;
510
+ }
511
+ function getValues(value) {
512
+ if (!Array.isArray(value)) {
513
+ value = [value || 0];
514
+ }
515
+ for (let i = 0; i < value.length; i++) {
516
+ let point = value[i] || 0;
517
+ point = Math.round((point - start) / step) * step + start;
518
+ point = +point.toFixed(UT.GetPrecisionCount(step));
519
+ if (point < min) {
520
+ point = min;
521
+ }
522
+ if (point > max) {
523
+ point = max;
524
+ }
525
+ value[i] = point;
526
+ }
527
+ return value;
528
+ }
529
+ useEffect(() => {
530
+ setValues(getValues(props.value));
531
+ }, [props.value]);
532
+ function getSide() {
533
+ return vertical ? (reverse ? 'bottom' : 'top') : (reverse ? 'right' : 'left');
534
+ }
535
+ function fixValueInEmpty(value) {
536
+ let fill = round || 1;
537
+ let empty = 1 - fill;
538
+ let emptyValue = empty * (end - start) / fill;
539
+ if (value > end + emptyValue / 2) {
540
+ value = start - emptyValue + value - end;
541
+ }
542
+ return value;
543
+ }
544
+ function fixAngle(angle) { angle = angle % 360; return angle < 0 ? angle = 360 + angle : angle; }
545
+ function getValueByAngle(angle) {
546
+ let fillAngle = 360 * (round || 1);
547
+ let emptyAngle = 360 - fillAngle;
548
+ if (reverse) {
549
+ angle = 180 - angle;
550
+ }
551
+ angle -= rotate;
552
+ angle -= emptyAngle / 2;
553
+ angle -= 90;
554
+ angle = fixAngle(angle);
555
+ let res = angle * (end - start) / fillAngle;
556
+ res = fixValueInEmpty(res);
557
+ return res;
558
+ }
559
+ function getAngleByValue(value, ang) {
560
+ let fillAngle = 360 * round;
561
+ let emptyAngle = 360 - fillAngle;
562
+ let res = value * fillAngle / (end - start);
563
+ res += 90;
564
+ res += emptyAngle / 2;
565
+ res += rotate;
566
+ res += (ang || 0);
567
+ return reverse ? res = 180 - res : res;
568
+ }
569
+ const sbp = (value, half) => size / (half ? 2 : 1) * value / 100;
570
+ const getRectByStr = (obj) => {
571
+ let { thickness = 1, offset = 0, color = '#000', roundCap = false, className, from = start, to = end } = obj;
572
+ try {
573
+ let thicknessValue = thickness;
574
+ if (isNaN(thicknessValue)) {
575
+ thicknessValue = 1;
576
+ }
577
+ thickness = thicknessValue;
578
+ let offsetValue = offset;
579
+ if (isNaN(offsetValue)) {
580
+ offsetValue = 0;
581
+ }
582
+ let defaultOffset = (size / 2) - (thickness / 2);
583
+ offset = defaultOffset - offsetValue;
584
+ if (offset > size - thickness / 2) {
585
+ offset = size - thickness / 2;
586
+ }
587
+ if (offset < thickness / 2) {
588
+ offset = thickness / 2;
589
+ }
590
+ }
591
+ catch (_a) { }
592
+ return { thickness, offset, color, roundCap, className, from, to };
593
+ };
594
+ function getXPByValue(value) {
595
+ return 100 * (value - start) / (end - start);
596
+ }
597
+ function getValueByXP(xp) {
598
+ return xp * (end - start) / 100;
599
+ }
600
+ function getXPByX(x) {
601
+ return x * 100 / $(mainDom.current)[vertical ? 'height' : 'width']();
602
+ }
603
+ const getArc = (rc) => {
604
+ let roundCap = rc.roundCap || false, full = rc.full || false, offset = rc.offset, color = rc.color || '#000', className = rc.className;
605
+ const { from = start, to = end } = rc;
606
+ const thickness = size * rc.thickness / 100;
607
+ const radius = (rc.offset * size / 2 / 100) - thickness / 2;
608
+ offset = sbp(offset);
609
+ return { thickness, radius, color, roundCap, full, className, from, to };
610
+ };
611
+ function getGroove() {
612
+ return _jsx("div", Object.assign({}, UT.AddToAttrs(grooveAttrs, { className: 'ai-range-groove' })));
613
+ }
614
+ return {
615
+ values, getValues, getSide, fixAngle, getValueByAngle, mainDom, isValueDisabled, rootProps: props,
616
+ getArc, getAngleByValue, getRectByStr, sbp, getXPByValue, getValueByXP, getXPByX, getGroove
617
+ };
618
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aio-range",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "linear and circular range input",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -12,12 +12,8 @@
12
12
  "url": "git+https://github.com/mohammadFeiz/aio-range.git"
13
13
  },
14
14
  "dependencies": {
15
- "aio-table": "latest",
16
- "aio-cordova": "latest",
17
- "aio-entity": "latest",
18
- "aio-input": "latest",
19
- "aio-utils": "latest",
20
- "aio-date": "latest"
15
+ "aio-deps": "latest",
16
+ "aio-utils": "latest"
21
17
  },
22
18
  "keywords": [
23
19
  "range",
package/README.md DELETED
@@ -1 +0,0 @@
1
- # aio-range