pixel-react 1.0.5 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/lib/StyleGuide/ColorPalette/types.d.ts +2 -0
  3. package/lib/assets/utils/functionUtils.d.ts +3 -0
  4. package/lib/components/DatePicker/DatePicker.d.ts +5 -0
  5. package/lib/components/DatePicker/DatePicker.stories.d.ts +9 -0
  6. package/lib/components/DatePicker/Timepicker.d.ts +4 -0
  7. package/lib/components/DatePicker/index.d.ts +1 -0
  8. package/lib/components/DatePicker/types.d.ts +81 -0
  9. package/lib/components/DragAndDrop/DragAndDrop.d.ts +9 -0
  10. package/lib/components/DragAndDrop/DragAndDrop.stories.d.ts +6 -0
  11. package/lib/components/DragAndDrop/DragAndDropList.d.ts +20 -0
  12. package/lib/components/DragAndDrop/index.d.ts +1 -0
  13. package/lib/components/Drawer/Drawer.d.ts +2 -1
  14. package/lib/components/IconButton/IconButton.d.ts +5 -0
  15. package/lib/components/IconButton/IconButton.stories.d.ts +6 -0
  16. package/lib/components/IconButton/index.d.ts +1 -0
  17. package/lib/components/{AddButton → IconButton}/types.d.ts +3 -2
  18. package/lib/components/InputWithDropdown/InputWithDropdown.d.ts +1 -1
  19. package/lib/components/InputWithDropdown/types.d.ts +3 -7
  20. package/lib/components/Modal/Modal.d.ts +5 -0
  21. package/lib/components/Modal/Modal.stories.d.ts +7 -0
  22. package/lib/components/Modal/index.d.ts +1 -0
  23. package/lib/components/Modal/types.d.ts +26 -0
  24. package/lib/components/TableTree/TableTree.d.ts +2 -2
  25. package/lib/components/ThemeProvider/CustomThemeProvider.d.ts +8 -0
  26. package/lib/hooks/useCustomThemeProvider.d.ts +11 -0
  27. package/lib/index.d.ts +76 -16
  28. package/lib/index.esm.js +13365 -414
  29. package/lib/index.esm.js.map +1 -1
  30. package/lib/index.js +13368 -415
  31. package/lib/index.js.map +1 -1
  32. package/lib/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +28 -23
  34. package/src/StyleGuide/ColorPalette/ColorPalette.scss +5 -0
  35. package/src/StyleGuide/ColorPalette/ColorPalette.tsx +10 -1
  36. package/src/StyleGuide/ColorPalette/colorPaletteList.ts +2 -2
  37. package/src/StyleGuide/ColorPalette/types.ts +2 -0
  38. package/src/assets/Themes/BaseTheme.scss +9 -1
  39. package/src/assets/Themes/DarkTheme.scss +8 -1
  40. package/src/assets/icons/add_variable_icon.svg +5 -0
  41. package/src/assets/icons/calendar_icon.svg +9 -0
  42. package/src/assets/icons/clock_icon.svg +11 -0
  43. package/src/assets/icons/collapse-icon.svg +6 -0
  44. package/src/assets/icons/copy-icon.svg +3 -0
  45. package/src/assets/icons/download-icon.svg +3 -0
  46. package/src/assets/icons/expand-icon.svg +6 -0
  47. package/src/assets/icons/info_icon.svg +4 -0
  48. package/src/assets/icons/left_arrow_icon.svg +3 -0
  49. package/src/assets/icons/license_info.svg +28 -0
  50. package/src/assets/icons/license_warning.svg +10 -0
  51. package/src/assets/icons/refresh-icon.svg +4 -0
  52. package/src/assets/icons/right_arrow_icon.svg +4 -0
  53. package/src/assets/styles/_mixins.scss +1 -0
  54. package/src/assets/utils/functionUtils.ts +37 -0
  55. package/src/components/DatePicker/DatePicker.scss +387 -0
  56. package/src/components/DatePicker/DatePicker.stories.tsx +161 -0
  57. package/src/components/DatePicker/DatePicker.tsx +438 -0
  58. package/src/components/DatePicker/Timepicker.tsx +372 -0
  59. package/src/components/DatePicker/index.ts +1 -0
  60. package/src/components/DatePicker/types.ts +100 -0
  61. package/src/components/DragAndDrop/DragAndDrop.d.ts +5 -0
  62. package/src/components/DragAndDrop/DragAndDrop.stories.tsx +25 -0
  63. package/src/components/DragAndDrop/DragAndDrop.ts +7 -0
  64. package/src/components/DragAndDrop/DragAndDropList.scss +69 -0
  65. package/src/components/DragAndDrop/DragAndDropList.tsx +150 -0
  66. package/src/components/DragAndDrop/index.ts +1 -0
  67. package/src/components/Drawer/Drawer.scss +0 -1
  68. package/src/components/Drawer/Drawer.tsx +7 -15
  69. package/src/components/Icon/iconList.ts +31 -9
  70. package/src/components/{AddButton/AddButton.scss → IconButton/IconButton.scss} +6 -2
  71. package/src/components/IconButton/IconButton.stories.tsx +25 -0
  72. package/src/components/{AddButton/AddButton.tsx → IconButton/IconButton.tsx} +10 -7
  73. package/src/components/IconButton/index.ts +1 -0
  74. package/src/components/{AddButton → IconButton}/types.ts +3 -2
  75. package/src/components/InputWithDropdown/InputWithDropdown.scss +1 -1
  76. package/src/components/InputWithDropdown/InputWithDropdown.stories.tsx +10 -13
  77. package/src/components/InputWithDropdown/InputWithDropdown.tsx +10 -8
  78. package/src/components/InputWithDropdown/types.ts +4 -7
  79. package/src/components/Modal/Modal.stories.tsx +63 -0
  80. package/src/components/Modal/Modal.tsx +71 -0
  81. package/src/components/Modal/index.tsx +1 -0
  82. package/src/components/Modal/modal.scss +37 -0
  83. package/src/components/Modal/types.ts +37 -0
  84. package/src/components/RadioButton/RadioButton.scss +3 -3
  85. package/src/components/Select/Select.scss +1 -1
  86. package/src/components/TableTree/TableTree.tsx +5 -1
  87. package/src/components/ThemeProvider/ThemeProvider.tsx +11 -8
  88. package/src/index.ts +6 -6
  89. package/lib/components/AddButton/AddButton.d.ts +0 -5
  90. package/lib/components/AddButton/AddButton.stories.d.ts +0 -6
  91. package/lib/components/AddButton/index.d.ts +0 -1
  92. package/src/assets/icons/expired_license_icon.svg +0 -3
  93. package/src/assets/icons/expiringSoon_license_icon.svg +0 -3
  94. package/src/components/AddButton/AddButton.stories.tsx +0 -24
  95. package/src/components/AddButton/index.ts +0 -1
@@ -0,0 +1,372 @@
1
+ import React, { useState, useRef, useEffect } from 'react';
2
+ import Typography from '../Typography';
3
+ import { TimePickerProps } from './types';
4
+ import Icon from '../Icon';
5
+ import classNames from 'classnames';
6
+ import { convertTo24Hour } from '../../assets/utils/functionUtils';
7
+ import { convertTo12Hour } from '../../assets/utils/functionUtils';
8
+ import { isValid12HourTime } from '../../assets/utils/functionUtils';
9
+
10
+ const TimePicker: React.FC<TimePickerProps> = ({
11
+ value,
12
+ onChange,
13
+ minTime,
14
+ maxTime,
15
+ onErrorChange,
16
+ }) => {
17
+ const [inputValue, setInputValue] = useState<string>('');
18
+ const [period, setPeriod] = useState<string | undefined>('AM');
19
+ const [timeFieldError, setTimeFieldError] = useState<boolean>(false);
20
+ const [isPeriodDropdownOpen, setIsPeriodDropdownOpen] = useState(false);
21
+ const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 });
22
+ const inputRef = useRef<HTMLInputElement>(null);
23
+ const periodRef = useRef<HTMLDivElement>(null);
24
+
25
+ useEffect(() => {
26
+ if (value) {
27
+ const time12h = convertTo12Hour(value);
28
+ const [time, periodValue] = time12h.split(' ') as [string, 'AM' | 'PM'];
29
+ setInputValue(time);
30
+ setPeriod(periodValue);
31
+
32
+ setTimeFieldError(!isTimeWithInBounds(time12h, minTime, maxTime));
33
+ }
34
+ }, [value, minTime, maxTime]);
35
+
36
+ useEffect(() => {
37
+ const handleClickOutside = (e: MouseEvent) => {
38
+ if (
39
+ isPeriodDropdownOpen &&
40
+ periodRef.current &&
41
+ !periodRef.current.contains(e.target as Node)
42
+ ) {
43
+ setIsPeriodDropdownOpen(false);
44
+ }
45
+ };
46
+ document.addEventListener('mousedown', handleClickOutside);
47
+ return () => document.removeEventListener('mousedown', handleClickOutside);
48
+ }, [isPeriodDropdownOpen]);
49
+
50
+ useEffect(() => {
51
+ onErrorChange(timeFieldError);
52
+ }, [timeFieldError]);
53
+
54
+ const generateTimeOptions = (): string[] => {
55
+ const options: string[] = [];
56
+ const start = 0;
57
+ const end = 23 * 60 + 45;
58
+ const interval = 15;
59
+
60
+ for (let i = start; i <= end; i += interval) {
61
+ const hours = Math.floor(i / 60);
62
+ const minutes = i % 60;
63
+ const period = hours >= 12 ? 'PM' : 'AM';
64
+ const displayHour = hours % 12 || 12;
65
+ const displayMinutes = minutes < 10 ? '0' + minutes : minutes;
66
+ options.push(`${displayHour}:${displayMinutes} ${period}`);
67
+ }
68
+ return options;
69
+ };
70
+
71
+ const timeOptions = generateTimeOptions();
72
+
73
+ const isTimeWithInBounds = (
74
+ time: string,
75
+ minTime?: string,
76
+ maxTime?: string
77
+ ): boolean => {
78
+ const [hours = 0, minutes = 0] = convertTo24Hour(time)
79
+ .split(':')
80
+ .map(Number);
81
+ const timeValue = hours * 60 + minutes;
82
+
83
+ if (minTime) {
84
+ const [minHours = 0, minMinutes = 0] = minTime.split(':').map(Number);
85
+ const minValue = minHours * 60 + minMinutes;
86
+ if (timeValue < minValue) return false;
87
+ }
88
+
89
+ if (maxTime) {
90
+ const [maxHours = 0, maxMinutes = 0] = maxTime.split(':').map(Number);
91
+ const maxValue = maxHours * 60 + maxMinutes;
92
+ if (timeValue > maxValue) return false;
93
+ }
94
+
95
+ return true;
96
+ };
97
+
98
+ const handleTimeInput = (event: React.ChangeEvent<HTMLInputElement>) => {
99
+ let [hourSection, minuteSection] = inputValue.split(':');
100
+ let [newHour, newMinute] = event.target.value.split(':');
101
+ const selectionStart = inputRef.current?.selectionStart ?? 0;
102
+
103
+ // Handle hour part input
104
+ if (selectionStart <= 2) {
105
+ const currentHour = parseInt(hourSection ?? '0') || 0;
106
+
107
+ if (newHour?.length === 1) {
108
+ hourSection = currentHour
109
+ ? hourSection?.slice(-1) + newHour
110
+ : `0${newHour}`; // Single digit input
111
+ } else {
112
+ hourSection = newHour?.padStart(2, '0'); // Two digits for hour
113
+ }
114
+
115
+ // Ensure hour part is valid (between 1 and 12)
116
+ let parsedHour = parseInt(hourSection ?? '0') || 0;
117
+ if (parsedHour > 12) {
118
+ parsedHour = parseInt(newHour ?? '0'); // Fix if hour exceeds 12
119
+ }
120
+
121
+ hourSection = parsedHour.toString().padStart(2, '0');
122
+
123
+ // Move to minute part if hour is greater than 1, otherwise stay on hour
124
+ if (parsedHour > 1) {
125
+ setTimeout(() => {
126
+ inputRef.current?.setSelectionRange(3, 5); // Move to minute part
127
+ }, 0);
128
+ } else {
129
+ setTimeout(() => {
130
+ inputRef.current?.setSelectionRange(0, 2); // Keep cursor on hour part
131
+ }, 0);
132
+ }
133
+ }
134
+
135
+ // Handle minute part input
136
+ if (selectionStart >= 3) {
137
+ const currentMinute = parseInt(minuteSection ?? '0') || 0;
138
+
139
+ if (newMinute?.length === 1) {
140
+ minuteSection = currentMinute
141
+ ? minuteSection?.slice(-1) + newMinute
142
+ : `0${newMinute}`; // Single digit input
143
+ } else {
144
+ minuteSection = newMinute?.padStart(2, '0'); // Two digits for minute
145
+ }
146
+
147
+ // Ensure minute part is valid (between 00 and 59)
148
+ let parsedMinute = parseInt(minuteSection ?? '0') || 0;
149
+ if (parsedMinute > 59) {
150
+ parsedMinute = parseInt(newMinute ?? '0'); // Fix if minute exceeds 59
151
+ }
152
+
153
+ minuteSection = parsedMinute.toString().padStart(2, '0');
154
+
155
+ if (parsedMinute < 6) {
156
+ setTimeout(() => {
157
+ inputRef.current?.setSelectionRange(3, 5); // Keep cursor on minute part
158
+ }, 0);
159
+ }
160
+ }
161
+
162
+ setInputValue(`${hourSection}:${minuteSection}`);
163
+ if (isValid12HourTime(`${hourSection}:${minuteSection}`)) {
164
+ const time24h = convertTo24Hour(
165
+ `${hourSection}:${minuteSection} ${period}`
166
+ );
167
+ onChange(time24h);
168
+ setTimeFieldError(false);
169
+ } else {
170
+ setTimeFieldError(true);
171
+ }
172
+ };
173
+
174
+ const togglePeriodDropdown = () => {
175
+ setIsPeriodDropdownOpen((prev) => !prev);
176
+ if (periodRef.current) {
177
+ const { top, left, height } = periodRef.current.getBoundingClientRect();
178
+ setDropdownPosition({ top: top + height, left: left });
179
+ }
180
+ };
181
+
182
+ const handlePeriodChange = (option: string) => {
183
+ setPeriod(option);
184
+ const time24h = convertTo24Hour(`${inputValue} ${option}`);
185
+ onChange(time24h);
186
+ setIsPeriodDropdownOpen(false);
187
+ };
188
+
189
+ const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
190
+ const { key } = event;
191
+ const selectionStart = inputRef.current?.selectionStart ?? 0;
192
+ const selectionEnd = inputRef.current?.selectionEnd ?? 0;
193
+ let [hourSection, minuteSection] = inputValue.split(':');
194
+
195
+ if (key === 'Backspace' && selectionStart <= 2) {
196
+ event.preventDefault();
197
+ hourSection = 'HH';
198
+ setInputValue(`${hourSection}:${minuteSection}`);
199
+ setTimeout(() => inputRef.current?.setSelectionRange(0, 2), 0);
200
+ setTimeFieldError(true);
201
+ }
202
+
203
+ if (key === 'Backspace' && selectionStart >= 3) {
204
+ event.preventDefault();
205
+ minuteSection = 'MM';
206
+ setInputValue(`${hourSection}:${minuteSection}`);
207
+ setTimeout(() => inputRef.current?.setSelectionRange(3, 5), 0);
208
+ setTimeFieldError(true);
209
+ }
210
+
211
+ if (key === 'ArrowRight') {
212
+ if (selectionEnd === 2) {
213
+ event.preventDefault();
214
+ inputRef.current?.setSelectionRange(3, 5);
215
+ } else if (selectionStart === 0) {
216
+ event.preventDefault();
217
+ inputRef.current?.setSelectionRange(0, 2);
218
+ }
219
+ }
220
+
221
+ if (key === 'ArrowLeft') {
222
+ if (selectionStart === 3) {
223
+ event.preventDefault();
224
+ inputRef.current?.setSelectionRange(0, 2);
225
+ } else if (selectionStart === 5) {
226
+ event.preventDefault();
227
+ inputRef.current?.setSelectionRange(3, 5);
228
+ }
229
+ }
230
+ };
231
+
232
+ const handleFocus = () => {
233
+ if (inputValue === '') {
234
+ setInputValue('HH:MM');
235
+ }
236
+ setTimeout(() => {
237
+ inputRef.current?.setSelectionRange(0, 2);
238
+ }, 0);
239
+ };
240
+
241
+ const handleBlur = () => {
242
+ if (inputValue === 'HH:MM') {
243
+ setInputValue('');
244
+ }
245
+ };
246
+
247
+ const handleClick = () => {
248
+ const selectionStart = inputRef.current?.selectionStart ?? 0;
249
+ if (selectionStart >= 3) {
250
+ inputRef.current?.setSelectionRange(3, 5);
251
+ } else {
252
+ inputRef.current?.setSelectionRange(0, 2);
253
+ }
254
+ };
255
+
256
+ const handleTimeOptionClick = (time: string) => {
257
+ const [timeValue, periodValue] = time.split(' ') as [string, 'AM' | 'PM'];
258
+ setInputValue(timeValue);
259
+ setPeriod(periodValue);
260
+ const time24h = convertTo24Hour(`${timeValue} ${periodValue}`);
261
+ onChange(time24h);
262
+ setTimeFieldError(false);
263
+ };
264
+
265
+ return (
266
+ <div className="ff-time-picker-container">
267
+ <div className="ff-time-picker-fields">
268
+ <div
269
+ className={classNames(
270
+ 'ff-time-input-container',
271
+ { 'ff-time-input-container--float': !!inputValue },
272
+ { 'ff-time-input-container--danger': !!timeFieldError }
273
+ )}
274
+ >
275
+ <Typography
276
+ as="label"
277
+ htmlFor="time"
278
+ className={classNames('ff-time-input-label', {
279
+ 'ff-time-input-label--danger': !!timeFieldError,
280
+ })}
281
+ >
282
+ Time
283
+ </Typography>
284
+ <input
285
+ name="time"
286
+ ref={inputRef}
287
+ type="text"
288
+ id="time-input"
289
+ value={inputValue}
290
+ inputMode="numeric"
291
+ placeholder="HH:MM"
292
+ onChange={handleTimeInput}
293
+ onKeyDown={handleKeyDown}
294
+ onFocus={handleFocus}
295
+ onClick={handleClick}
296
+ onBlur={handleBlur}
297
+ maxLength={5}
298
+ className={classNames('ff-time-input', {
299
+ 'ff-time-input--danger': !!timeFieldError,
300
+ })}
301
+ />
302
+ </div>
303
+ <div
304
+ className={classNames('ff-time-period-container', {
305
+ 'ff-time-period-container--active': !!isPeriodDropdownOpen,
306
+ })}
307
+ ref={periodRef}
308
+ >
309
+ <div
310
+ onClick={togglePeriodDropdown}
311
+ className="ff-time-period-select"
312
+ aria-haspopup="listbox"
313
+ aria-expanded={isPeriodDropdownOpen}
314
+ >
315
+ <Typography>{period}</Typography>
316
+ <Icon
317
+ name={isPeriodDropdownOpen ? 'arrow_up' : 'arrow_down'}
318
+ className="ff-time-period-icon"
319
+ height={12}
320
+ width={12}
321
+ />
322
+ </div>
323
+
324
+ {isPeriodDropdownOpen && (
325
+ <ul
326
+ className="ff-time-period-options"
327
+ style={{
328
+ top: `${dropdownPosition.top}px`,
329
+ left: `${dropdownPosition.left}px`,
330
+ }}
331
+ role="listbox"
332
+ >
333
+ <Typography
334
+ as="li"
335
+ className="ff-option-item"
336
+ onClick={() => handlePeriodChange('AM')}
337
+ aria-selected={period === 'AM'}
338
+ >
339
+ AM
340
+ </Typography>
341
+ <Typography
342
+ as="li"
343
+ className="ff-option-item"
344
+ onClick={() => handlePeriodChange('PM')}
345
+ aria-selected={period === 'PM'}
346
+ >
347
+ PM
348
+ </Typography>
349
+ </ul>
350
+ )}
351
+ </div>
352
+ </div>
353
+ <div className="ff-time-picker-options">
354
+ {timeOptions
355
+ .filter((time) => isTimeWithInBounds(time, minTime, maxTime))
356
+ .map((time, index) => (
357
+ <div
358
+ key={index}
359
+ className="ff-time-option"
360
+ onClick={() => handleTimeOptionClick(time)}
361
+ >
362
+ <Typography lineHeight="18px" textAlign="center">
363
+ {time}
364
+ </Typography>
365
+ </div>
366
+ ))}
367
+ </div>
368
+ </div>
369
+ );
370
+ };
371
+
372
+ export default TimePicker;
@@ -0,0 +1 @@
1
+ export { default } from './DatePicker';
@@ -0,0 +1,100 @@
1
+ export interface DatePickerProps {
2
+ /**
3
+ * The minimum selectable date.
4
+ */
5
+ minDate?: DateValue;
6
+
7
+ /**
8
+ * The maximum selectable date.
9
+ */
10
+ maxDate?: DateValue;
11
+
12
+ /**
13
+ * Selected date value.
14
+ */
15
+ value?: DateValue;
16
+
17
+ /**
18
+ * Function to handle date selection.
19
+ */
20
+ onChange: (value: DateValue) => void;
21
+
22
+ /**
23
+ * Placeholder text for the input field.
24
+ */
25
+ placeholder?: string;
26
+
27
+ /**
28
+ * Disables the date picker.
29
+ */
30
+ disabled?: boolean;
31
+
32
+ /**
33
+ * Format for displaying the selected date. Default is 'EEEE, dd MMM yyyy'.
34
+ */
35
+ dateFormat?: string;
36
+
37
+ /**
38
+ * Format for displaying the selected time. Default is 'hh:mm a'.
39
+ */
40
+ timeFormat?: string;
41
+
42
+ /**
43
+ * Timezone for the date picker.
44
+ */
45
+ timezone?: string;
46
+
47
+ /**
48
+ * Custom width for the calendar. This will override the default width of the calendar.
49
+ */
50
+ calendarWidth?: number;
51
+
52
+ /**
53
+ * When true, displays the input field error.
54
+ */
55
+ error?: boolean;
56
+
57
+ /**
58
+ * Helper text to display below the input field, used for error messages or instructions.
59
+ */
60
+ helperText?: string | undefined;
61
+ }
62
+
63
+ export type DateValue = Date | undefined;
64
+
65
+ export interface CustomCaptionProps {
66
+ children?: React.ReactNode; // You can use ReactNode as a fallback for dynamic content
67
+ }
68
+
69
+ export interface CustomCalenderButtonProps {
70
+ className?: string;
71
+ disabled?: boolean | undefined;
72
+ onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
73
+ }
74
+
75
+ export interface TimePickerProps {
76
+ /**
77
+ * The current time value, in string format (e.g., '14:30').
78
+ */
79
+ value: string;
80
+
81
+ /**
82
+ * Function to handle time selection changes, receiving the selected time as a string.
83
+ */
84
+ onChange: (time: string) => void;
85
+
86
+ /**
87
+ * The minimum selectable time, used to restrict the earliest selectable time.
88
+ */
89
+ minTime?: string;
90
+
91
+ /**
92
+ * The maximum selectable time, used to restrict the latest selectable time.
93
+ */
94
+ maxTime?: string;
95
+
96
+ /**
97
+ * Function to handle error state changes, receiving a boolean indicating the presence of an error.
98
+ */
99
+ onErrorChange: (error: boolean) => void;
100
+ }
@@ -0,0 +1,5 @@
1
+ declare module 'DragAndDrop' {
2
+ export * from '@dnd-kit/core';
3
+ export * from '@dnd-kit/sortable';
4
+ export * from '@dnd-kit/utilities';
5
+ }
@@ -0,0 +1,25 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import DragAndDropList from './DragAndDropList';
3
+
4
+ const meta: Meta<typeof DragAndDropList> = {
5
+ title: 'Components/DragAndDrop',
6
+ component: DragAndDropList,
7
+ parameters: {
8
+ layout: 'centered',
9
+ docs: {
10
+ description: {
11
+ component: `It is a drag and drop list component that allows users to reorder items by dragging and dropping them. Library used is dnd-kit/core, dnd-kit/sortable, dnd-kit/utilities`,
12
+ story:
13
+ 'This is a link of [dnd-kit library](https://www.npmjs.com/package/@dnd-kit/core) for reference to an external website.',
14
+ },
15
+ },
16
+ },
17
+ tags: ['autodocs'],
18
+ };
19
+
20
+ type Story = StoryObj<typeof DragAndDropList>;
21
+
22
+ export const Primary: Story = {
23
+ render: () => <DragAndDropList />,
24
+ };
25
+ export default meta;
@@ -0,0 +1,7 @@
1
+ import * as DNDCore from '@dnd-kit/core';
2
+ import * as DNDSortable from '@dnd-kit/sortable';
3
+ import * as DNDUtilities from '@dnd-kit/utilities';
4
+
5
+ const DragAndDrop = { DNDCore, DNDSortable, DNDUtilities };
6
+
7
+ export default DragAndDrop;
@@ -0,0 +1,69 @@
1
+ $primary-color: #2563eb;
2
+ $primary-hover-color: #235dda;
3
+ $background-color: #f2f2f3;
4
+ $white-color: #fff;
5
+ $border-radius: 5px;
6
+ $box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px;
7
+ $checkbox-size: 20px;
8
+
9
+ .drag-and-drop-list {
10
+ height: max-content;
11
+ width: fit-content;
12
+ display: flex;
13
+ flex-direction: column;
14
+ align-items: center;
15
+ gap: 30px;
16
+ }
17
+
18
+ .column {
19
+ background-color: $background-color;
20
+ border-radius: $border-radius;
21
+ padding: 15px;
22
+ width: 80%;
23
+ max-width: 500px;
24
+ display: flex;
25
+ flex-direction: column;
26
+ gap: 15px;
27
+
28
+ .task {
29
+ background-color: $white-color;
30
+ border-radius: $border-radius;
31
+ box-shadow: $box-shadow;
32
+ padding: 4px 8px;
33
+ display: flex;
34
+ align-items: center;
35
+ justify-content: flex-start;
36
+ gap: 20px;
37
+ cursor: grab;
38
+ &-title {
39
+ word-break: break-all;
40
+ }
41
+ }
42
+ }
43
+
44
+ .container {
45
+ display: flex;
46
+ justify-content: space-between;
47
+ gap: 10px;
48
+
49
+ .input {
50
+ border: 2px solid #ddd;
51
+ border-radius: $border-radius;
52
+ padding: 10px;
53
+ width: 200px;
54
+ }
55
+
56
+ .button {
57
+ border: none;
58
+ border-radius: $border-radius;
59
+ padding: 10px 15px;
60
+ background-color: $primary-color;
61
+ color: $white-color;
62
+ cursor: pointer;
63
+ margin-left: 10px;
64
+
65
+ &:hover {
66
+ background-color: $primary-hover-color;
67
+ }
68
+ }
69
+ }