playbook_ui 16.7.0 → 16.8.0.pre.alpha.PLAY2935formbuilderrequiredindicatorbug16780

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.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +2 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +2 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/VirtualizedTableView.tsx +5 -1
  5. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +24 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/Utilities/ColumnLayoutHelper.ts +138 -0
  7. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +144 -0
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.jsx +1 -0
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.md +6 -0
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_width.jsx +57 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_width.md +66 -0
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_enable_toggle_expansion_rails.html.erb +62 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_enable_toggle_expansion_rails.md +7 -0
  14. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header.jsx +12 -4
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header.md +4 -0
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header_rails.html.erb +16 -2
  17. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_header_rails.md +4 -0
  18. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_scroll_limitation.jsx +68 -0
  19. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sticky_scroll_limitation.md +7 -0
  20. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.html.erb +16 -2
  21. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.jsx +12 -5
  22. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_rails.md +4 -0
  23. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_react.md +5 -3
  24. data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.json +180 -5839
  25. data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.overrides.json +5 -30
  26. data/app/pb_kits/playbook/pb_advanced_table/docs/advanced_table_column_definitions_styling.json +4 -1
  27. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +3 -0
  28. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -0
  29. data/app/pb_kits/playbook/pb_card/_card.tsx +1 -1
  30. data/app/pb_kits/playbook/pb_card/card.html.erb +1 -1
  31. data/app/pb_kits/playbook/pb_currency/_currency.tsx +9 -6
  32. data/app/pb_kits/playbook/pb_currency/currency.rb +5 -10
  33. data/app/pb_kits/playbook/pb_currency/currency.test.js +44 -1
  34. data/app/pb_kits/playbook/pb_date/docs/_playground.json +13 -17
  35. data/app/pb_kits/playbook/pb_date/docs/_playground.overrides.json +13 -16
  36. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +3 -2
  37. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +38 -23
  38. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +2 -1
  39. data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +31 -0
  40. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_dialog_submission.jsx +2 -2
  41. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.html.erb +0 -2
  42. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_inline.jsx +0 -2
  43. data/app/pb_kits/playbook/pb_date_picker/docs/_playground.json +136 -42
  44. data/app/pb_kits/playbook/pb_date_picker/docs/_playground.overrides.json +113 -45
  45. data/app/pb_kits/playbook/pb_date_range_inline/docs/_playground.json +48 -6
  46. data/app/pb_kits/playbook/pb_date_range_inline/docs/_playground.overrides.json +57 -0
  47. data/app/pb_kits/playbook/pb_date_range_stacked/docs/_playground.json +28 -5
  48. data/app/pb_kits/playbook/pb_date_range_stacked/docs/_playground.overrides.json +38 -0
  49. data/app/pb_kits/playbook/pb_date_stacked/docs/_playground.json +1 -1
  50. data/app/pb_kits/playbook/pb_date_stacked/docs/_playground.overrides.json +1 -1
  51. data/app/pb_kits/playbook/pb_date_time/docs/_playground.json +16 -3
  52. data/app/pb_kits/playbook/pb_date_time/docs/_playground.overrides.json +16 -3
  53. data/app/pb_kits/playbook/pb_date_time_stacked/docs/_playground.json +11 -15
  54. data/app/pb_kits/playbook/pb_date_time_stacked/docs/_playground.overrides.json +11 -15
  55. data/app/pb_kits/playbook/pb_date_year_stacked/docs/_playground.json +4 -4
  56. data/app/pb_kits/playbook/pb_date_year_stacked/docs/_playground.overrides.json +4 -4
  57. data/app/pb_kits/playbook/pb_detail/docs/_playground.json +12 -18
  58. data/app/pb_kits/playbook/pb_detail/docs/_playground.overrides.json +13 -12
  59. data/app/pb_kits/playbook/pb_dialog/docs/_playground.json +108 -42
  60. data/app/pb_kits/playbook/pb_dialog/docs/_playground.overrides.json +88 -40
  61. data/app/pb_kits/playbook/pb_distribution_bar/docs/_playground.json +65 -7
  62. data/app/pb_kits/playbook/pb_distribution_bar/docs/_playground.overrides.json +45 -0
  63. data/app/pb_kits/playbook/pb_draggable/_draggable.scss +19 -0
  64. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_rails.md +2 -0
  65. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_react.md +1 -0
  66. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_rails.md +2 -0
  67. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list_react.md +3 -1
  68. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_rails.md +3 -1
  69. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list_react.md +3 -1
  70. data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +16 -0
  71. data/app/pb_kits/playbook/pb_draggable/draggable_container.html.erb +3 -1
  72. data/app/pb_kits/playbook/pb_draggable/draggable_item.html.erb +1 -0
  73. data/app/pb_kits/playbook/pb_draggable/index.js +149 -7
  74. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +1 -0
  75. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +67 -1
  76. data/app/pb_kits/playbook/pb_draggable/touchDrag.test.js +38 -0
  77. data/app/pb_kits/playbook/pb_draggable/utilities/touchDrag.ts +173 -0
  78. data/app/pb_kits/playbook/pb_dropdown/docs/_playground.json +318 -21
  79. data/app/pb_kits/playbook/pb_dropdown/docs/_playground.overrides.json +192 -19
  80. data/app/pb_kits/playbook/pb_empty_state/docs/_playground.json +77 -12
  81. data/app/pb_kits/playbook/pb_empty_state/docs/_playground.overrides.json +79 -0
  82. data/app/pb_kits/playbook/pb_file_upload/docs/_playground.json +98 -13
  83. data/app/pb_kits/playbook/pb_file_upload/docs/_playground.overrides.json +99 -0
  84. data/app/pb_kits/playbook/pb_form/docs/_form_with_required_indicator.html.erb +20 -19
  85. data/app/pb_kits/playbook/pb_icon/_icon.scss +2 -1
  86. data/app/pb_kits/playbook/pb_icon/docs/example.yml +0 -2
  87. data/app/pb_kits/playbook/pb_icon/docs/index.js +0 -1
  88. data/app/pb_kits/playbook/pb_link/docs/_playground.json +81 -40
  89. data/app/pb_kits/playbook/pb_link/docs/_playground.overrides.json +88 -30
  90. data/app/pb_kits/playbook/pb_list/_list_item.tsx +4 -1
  91. data/app/pb_kits/playbook/pb_list/item.html.erb +1 -1
  92. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_centered_data.html.erb +90 -0
  93. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_centered_data.jsx +100 -0
  94. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_centered_data.md +1 -0
  95. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/_pb_circle_chart_default.jsx +1 -1
  96. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/example.yml +2 -0
  97. data/app/pb_kits/playbook/pb_pb_circle_chart/docs/index.js +2 -1
  98. data/app/pb_kits/playbook/pb_phone_number_input/docs/_playground.json +4 -2
  99. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +1 -1
  100. data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_styles.scss +262 -43
  101. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.html.erb +1 -0
  102. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.md +12 -0
  103. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_simple.html.erb +9 -0
  104. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_simple.md +8 -0
  105. data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +2 -0
  106. data/app/pb_kits/playbook/pb_rich_text_editor/kit.schema.json +18 -9
  107. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +162 -0
  108. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +71 -0
  109. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.js +202 -0
  110. data/app/pb_kits/playbook/pb_table/docs/_table_sticky.html.erb +85 -83
  111. data/app/pb_kits/playbook/pb_table/docs/_table_sticky.jsx +88 -86
  112. data/app/pb_kits/playbook/pb_table/docs/_table_sticky.md +3 -1
  113. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.md +1 -1
  114. data/app/pb_kits/playbook/pb_text_input/_text_input.scss +37 -0
  115. data/app/pb_kits/playbook/pb_title/docs/_playground.json +72 -23
  116. data/app/pb_kits/playbook/pb_title/docs/_playground.overrides.json +80 -16
  117. data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +133 -102
  118. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +54 -41
  119. data/app/pb_kits/playbook/pb_tooltip/tooltip.test.jsx +60 -2
  120. data/dist/chunks/{_pb_line_graph-CIWJe3Gr.js → _pb_line_graph-BgsTI0CL.js} +1 -1
  121. data/dist/chunks/_typeahead-DA__Kgp5.js +5 -0
  122. data/dist/chunks/{globalProps-CqO4Tko1.js → globalProps-DOB47YGB.js} +1 -1
  123. data/dist/chunks/{lib-czQnE40X.js → lib-BzglXly2.js} +2 -2
  124. data/dist/chunks/vendor.js +4 -4
  125. data/dist/menu.yml +71 -132
  126. data/dist/playbook-rails-react-bindings.js +1 -1
  127. data/dist/playbook-rails.js +1 -1
  128. data/dist/playbook.css +1 -1
  129. data/lib/playbook/forms/builder/form_field_builder.rb +2 -0
  130. data/lib/playbook/version.rb +2 -2
  131. metadata +31 -10
  132. data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.html.erb +0 -1
  133. data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.jsx +0 -21
  134. data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.md +0 -7
  135. data/dist/chunks/_typeahead-B_Ac4z84.js +0 -1
@@ -9,6 +9,7 @@ import {
9
9
  import { globalProps } from "../../utilities/globalProps";
10
10
  import { DraggableContext } from "../context";
11
11
  import { noop } from '../../utilities/object'
12
+ import { bindTouchDrag, isTouchDragDevice } from "../utilities/touchDrag";
12
13
 
13
14
  type DraggableItemProps = {
14
15
  aria?: { [key: string]: string };
@@ -54,12 +55,76 @@ const DraggableItem = (props: DraggableItemProps) => {
54
55
  handleDragStart,
55
56
  handleDragEnter,
56
57
  handleDragEnd,
58
+ handleDrop,
59
+ handleDragOver,
57
60
  dropZone = 'ghost',
58
61
  dropZoneColor = 'neutral',
59
62
  direction = 'horizontal'
60
63
  } = DraggableContext();
61
64
 
62
65
  const itemRef = React.useRef<HTMLElement>(null);
66
+ const [useTouchDrag, setUseTouchDrag] = React.useState(false);
67
+ const handlersRef = React.useRef({
68
+ handleDragStart,
69
+ handleDragEnter,
70
+ handleDragEnd,
71
+ handleDrop,
72
+ handleDragOver,
73
+ onDragStart,
74
+ onDragEnter,
75
+ onDragOver,
76
+ onDrop,
77
+ onDragEnd,
78
+ });
79
+
80
+ handlersRef.current = {
81
+ handleDragStart,
82
+ handleDragEnter,
83
+ handleDragEnd,
84
+ handleDrop,
85
+ handleDragOver,
86
+ onDragStart,
87
+ onDragEnter,
88
+ onDragOver,
89
+ onDrop,
90
+ onDragEnd,
91
+ };
92
+
93
+ React.useEffect(() => {
94
+ setUseTouchDrag(isTouchDragDevice());
95
+ }, []);
96
+
97
+ React.useEffect(() => {
98
+ if (!useTouchDrag || !itemRef.current || !dragId) return;
99
+
100
+ return bindTouchDrag({
101
+ dragId,
102
+ container,
103
+ itemElement: itemRef.current,
104
+ handlers: {
105
+ onDragStart: (id, itemContainer) => {
106
+ handlersRef.current.handleDragStart(id, itemContainer);
107
+ handlersRef.current.onDragStart();
108
+ },
109
+ onDragEnter: (targetDragId, targetContainer) => {
110
+ handlersRef.current.handleDragEnter(targetDragId, targetContainer);
111
+ handlersRef.current.onDragEnter();
112
+ },
113
+ onDragOver: (event, targetContainer) => {
114
+ handlersRef.current.handleDragOver(event, targetContainer);
115
+ handlersRef.current.onDragOver();
116
+ },
117
+ onDrop: (dropContainer) => {
118
+ handlersRef.current.handleDrop(dropContainer);
119
+ handlersRef.current.onDrop();
120
+ },
121
+ onDragEnd: () => {
122
+ handlersRef.current.handleDragEnd();
123
+ handlersRef.current.onDragEnd();
124
+ },
125
+ },
126
+ });
127
+ }, [useTouchDrag, dragId, container]);
63
128
 
64
129
  const ariaProps = buildAriaProps(aria);
65
130
  const dataProps = buildDataProps(data);
@@ -122,7 +187,8 @@ const DraggableItem = (props: DraggableItemProps) => {
122
187
  {...dataProps}
123
188
  {...htmlProps}
124
189
  className={classes}
125
- draggable
190
+ data-pb-drag-id={dragId}
191
+ draggable={!useTouchDrag}
126
192
  id={id}
127
193
  key={dragId}
128
194
  onDrag={onDrag}
@@ -0,0 +1,38 @@
1
+ import {
2
+ DRAG_HANDLE_SELECTOR,
3
+ getContainerFromElement,
4
+ getDragIdFromElement,
5
+ } from "./utilities/touchDrag";
6
+
7
+ describe("touchDrag utilities", () => {
8
+ test("DRAG_HANDLE_SELECTOR matches standard and card handles", () => {
9
+ document.body.innerHTML = `
10
+ <div class="pb_draggable_item" data-pb-drag-id="1">
11
+ <span class="pb_draggable_handle"></span>
12
+ <span class="card_draggable_handle"></span>
13
+ </div>
14
+ `;
15
+
16
+ const item = document.querySelector(".pb_draggable_item");
17
+ expect(item.querySelector(DRAG_HANDLE_SELECTOR)).toBeTruthy();
18
+ });
19
+
20
+ test("getDragIdFromElement reads data-pb-drag-id", () => {
21
+ document.body.innerHTML = `
22
+ <div class="pb_draggable_item" data-pb-drag-id="task-1"></div>
23
+ `;
24
+
25
+ expect(getDragIdFromElement(document.querySelector(".pb_draggable_item"))).toBe("task-1");
26
+ });
27
+
28
+ test("getContainerFromElement reads data-pb-drag-container", () => {
29
+ document.body.innerHTML = `
30
+ <div class="pb_draggable_container" data-pb-drag-container="To Do">
31
+ <div class="pb_draggable_item" data-pb-drag-id="1"></div>
32
+ </div>
33
+ `;
34
+
35
+ const item = document.querySelector(".pb_draggable_item");
36
+ expect(getContainerFromElement(item)).toBe("To Do");
37
+ });
38
+ });
@@ -0,0 +1,173 @@
1
+ export const DRAG_HANDLE_SELECTOR = '.pb_draggable_handle, .card_draggable_handle';
2
+
3
+ const DRAG_THRESHOLD_PX = 5;
4
+
5
+ export const isTouchDragDevice = (): boolean => {
6
+ if (typeof window === 'undefined') return false;
7
+
8
+ const hasTouch = 'ontouchstart' in window;
9
+ const hasCoarsePointer =
10
+ typeof window.matchMedia === 'function' &&
11
+ window.matchMedia('(hover: none) and (pointer: coarse)').matches;
12
+
13
+ return hasTouch || hasCoarsePointer;
14
+ };
15
+
16
+ export const getDragIdFromElement = (element: Element | null): string | null => {
17
+ const item = element?.closest('.pb_draggable_item');
18
+ if (!item) return null;
19
+
20
+ return item.getAttribute('data-pb-drag-id');
21
+ };
22
+
23
+ export const getContainerFromElement = (element: Element | null): string | undefined => {
24
+ const container = element?.closest('.pb_draggable_container');
25
+ if (!container) return undefined;
26
+
27
+ return container.getAttribute('data-pb-drag-container') || undefined;
28
+ };
29
+
30
+ type TouchDragHandlers = {
31
+ onDragStart: (dragId: string, container?: string) => void;
32
+ onDragEnter: (targetDragId: string, container?: string) => void;
33
+ onDragOver: (event: Event, container?: string) => void;
34
+ onDrop: (container?: string) => void;
35
+ onDragEnd: () => void;
36
+ };
37
+
38
+ type TouchDragOptions = {
39
+ dragId: string;
40
+ container?: string;
41
+ itemElement: HTMLElement;
42
+ handlers: TouchDragHandlers;
43
+ };
44
+
45
+ type TouchDragState = {
46
+ active: boolean;
47
+ dragging: boolean;
48
+ startX: number;
49
+ startY: number;
50
+ lastTargetDragId: string | null;
51
+ lastContainer: string | undefined;
52
+ };
53
+
54
+ const createPreventableEvent = (): Event => ({
55
+ preventDefault: () => undefined,
56
+ } as Event);
57
+
58
+ export const bindTouchDrag = ({
59
+ dragId,
60
+ container,
61
+ itemElement,
62
+ handlers,
63
+ }: TouchDragOptions): (() => void) => {
64
+ if (!isTouchDragDevice()) return () => undefined;
65
+
66
+ const handle = itemElement.querySelector(DRAG_HANDLE_SELECTOR) as HTMLElement | null;
67
+ const dragTarget = handle || itemElement;
68
+
69
+ const state: TouchDragState = {
70
+ active: false,
71
+ dragging: false,
72
+ startX: 0,
73
+ startY: 0,
74
+ lastTargetDragId: null,
75
+ lastContainer: undefined,
76
+ };
77
+
78
+ const resetState = () => {
79
+ state.active = false;
80
+ state.dragging = false;
81
+ state.lastTargetDragId = null;
82
+ state.lastContainer = undefined;
83
+ itemElement.classList.remove('is_touch_active');
84
+ };
85
+
86
+ const handleTouchStart = (event: TouchEvent) => {
87
+ if (handle && !handle.contains(event.target as Node)) return;
88
+
89
+ const touch = event.touches[0];
90
+ if (!touch) return;
91
+
92
+ state.active = true;
93
+ state.startX = touch.clientX;
94
+ state.startY = touch.clientY;
95
+ itemElement.classList.add('is_touch_active');
96
+ };
97
+
98
+ const handleTouchMove = (event: TouchEvent) => {
99
+ if (!state.active) return;
100
+
101
+ const touch = event.touches[0];
102
+ if (!touch) return;
103
+
104
+ if (!state.dragging) {
105
+ const deltaX = touch.clientX - state.startX;
106
+ const deltaY = touch.clientY - state.startY;
107
+
108
+ if (Math.hypot(deltaX, deltaY) < DRAG_THRESHOLD_PX) return;
109
+
110
+ state.dragging = true;
111
+ handlers.onDragStart(dragId, container);
112
+ }
113
+
114
+ event.preventDefault();
115
+
116
+ const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY);
117
+ const targetDragId = getDragIdFromElement(elementBelow);
118
+ const targetContainer = getContainerFromElement(elementBelow);
119
+
120
+ if (targetDragId && targetDragId !== dragId && targetDragId !== state.lastTargetDragId) {
121
+ state.lastTargetDragId = targetDragId;
122
+ handlers.onDragEnter(targetDragId, targetContainer ?? container);
123
+ }
124
+
125
+ if (targetContainer && targetContainer !== state.lastContainer) {
126
+ state.lastContainer = targetContainer;
127
+ handlers.onDragOver(createPreventableEvent(), targetContainer);
128
+ } else if (targetContainer) {
129
+ handlers.onDragOver(createPreventableEvent(), targetContainer);
130
+ }
131
+ };
132
+
133
+ const finishDrag = (touch: Touch | null) => {
134
+ if (!state.active) return;
135
+
136
+ if (state.dragging && touch) {
137
+ const elementBelow = document.elementFromPoint(touch.clientX, touch.clientY);
138
+ const dropContainer = getContainerFromElement(elementBelow) ?? container;
139
+
140
+ if (dropContainer) {
141
+ handlers.onDrop(dropContainer);
142
+ }
143
+
144
+ handlers.onDragEnd();
145
+ }
146
+
147
+ resetState();
148
+ };
149
+
150
+ const handleTouchEnd = (event: TouchEvent) => {
151
+ finishDrag(event.changedTouches[0] ?? null);
152
+ };
153
+
154
+ const handleTouchCancel = (event: TouchEvent) => {
155
+ if (state.dragging) {
156
+ handlers.onDragEnd();
157
+ }
158
+
159
+ finishDrag(event.changedTouches[0] ?? null);
160
+ };
161
+
162
+ dragTarget.addEventListener('touchstart', handleTouchStart, { passive: true });
163
+ dragTarget.addEventListener('touchmove', handleTouchMove, { passive: false });
164
+ dragTarget.addEventListener('touchend', handleTouchEnd, { passive: true });
165
+ dragTarget.addEventListener('touchcancel', handleTouchCancel, { passive: true });
166
+
167
+ return () => {
168
+ dragTarget.removeEventListener('touchstart', handleTouchStart);
169
+ dragTarget.removeEventListener('touchmove', handleTouchMove);
170
+ dragTarget.removeEventListener('touchend', handleTouchEnd);
171
+ dragTarget.removeEventListener('touchcancel', handleTouchCancel);
172
+ };
173
+ };