no-frills-ui 0.0.14-alpha.0 → 0.0.14-alpha.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/README.md +56 -23
- package/dist/index.js +229 -1666
- package/dist/index.js.map +1 -1
- package/lib-esm/components/Chip/Chip.d.ts +2 -0
- package/lib-esm/components/Chip/Chip.js +3 -2
- package/lib-esm/components/Chip/Chip.js.map +1 -1
- package/lib-esm/components/ChipInput/ChipInput.d.ts +33 -0
- package/lib-esm/components/ChipInput/ChipInput.js +216 -0
- package/lib-esm/components/ChipInput/ChipInput.js.map +1 -0
- package/lib-esm/components/ChipInput/index.d.ts +1 -0
- package/lib-esm/components/ChipInput/index.js +2 -0
- package/lib-esm/components/ChipInput/index.js.map +1 -0
- package/lib-esm/components/DragAndDrop/DragAndDrop.d.ts +27 -0
- package/lib-esm/components/DragAndDrop/DragAndDrop.js +37 -1
- package/lib-esm/components/DragAndDrop/DragAndDrop.js.map +1 -1
- package/lib-esm/components/DragAndDrop/DragItem.d.ts +37 -0
- package/lib-esm/components/DragAndDrop/DragItem.js +141 -3
- package/lib-esm/components/DragAndDrop/DragItem.js.map +1 -1
- package/lib-esm/components/DragAndDrop/types.d.ts +3 -0
- package/lib-esm/components/DragAndDrop/types.js.map +1 -1
- package/lib-esm/components/Input/Input.js +1 -1
- package/package.json +5 -3
|
@@ -15,6 +15,7 @@ import constants from '../../shared/constants';
|
|
|
15
15
|
import { Close } from '../../icons';
|
|
16
16
|
const Container = styled.div `
|
|
17
17
|
padding: 5px;
|
|
18
|
+
padding-left: 15px;
|
|
18
19
|
border-radius: 16px;
|
|
19
20
|
background-color: var(--border-light-color, ${constants.BORDER_LIGHT_COLOR});
|
|
20
21
|
display: inline-flex;
|
|
@@ -23,7 +24,7 @@ const Container = styled.div `
|
|
|
23
24
|
align-items: center;
|
|
24
25
|
|
|
25
26
|
&:focus-within {
|
|
26
|
-
|
|
27
|
+
outline: 2px solid var(--primary-light, ${constants.PRIMARY_LIGHT});
|
|
27
28
|
}
|
|
28
29
|
`;
|
|
29
30
|
const Button = styled.button `
|
|
@@ -42,6 +43,6 @@ export default function Chip(props) {
|
|
|
42
43
|
onCloseClick === null || onCloseClick === void 0 ? void 0 : onCloseClick();
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
|
-
return (_jsxs(Container, Object.assign({}, rest, { onKeyUp: keyUpHandler, children: [label, _jsx(Button, { onClick: onCloseClick, children: _jsx(Close, { height: 20, width: 20 }) })] })));
|
|
46
|
+
return (_jsxs(Container, Object.assign({}, rest, { onKeyUp: keyUpHandler, children: [label, _jsx(Button, { onClick: onCloseClick, "aria-label": `Remove ${label}`, children: _jsx(Close, { height: 20, width: 20 }) })] })));
|
|
46
47
|
}
|
|
47
48
|
//# sourceMappingURL=Chip.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chip.js","sourceRoot":"","sources":["../../../src/components/Chip/Chip.tsx"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"Chip.js","sourceRoot":"","sources":["../../../src/components/Chip/Chip.tsx"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AASpC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAA;;;;kDAIsB,SAAS,CAAC,kBAAkB;;;;;;;kDAO5B,SAAS,CAAC,aAAa;;CAExE,CAAC;AAEF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;;+CAEmB,SAAS,CAAC,eAAe;;;;;;CAMvE,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,KAAgB;IACzC,MAAM,EAAE,KAAK,EAAE,YAAY,KAAc,KAAK,EAAd,IAAI,UAAK,KAAK,EAAxC,yBAAgC,CAAQ,CAAC;IAE/C,MAAM,YAAY,GAA8C,CAAC,CAAC,EAAE,EAAE;QAClE,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,EAAE,EAAE,CAAC;YACtC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,EAAI,CAAC;QACrB,CAAC;IACL,CAAC,CAAA;IAED,OAAO,CACH,MAAC,SAAS,oBAAK,IAAI,IAAE,OAAO,EAAE,YAAY,aACrC,KAAK,EACN,KAAC,MAAM,IAAC,OAAO,EAAE,YAAY,gBAAc,UAAU,KAAK,EAAE,YACxD,KAAC,KAAK,IAAC,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,GAAI,GAC3B,KACD,CACf,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
type ChipInputProps = PropTypes.InferProps<typeof ChipInput.propTypes>;
|
|
4
|
+
/**
|
|
5
|
+
* A chip input component that allows users to add and remove chips (tags) by typing and pressing Enter.
|
|
6
|
+
* @component
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <ChipInput
|
|
10
|
+
* value={['tag1', 'tag2']}
|
|
11
|
+
* onChange={(newTags) => console.log(newTags)}
|
|
12
|
+
* label="Add tags"
|
|
13
|
+
* errorText="At least one tag is required"
|
|
14
|
+
* />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
declare function ChipInput(props: ChipInputProps & React.AllHTMLAttributes<HTMLInputElement>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
18
|
+
declare namespace ChipInput {
|
|
19
|
+
var propTypes: {
|
|
20
|
+
/** Label for the field */
|
|
21
|
+
label: PropTypes.Validator<string>;
|
|
22
|
+
/** Error message for the field */
|
|
23
|
+
errorText: PropTypes.Requireable<string>;
|
|
24
|
+
/** Values to display as chips */
|
|
25
|
+
value: PropTypes.Requireable<string[]>;
|
|
26
|
+
/** Callback when chips change */
|
|
27
|
+
onChange: PropTypes.Requireable<(...args: any[]) => any>;
|
|
28
|
+
};
|
|
29
|
+
var defaultProps: {
|
|
30
|
+
value: any[];
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export default ChipInput;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import styled from '@emotion/styled';
|
|
5
|
+
import constants from '../../shared/constants';
|
|
6
|
+
import Chip from '../Chip/Chip';
|
|
7
|
+
import { DragAndDrop, ORIENTATION } from '../DragAndDrop';
|
|
8
|
+
// Label component for the ChipInput
|
|
9
|
+
const Label = styled.label `
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
flex: 1;
|
|
13
|
+
position: relative;
|
|
14
|
+
margin: 10px 5px;
|
|
15
|
+
color: inherit;
|
|
16
|
+
padding: 0 8px;
|
|
17
|
+
width: 250px;
|
|
18
|
+
border-radius: 3px;
|
|
19
|
+
border: 1px solid var(--border-color, ${constants.BORDER_COLOR});
|
|
20
|
+
background-color: var(--background, ${constants.BACKGROUND});
|
|
21
|
+
|
|
22
|
+
/** Focused */
|
|
23
|
+
&:has(:focus), &:has(:active) {
|
|
24
|
+
border-color: var(--primary, ${constants.PRIMARY});
|
|
25
|
+
box-shadow: 0 0 0 4px var(--primary-light, ${constants.PRIMARY_LIGHT});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&:has(:focus) > span, &:has(:active) > span {
|
|
29
|
+
color: var(--primary, ${constants.PRIMARY});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Disabled */
|
|
33
|
+
&:has(:disabled) {
|
|
34
|
+
border-color: var(--disabled-border, ${constants.DISABLED_BORDER});
|
|
35
|
+
background-color: var(--disabled-background, ${constants.DISABLED_BACKGROUND});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:has(:disabled) > span {
|
|
39
|
+
color: #777;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Invalid */
|
|
43
|
+
&:has(:focus:invalid) {
|
|
44
|
+
border-color: var(--error, ${constants.ERROR});
|
|
45
|
+
box-shadow: 0 0 0 4px var(--error-light, ${constants.ERROR_LIGHT});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
${props => props.touched ? `
|
|
49
|
+
&:has(:invalid) {
|
|
50
|
+
border-color: var(--error, ${constants.ERROR});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&:has(:invalid) > span {
|
|
54
|
+
color: var(--error, ${constants.ERROR});
|
|
55
|
+
}
|
|
56
|
+
` : ''}
|
|
57
|
+
|
|
58
|
+
/** Error */
|
|
59
|
+
${props => props.errorText ? `
|
|
60
|
+
border-color: var(--error, ${constants.ERROR});
|
|
61
|
+
|
|
62
|
+
& > span {
|
|
63
|
+
color: var(--error, ${constants.ERROR});
|
|
64
|
+
}
|
|
65
|
+
` : ''}
|
|
66
|
+
|
|
67
|
+
/** Required */
|
|
68
|
+
&:has(:required) > span:after {
|
|
69
|
+
content: '*';
|
|
70
|
+
margin-left: 2px;
|
|
71
|
+
color: var(--error, ${constants.ERROR});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
& > input {
|
|
75
|
+
border: none;
|
|
76
|
+
outline: none;
|
|
77
|
+
width: 100%;
|
|
78
|
+
line-height: 30px;
|
|
79
|
+
min-height: 30px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Label Animation */
|
|
83
|
+
& > span {
|
|
84
|
+
position: absolute;
|
|
85
|
+
padding: 0 5px;
|
|
86
|
+
top: 0px;
|
|
87
|
+
left: 4px;
|
|
88
|
+
font-size: 14px;
|
|
89
|
+
line-height: 32px;
|
|
90
|
+
transition: all 300ms ease;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
&:has(:focus) > span, &:has(:placeholder-shown) > span {
|
|
94
|
+
top: -8px;
|
|
95
|
+
background: var(--background, ${constants.BACKGROUND});
|
|
96
|
+
font-size: 12px;
|
|
97
|
+
line-height: 14px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
${props => props.text !== '' ? `
|
|
101
|
+
& > span {
|
|
102
|
+
top: -8px;
|
|
103
|
+
background: var(--background, ${constants.BACKGROUND});
|
|
104
|
+
font-size: 12px;
|
|
105
|
+
line-height: 14px;
|
|
106
|
+
}
|
|
107
|
+
` : ''}
|
|
108
|
+
`;
|
|
109
|
+
// Error message container
|
|
110
|
+
const ErrorContainer = styled.div `
|
|
111
|
+
color: var(--error, ${constants.ERROR});
|
|
112
|
+
padding-top: 3px;
|
|
113
|
+
font-size: 12px;
|
|
114
|
+
line-height: 14px;
|
|
115
|
+
margin-left: 3px;
|
|
116
|
+
`;
|
|
117
|
+
/**
|
|
118
|
+
* A chip input component that allows users to add and remove chips (tags) by typing and pressing Enter.
|
|
119
|
+
* @component
|
|
120
|
+
* @example
|
|
121
|
+
* ```tsx
|
|
122
|
+
* <ChipInput
|
|
123
|
+
* value={['tag1', 'tag2']}
|
|
124
|
+
* onChange={(newTags) => console.log(newTags)}
|
|
125
|
+
* label="Add tags"
|
|
126
|
+
* errorText="At least one tag is required"
|
|
127
|
+
* />
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export default function ChipInput(props) {
|
|
131
|
+
const [text, setText] = useState('');
|
|
132
|
+
const [touched, setTouched] = useState(false);
|
|
133
|
+
const [value, setValue] = useState(props.value);
|
|
134
|
+
const InputRef = React.useRef(null);
|
|
135
|
+
// Sync internal value with props.value
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
setValue(props.value);
|
|
138
|
+
}, [props.value]);
|
|
139
|
+
/**
|
|
140
|
+
* Update the chip values and notify changes.
|
|
141
|
+
* @param newValue The new array of chip values
|
|
142
|
+
*/
|
|
143
|
+
const updateValue = (newValue) => {
|
|
144
|
+
var _a;
|
|
145
|
+
const deduped = Array.from(new Set(newValue));
|
|
146
|
+
setValue(deduped);
|
|
147
|
+
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, deduped);
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Marks the input as touched on focus.
|
|
151
|
+
* @param e React focus event
|
|
152
|
+
*/
|
|
153
|
+
const handleFocus = (e) => {
|
|
154
|
+
setTouched(true);
|
|
155
|
+
if (props.onFocus) {
|
|
156
|
+
props.onFocus(e);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Change handler for the input field.
|
|
161
|
+
* @param e React change event
|
|
162
|
+
*/
|
|
163
|
+
const handleChange = (e) => {
|
|
164
|
+
setText(e.target.value);
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Adds a new chip on Enter key press.
|
|
168
|
+
* @param e React keyboard event
|
|
169
|
+
*/
|
|
170
|
+
const handleKeyUp = (e) => {
|
|
171
|
+
if (e.key === 'Enter' && text.trim() !== '') {
|
|
172
|
+
const newValue = [...value, text.trim()];
|
|
173
|
+
updateValue(newValue);
|
|
174
|
+
setText('');
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Removes a chip from the list.
|
|
179
|
+
* @param chipToRemove The chip value to remove
|
|
180
|
+
*/
|
|
181
|
+
const removeChip = (chipToRemove) => {
|
|
182
|
+
const newValue = value.filter(chip => chip !== chipToRemove);
|
|
183
|
+
updateValue(newValue);
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Moves a chip from one position to another.
|
|
187
|
+
* @param start The starting index of the item to move
|
|
188
|
+
* @param end The ending index where the item should be placed
|
|
189
|
+
*/
|
|
190
|
+
const onDrop = (start, end) => {
|
|
191
|
+
// Clone existing elements
|
|
192
|
+
const newItems = [...value];
|
|
193
|
+
// Remove the element to be moved
|
|
194
|
+
const item = newItems.splice(start, 1);
|
|
195
|
+
// Add it back at the required position
|
|
196
|
+
newItems.splice(end, 0, item[0]);
|
|
197
|
+
// Update
|
|
198
|
+
updateValue(newItems);
|
|
199
|
+
};
|
|
200
|
+
// Render the component
|
|
201
|
+
return (_jsxs(Label, { text: text, touched: touched, errorText: props.errorText, children: [_jsx("input", Object.assign({}, props, { ref: InputRef, type: "text", value: text, onChange: handleChange, onFocus: handleFocus, onKeyUp: handleKeyUp, required: props.required && value.length === 0 })), _jsx("div", { children: (value === null || value === void 0 ? void 0 : value.length) > 0 && (_jsx(DragAndDrop, { orientation: ORIENTATION.HORIZONTAL, onDrop: onDrop, children: value.map((chip) => (_jsx(Chip, { label: chip, onCloseClick: () => removeChip(chip) }, chip))) })) }), _jsx("span", { children: props.label }), props.errorText && _jsx(ErrorContainer, { children: props.errorText })] }));
|
|
202
|
+
}
|
|
203
|
+
ChipInput.propTypes = {
|
|
204
|
+
/** Label for the field */
|
|
205
|
+
label: PropTypes.string.isRequired,
|
|
206
|
+
/** Error message for the field */
|
|
207
|
+
errorText: PropTypes.string,
|
|
208
|
+
/** Values to display as chips */
|
|
209
|
+
value: PropTypes.arrayOf(PropTypes.string),
|
|
210
|
+
/** Callback when chips change */
|
|
211
|
+
onChange: PropTypes.func,
|
|
212
|
+
};
|
|
213
|
+
ChipInput.defaultProps = {
|
|
214
|
+
value: [],
|
|
215
|
+
};
|
|
216
|
+
//# sourceMappingURL=ChipInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChipInput.js","sourceRoot":"","sources":["../../../src/components/ChipInput/ChipInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ChipInput } from './ChipInput';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ChipInput/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -8,10 +8,37 @@ type DragAndDropProps = {
|
|
|
8
8
|
/** Shows drag indicator against each list item */
|
|
9
9
|
showIndicator: boolean;
|
|
10
10
|
} & PropsWithChildren<{}>;
|
|
11
|
+
/**
|
|
12
|
+
* A drag and drop container component that enables reordering of child elements.
|
|
13
|
+
*
|
|
14
|
+
* @component
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <DragAndDrop
|
|
18
|
+
* orientation={ORIENTATION.VERTICAL}
|
|
19
|
+
* onDrop={(start, end) => handleReorder(start, end)}
|
|
20
|
+
* showIndicator={true}
|
|
21
|
+
* >
|
|
22
|
+
* <div>Item 1</div>
|
|
23
|
+
* <div>Item 2</div>
|
|
24
|
+
* <div>Item 3</div>
|
|
25
|
+
* </DragAndDrop>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @param {DragAndDropProps} props - The component props
|
|
29
|
+
* @param {ORIENTATION} props.orientation - Determines the layout direction (horizontal or vertical). Defaults to VERTICAL.
|
|
30
|
+
* @param {(start: number, end: number) => void} props.onDrop - Callback fired when an item is dropped, receives the start and end indices
|
|
31
|
+
* @param {boolean} props.showIndicator - Whether to display drag indicators for each list item. Defaults to false.
|
|
32
|
+
* @param {React.ReactNode} props.children - Child elements to be rendered as draggable items
|
|
33
|
+
*
|
|
34
|
+
* @returns {JSX.Element} A draggable container with reorderable items
|
|
35
|
+
*/
|
|
11
36
|
declare function DragAndDrop(props: DragAndDropProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
12
37
|
declare namespace DragAndDrop {
|
|
13
38
|
var defaultProps: {
|
|
39
|
+
/** Orientation of the list layout */
|
|
14
40
|
orientation: ORIENTATION;
|
|
41
|
+
/** Whether to display drag indicators for each list item */
|
|
15
42
|
showIndicator: boolean;
|
|
16
43
|
};
|
|
17
44
|
}
|
|
@@ -3,23 +3,59 @@ import React, { useState } from 'react';
|
|
|
3
3
|
import styled from '@emotion/styled';
|
|
4
4
|
import DragItem from './DragItem';
|
|
5
5
|
import { ORIENTATION, DragContext } from './types';
|
|
6
|
+
/** Container Component */
|
|
6
7
|
const Container = styled.div `
|
|
7
8
|
flex: 1;
|
|
8
9
|
display: flex;
|
|
9
10
|
position: relative;
|
|
11
|
+
flex-wrap: wrap;
|
|
10
12
|
flex-direction: ${props => props.orientation === ORIENTATION.HORIZONTAL ? 'row' : 'column'};
|
|
11
13
|
`;
|
|
14
|
+
/**
|
|
15
|
+
* A drag and drop container component that enables reordering of child elements.
|
|
16
|
+
*
|
|
17
|
+
* @component
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <DragAndDrop
|
|
21
|
+
* orientation={ORIENTATION.VERTICAL}
|
|
22
|
+
* onDrop={(start, end) => handleReorder(start, end)}
|
|
23
|
+
* showIndicator={true}
|
|
24
|
+
* >
|
|
25
|
+
* <div>Item 1</div>
|
|
26
|
+
* <div>Item 2</div>
|
|
27
|
+
* <div>Item 3</div>
|
|
28
|
+
* </DragAndDrop>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @param {DragAndDropProps} props - The component props
|
|
32
|
+
* @param {ORIENTATION} props.orientation - Determines the layout direction (horizontal or vertical). Defaults to VERTICAL.
|
|
33
|
+
* @param {(start: number, end: number) => void} props.onDrop - Callback fired when an item is dropped, receives the start and end indices
|
|
34
|
+
* @param {boolean} props.showIndicator - Whether to display drag indicators for each list item. Defaults to false.
|
|
35
|
+
* @param {React.ReactNode} props.children - Child elements to be rendered as draggable items
|
|
36
|
+
*
|
|
37
|
+
* @returns {JSX.Element} A draggable container with reorderable items
|
|
38
|
+
*/
|
|
12
39
|
export default function DragAndDrop(props) {
|
|
13
40
|
const { orientation, children, onDrop, showIndicator } = props;
|
|
14
41
|
const [startIndex, setStartIndex] = useState(null);
|
|
42
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
43
|
+
const [dragOver, setDragOver] = useState(null);
|
|
44
|
+
/**
|
|
45
|
+
* Drop handler invoked when a draggable item is released.
|
|
46
|
+
* @param index
|
|
47
|
+
*/
|
|
15
48
|
const drop = (index) => {
|
|
16
49
|
startIndex !== null && (onDrop === null || onDrop === void 0 ? void 0 : onDrop(startIndex, index));
|
|
17
50
|
setStartIndex(null);
|
|
51
|
+
setIsDragging(false);
|
|
18
52
|
};
|
|
19
|
-
return (_jsx(DragContext.Provider, { value: { startIndex, setStartIndex, drop }, children: _jsx(Container, { orientation: orientation, children: React.Children.map(children, (child, index) => (_jsx(DragItem, { index: index, orientation: orientation, showIndicator: showIndicator, children: child }))) }) }));
|
|
53
|
+
return (_jsx(DragContext.Provider, { value: { startIndex, setStartIndex, drop, isDragging, setIsDragging, setDragOver }, children: _jsx(Container, { orientation: orientation, children: React.Children.map(children, (child, index) => (_jsx(DragItem, { index: index, orientation: orientation, showIndicator: showIndicator, dragOver: dragOver, children: child }))) }) }));
|
|
20
54
|
}
|
|
21
55
|
DragAndDrop.defaultProps = {
|
|
56
|
+
/** Orientation of the list layout */
|
|
22
57
|
orientation: ORIENTATION.VERTICAL,
|
|
58
|
+
/** Whether to display drag indicators for each list item */
|
|
23
59
|
showIndicator: false,
|
|
24
60
|
};
|
|
25
61
|
//# sourceMappingURL=DragAndDrop.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DragAndDrop.js","sourceRoot":"","sources":["../../../src/components/DragAndDrop/DragAndDrop.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAqB,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAWnD,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAA4B
|
|
1
|
+
{"version":3,"file":"DragAndDrop.js","sourceRoot":"","sources":["../../../src/components/DragAndDrop/DragAndDrop.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAqB,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAWnD,0BAA0B;AAC1B,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAA4B;;;;;sBAKlC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,KAAK,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;CAC7F,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,KAAuB;IACvD,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC;IAC/D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAS,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC7D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAS,IAAI,CAAC,CAAC;IAEvD;;;OAGG;IACH,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,EAAE;QAC3B,UAAU,KAAK,IAAI,KAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,UAAU,EAAE,KAAK,CAAC,CAAA,CAAC;QACnD,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,aAAa,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,CAAA;IAED,OAAO,CAAC,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,YAC5G,KAAC,SAAS,IAAC,WAAW,EAAE,WAAW,YAC9B,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAC5C,KAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,YAC7F,KAAK,GACC,CACd,CAAC,GACM,GACO,CAAC,CAAC;AAC7B,CAAC;AAED,WAAW,CAAC,YAAY,GAAG;IACvB,qCAAqC;IACrC,WAAW,EAAE,WAAW,CAAC,QAAQ;IACjC,4DAA4D;IAC5D,aAAa,EAAE,KAAK;CACvB,CAAA"}
|
|
@@ -1,9 +1,46 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
2
|
import { ORIENTATION } from './types';
|
|
3
3
|
interface DragItemProps {
|
|
4
|
+
/** Position index of the draggable item */
|
|
4
5
|
index: number;
|
|
6
|
+
/** Orientation of the drag operation (VERTICAL or HORIZONTAL) */
|
|
5
7
|
orientation: ORIENTATION;
|
|
8
|
+
/** Whether to show a drag handle indicator instead of making the entire item draggable */
|
|
6
9
|
showIndicator: boolean;
|
|
10
|
+
/** The index of the item currently being dragged over */
|
|
11
|
+
dragOver: number;
|
|
7
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* A draggable item component that supports both mouse and touch interactions for drag-and-drop functionality.
|
|
15
|
+
*
|
|
16
|
+
* @component
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* <DragItem
|
|
20
|
+
* index={0}
|
|
21
|
+
* orientation={ORIENTATION.VERTICAL}
|
|
22
|
+
* showIndicator={true}
|
|
23
|
+
* dragOver={-1}
|
|
24
|
+
* >
|
|
25
|
+
* <div>Draggable content</div>
|
|
26
|
+
* </DragItem>
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @param props - The component props
|
|
30
|
+
* @param props.index - The position index of this item in the draggable list
|
|
31
|
+
* @param props.orientation - The orientation of the drag operation (VERTICAL or HORIZONTAL)
|
|
32
|
+
* @param props.showIndicator - Whether to show a drag handle indicator instead of making the entire item draggable
|
|
33
|
+
* @param props.dragOver - The index of the item currently being dragged over
|
|
34
|
+
* @param props.children - The content to be rendered inside the draggable item
|
|
35
|
+
*
|
|
36
|
+
* @remarks
|
|
37
|
+
* - Uses the DragContext to manage drag state across items
|
|
38
|
+
* - Provides visual feedback with borders during drag operations
|
|
39
|
+
* - Supports haptic feedback (vibration) on touch devices
|
|
40
|
+
* - For touch devices, requires a 200ms hold before drag starts
|
|
41
|
+
* - When showIndicator is true, only the drag handle can initiate drag operations
|
|
42
|
+
*
|
|
43
|
+
* @returns A draggable item with optional drag indicator and visual feedback
|
|
44
|
+
*/
|
|
8
45
|
export default function DragItem(props: PropsWithChildren<DragItemProps>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
9
46
|
export {};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import { useContext, useState } from 'react';
|
|
2
|
+
import { useContext, useState, useEffect } from 'react';
|
|
3
3
|
import styled from '@emotion/styled';
|
|
4
4
|
import constants from '../../shared/constants';
|
|
5
5
|
import { ORIENTATION, DragContext } from './types';
|
|
6
6
|
import { DragIndicator } from '../../icons';
|
|
7
|
+
/** Styled component for the draggable item container */
|
|
7
8
|
const Item = styled.div `
|
|
8
9
|
cursor: ${props => props.showIndicator ? 'default' : 'move'};
|
|
9
10
|
display: flex;
|
|
11
|
+
user-select: ${props => props.showIndicator ? 'auto' : 'none'};
|
|
10
12
|
border-top: 2px solid ${props => props.orientation === ORIENTATION.VERTICAL && props.active > 0
|
|
11
13
|
? constants.PRIMARY : 'transparent'};
|
|
12
14
|
border-bottom: 2px solid ${props => props.orientation === ORIENTATION.VERTICAL && props.active < 0
|
|
@@ -15,35 +17,171 @@ const Item = styled.div `
|
|
|
15
17
|
? constants.PRIMARY : 'transparent'};
|
|
16
18
|
border-right: 2px solid ${props => props.orientation === ORIENTATION.HORIZONTAL && props.active < 0
|
|
17
19
|
? constants.PRIMARY : 'transparent'};
|
|
20
|
+
opacity: ${props => props.dragging ? 0.5 : 1};
|
|
18
21
|
`;
|
|
22
|
+
/** Styled component for the drag handle indicator */
|
|
19
23
|
const DragKnob = styled.div `
|
|
20
24
|
padding-top: 8px;
|
|
21
25
|
cursor: move;
|
|
26
|
+
touch-action: none;
|
|
22
27
|
color: var(--disabled, ${constants.DISABLED});
|
|
23
28
|
`;
|
|
29
|
+
/** Container for the children */
|
|
24
30
|
const Container = styled.div `
|
|
25
31
|
flex: 1;
|
|
26
32
|
`;
|
|
33
|
+
/**
|
|
34
|
+
* A draggable item component that supports both mouse and touch interactions for drag-and-drop functionality.
|
|
35
|
+
*
|
|
36
|
+
* @component
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* <DragItem
|
|
40
|
+
* index={0}
|
|
41
|
+
* orientation={ORIENTATION.VERTICAL}
|
|
42
|
+
* showIndicator={true}
|
|
43
|
+
* dragOver={-1}
|
|
44
|
+
* >
|
|
45
|
+
* <div>Draggable content</div>
|
|
46
|
+
* </DragItem>
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @param props - The component props
|
|
50
|
+
* @param props.index - The position index of this item in the draggable list
|
|
51
|
+
* @param props.orientation - The orientation of the drag operation (VERTICAL or HORIZONTAL)
|
|
52
|
+
* @param props.showIndicator - Whether to show a drag handle indicator instead of making the entire item draggable
|
|
53
|
+
* @param props.dragOver - The index of the item currently being dragged over
|
|
54
|
+
* @param props.children - The content to be rendered inside the draggable item
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* - Uses the DragContext to manage drag state across items
|
|
58
|
+
* - Provides visual feedback with borders during drag operations
|
|
59
|
+
* - Supports haptic feedback (vibration) on touch devices
|
|
60
|
+
* - For touch devices, requires a 200ms hold before drag starts
|
|
61
|
+
* - When showIndicator is true, only the drag handle can initiate drag operations
|
|
62
|
+
*
|
|
63
|
+
* @returns A draggable item with optional drag indicator and visual feedback
|
|
64
|
+
*/
|
|
27
65
|
export default function DragItem(props) {
|
|
28
|
-
const { index, orientation, children, showIndicator } = props;
|
|
66
|
+
const { index, orientation, children, showIndicator, dragOver } = props;
|
|
29
67
|
const [active, setActive] = useState(0);
|
|
68
|
+
const [touchTimer, setTouchTimer] = useState(null);
|
|
30
69
|
const context = useContext(DragContext);
|
|
70
|
+
/**
|
|
71
|
+
* Vibrate the device for haptic feedback
|
|
72
|
+
* @param duration Duration of the vibration in milliseconds
|
|
73
|
+
*/
|
|
74
|
+
const vibrate = (duration) => {
|
|
75
|
+
if (navigator.vibrate) {
|
|
76
|
+
navigator.vibrate(duration);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Drag start event handler
|
|
81
|
+
* @param e Event
|
|
82
|
+
*/
|
|
31
83
|
const dragStartHandler = (e) => {
|
|
32
84
|
context.setStartIndex(index);
|
|
85
|
+
context.setIsDragging(true);
|
|
33
86
|
};
|
|
87
|
+
/**
|
|
88
|
+
* Drag over event handler
|
|
89
|
+
* @param e Event
|
|
90
|
+
*/
|
|
34
91
|
const dragOverHandler = (e) => {
|
|
35
92
|
e.preventDefault();
|
|
36
93
|
e.stopPropagation();
|
|
37
94
|
setActive(context.startIndex - index);
|
|
38
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* Drag leave event handler
|
|
98
|
+
*/
|
|
39
99
|
const dragExitHandler = () => {
|
|
40
100
|
setActive(0);
|
|
41
101
|
};
|
|
102
|
+
/**
|
|
103
|
+
* Drop event handler
|
|
104
|
+
* @param e Event
|
|
105
|
+
*/
|
|
42
106
|
const dropHandler = (e) => {
|
|
43
107
|
e.preventDefault();
|
|
44
108
|
setActive(0);
|
|
45
109
|
context.drop(index);
|
|
110
|
+
context.setIsDragging(false);
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Touch start event handler
|
|
114
|
+
* @param e Event
|
|
115
|
+
*/
|
|
116
|
+
const touchStartHandler = (e) => {
|
|
117
|
+
const timer = setTimeout(() => {
|
|
118
|
+
context.setStartIndex(index);
|
|
119
|
+
context.setIsDragging(true);
|
|
120
|
+
context.setDragOver(index);
|
|
121
|
+
document.body.style.overflow = 'hidden';
|
|
122
|
+
vibrate(50);
|
|
123
|
+
}, 200);
|
|
124
|
+
setTouchTimer(timer);
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Touch move event handler
|
|
128
|
+
* @param e Event
|
|
129
|
+
* @returns void
|
|
130
|
+
*/
|
|
131
|
+
const touchMoveHandler = (e) => {
|
|
132
|
+
var _a;
|
|
133
|
+
const touch = e.touches[0];
|
|
134
|
+
if (!touch)
|
|
135
|
+
return;
|
|
136
|
+
if (context.isDragging) {
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
// get the element under the touch point
|
|
139
|
+
const el = document.elementFromPoint(touch.clientX, touch.clientY);
|
|
140
|
+
const overAttr = (_a = el === null || el === void 0 ? void 0 : el.closest('[data-drag-index]')) === null || _a === void 0 ? void 0 : _a.getAttribute('data-drag-index');
|
|
141
|
+
const overIndex = overAttr != null ? parseInt(overAttr, 10) : null;
|
|
142
|
+
// if we know which index we're over, update visual state
|
|
143
|
+
if (overIndex !== null) {
|
|
144
|
+
context.setDragOver(overIndex);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else if (touchTimer) {
|
|
148
|
+
clearTimeout(touchTimer);
|
|
149
|
+
setTouchTimer(null);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Touch end event handler
|
|
154
|
+
* @param e Event
|
|
155
|
+
*/
|
|
156
|
+
const touchEndHandler = (e) => {
|
|
157
|
+
if (touchTimer) {
|
|
158
|
+
clearTimeout(touchTimer);
|
|
159
|
+
setTouchTimer(null);
|
|
160
|
+
}
|
|
161
|
+
if (context.isDragging) {
|
|
162
|
+
context.drop(dragOver);
|
|
163
|
+
vibrate(50);
|
|
164
|
+
context.setIsDragging(false);
|
|
165
|
+
document.body.style.overflow = 'auto';
|
|
166
|
+
}
|
|
46
167
|
};
|
|
47
|
-
|
|
168
|
+
/** Cleanup touch timer on unmount */
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
return () => {
|
|
171
|
+
if (touchTimer)
|
|
172
|
+
clearTimeout(touchTimer);
|
|
173
|
+
document.body.style.overflow = 'auto';
|
|
174
|
+
};
|
|
175
|
+
}, [touchTimer]);
|
|
176
|
+
/** Update active state based on dragOver changes */
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
if (context.isDragging && dragOver === index) {
|
|
179
|
+
setActive(context.startIndex - index);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
setActive(0);
|
|
183
|
+
}
|
|
184
|
+
}, [dragOver, context.startIndex, index, context.isDragging]);
|
|
185
|
+
return _jsxs(Item, { draggable: !showIndicator, showIndicator: showIndicator, active: active, dragging: context.isDragging && context.startIndex === index, orientation: orientation, "data-drag-index": index, onDragStart: !showIndicator ? dragStartHandler : undefined, onDragOver: dragOverHandler, onDragLeave: dragExitHandler, onDrop: dropHandler, onTouchStart: !showIndicator ? touchStartHandler : undefined, onTouchMove: touchMoveHandler, onTouchEnd: touchEndHandler, onTouchCancel: touchEndHandler, children: [showIndicator && _jsx(DragKnob, { draggable: true, onDragStart: dragStartHandler, onTouchStart: touchStartHandler, children: _jsx(DragIndicator, {}) }), _jsx(Container, { children: children })] });
|
|
48
186
|
}
|
|
49
187
|
//# sourceMappingURL=DragItem.js.map
|