@flytedan/flytebot-design-system 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +254 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -31
- package/dist/index.d.ts +73 -31
- package/dist/index.js +254 -119
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components.css +172 -11
package/dist/index.d.cts
CHANGED
|
@@ -924,6 +924,12 @@ interface SortMenuProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
924
924
|
onSort?: (key: string, dir: "asc" | "desc") => void;
|
|
925
925
|
/** Which edge the popover aligns to. Default "right". */
|
|
926
926
|
align?: "left" | "right";
|
|
927
|
+
/** Trigger button height, same scale as every other control in the kit (Button,
|
|
928
|
+
* Input). Default "md" — matches Input/SearchField's own default height, since
|
|
929
|
+
* this is most often placed directly alongside a SearchField in one header row
|
|
930
|
+
* (see TransferList) and the two need to line up. Pass "sm" for a denser,
|
|
931
|
+
* standalone placement. */
|
|
932
|
+
size?: "sm" | "md";
|
|
927
933
|
className?: string;
|
|
928
934
|
}
|
|
929
935
|
/**
|
|
@@ -941,7 +947,7 @@ interface SortMenuProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
941
947
|
* Purely presentational: reports intent through onSort(key, dir) and never holds sort
|
|
942
948
|
* state, so it stays honest against a real endpoint.
|
|
943
949
|
*/
|
|
944
|
-
declare function SortMenu({ fields, sort, onSort, align, className, ...rest }: SortMenuProps): React.JSX.Element;
|
|
950
|
+
declare function SortMenu({ fields, sort, onSort, align, size, className, ...rest }: SortMenuProps): React.JSX.Element;
|
|
945
951
|
|
|
946
952
|
interface Step {
|
|
947
953
|
id: string;
|
|
@@ -1033,8 +1039,19 @@ interface VirtualListProps<T> {
|
|
|
1033
1039
|
start?: boolean;
|
|
1034
1040
|
end?: boolean;
|
|
1035
1041
|
};
|
|
1036
|
-
/** Suppresses onNeedMore while a fetch the caller already started is in flight.
|
|
1042
|
+
/** Suppresses onNeedMore while a fetch the caller already started is in flight. Drives the
|
|
1043
|
+
* small pinned spinner at the bottom of the list — rows already mounted stay exactly as
|
|
1044
|
+
* they are, since this only ever means "more is being appended," never "what's on screen
|
|
1045
|
+
* might be stale." For the append-vs-replace distinction, see `refreshing` below. */
|
|
1037
1046
|
loading?: boolean;
|
|
1047
|
+
/** True while the caller is replacing the WHOLE result set (a search or sort change), as
|
|
1048
|
+
* opposed to `loading` appending more onto the end. `items` is expected to still be the
|
|
1049
|
+
* PREVIOUS result set while this is true — this renders it underneath a full-panel scrim
|
|
1050
|
+
* instead of clearing to empty, so a search/sort edit never blanks the list while the new
|
|
1051
|
+
* page is in flight. Swap `items` to the new rows once they land and this back to false. */
|
|
1052
|
+
refreshing?: boolean;
|
|
1053
|
+
/** Copy shown in the `refreshing` overlay's centered card, next to its spinner. */
|
|
1054
|
+
refreshingLabel?: string;
|
|
1038
1055
|
keyOf: (item: T) => string | number;
|
|
1039
1056
|
/** Viewport height in px. Default (400) is ten rows at the kit's --control-h-md (44px). */
|
|
1040
1057
|
height?: number;
|
|
@@ -1071,7 +1088,7 @@ interface VirtualListProps<T> {
|
|
|
1071
1088
|
* needed to compute the window. The caller owns fetching more rows (onNeedMore) and
|
|
1072
1089
|
* knowing when an edge is exhausted (hasMore).
|
|
1073
1090
|
*/
|
|
1074
|
-
declare function VirtualList<T>({ items, itemHeight, renderItem, onNeedMore, hasMore, loading, keyOf, height, emptyState, className, style, }: VirtualListProps<T>): React.JSX.Element;
|
|
1091
|
+
declare function VirtualList<T>({ items, itemHeight, renderItem, onNeedMore, hasMore, loading, refreshing, refreshingLabel, keyOf, height, emptyState, className, style, }: VirtualListProps<T>): React.JSX.Element;
|
|
1075
1092
|
|
|
1076
1093
|
interface EntityRowAction {
|
|
1077
1094
|
/** Phosphor icon name, e.g. "plus" */
|
|
@@ -1089,35 +1106,45 @@ interface EntityRowProps {
|
|
|
1089
1106
|
* title doesn't. Optional because plenty of rows are fine with just a name. */
|
|
1090
1107
|
meta?: React.ReactNode;
|
|
1091
1108
|
action?: EntityRowAction;
|
|
1092
|
-
/** Marks the row a
|
|
1093
|
-
*
|
|
1109
|
+
/** Marks the row a drag source: shows the grip icon and a grab cursor, and reports
|
|
1110
|
+
* `onPointerDown` so the caller's own pointer-based drag (see TransferList) can pick
|
|
1111
|
+
* the gesture up from there. Deliberately NOT the native HTML `draggable` attribute
|
|
1112
|
+
* (see the file doc comment for why) — this row never starts a native browser drag. */
|
|
1094
1113
|
draggable?: boolean;
|
|
1095
|
-
|
|
1096
|
-
onDragEnd?: (e: React.DragEvent<HTMLDivElement>) => void;
|
|
1114
|
+
onPointerDown?: (e: React.PointerEvent<HTMLDivElement>) => void;
|
|
1097
1115
|
style?: React.CSSProperties;
|
|
1098
1116
|
className?: string;
|
|
1099
1117
|
}
|
|
1100
1118
|
/**
|
|
1101
|
-
* EntityRow — a single
|
|
1102
|
-
*
|
|
1119
|
+
* EntityRow — a single row for a name plus an optional secondary line and an optional
|
|
1120
|
+
* action, meant to be stamped out by the hundreds inside a VirtualList.
|
|
1103
1121
|
*
|
|
1104
|
-
*
|
|
1105
|
-
*
|
|
1106
|
-
*
|
|
1122
|
+
* A real card per row, not flat text: its own surface distinct from the list's
|
|
1123
|
+
* background (`--surface-2` against the list's `--surface`), a hairline border, a soft
|
|
1124
|
+
* rest-state shadow that lifts on hover — the same `--r-md`/`--e-1`/`--e-2` elevation
|
|
1125
|
+
* vocabulary Card itself uses (see styles/components.css's ".fd-erow" rules), just at
|
|
1126
|
+
* the tighter radius a compact row reads better at than Card's own `--r-lg`. Height is
|
|
1127
|
+
* still left to the caller (it fills 100% of its parent) because VirtualList is what
|
|
1107
1128
|
* actually fixes row height, and duplicating that number here would be one more place a
|
|
1108
|
-
* future change has to remember to update
|
|
1129
|
+
* future change has to remember to update — the card treatment lives entirely in
|
|
1130
|
+
* padding/border/shadow, not height.
|
|
1109
1131
|
*
|
|
1110
1132
|
* The drag/drop split is deliberate: a row only ever needs to say "I am the thing being
|
|
1111
|
-
* dragged" (draggable +
|
|
1112
|
-
*
|
|
1113
|
-
*
|
|
1114
|
-
*
|
|
1115
|
-
* TransferList
|
|
1133
|
+
* dragged" (draggable + onPointerDown), never "something was dropped on me" — nothing in
|
|
1134
|
+
* this kit drops one row onto another to reorder it, only a row onto a list to move it
|
|
1135
|
+
* there. Putting the drop handling on every row would mean wiring the same drop logic N
|
|
1136
|
+
* times over instead of once on the list container that actually owns it (see
|
|
1137
|
+
* TransferList's own doc comment for why it drives a pointer-based custom drag rather than
|
|
1138
|
+
* native HTML5 DnD — in short, a native drag image is a static snapshot, not a live
|
|
1139
|
+
* element, so it can't sustain a persistent tilt that follows the cursor), so this only
|
|
1140
|
+
* exposes the source half of the contract: `onPointerDown` hands the gesture off to
|
|
1141
|
+
* whatever the caller wants to do with it (TransferList starts tracking a drag once the
|
|
1142
|
+
* pointer has moved past a small threshold, so a plain click still reads as a click).
|
|
1116
1143
|
* The action button exists precisely so drag-and-drop is never the only way to do the
|
|
1117
1144
|
* same move — pointer-only and keyboard users get an equally real affordance, not a
|
|
1118
1145
|
* degraded fallback.
|
|
1119
1146
|
*/
|
|
1120
|
-
declare function EntityRow({ title, meta, action, draggable,
|
|
1147
|
+
declare function EntityRow({ title, meta, action, draggable, onPointerDown, style, className }: EntityRowProps): React.JSX.Element;
|
|
1121
1148
|
|
|
1122
1149
|
type TransferListSide = "left" | "right";
|
|
1123
1150
|
interface TransferListSideProps<T> {
|
|
@@ -1126,6 +1153,11 @@ interface TransferListSideProps<T> {
|
|
|
1126
1153
|
/** Total matching count on the server, if known — shown next to the label. */
|
|
1127
1154
|
total?: number;
|
|
1128
1155
|
loading?: boolean;
|
|
1156
|
+
/** True while this side's WHOLE result set is being replaced (a search or sort
|
|
1157
|
+
* change), not merely appended to. `items` should still be the previous result set
|
|
1158
|
+
* while this is true — see VirtualList's own `refreshing` prop, which this threads
|
|
1159
|
+
* straight through. */
|
|
1160
|
+
refreshing?: boolean;
|
|
1129
1161
|
search: string;
|
|
1130
1162
|
onSearchChange: (value: string) => void;
|
|
1131
1163
|
sort?: {
|
|
@@ -1142,6 +1174,12 @@ interface TransferListSideProps<T> {
|
|
|
1142
1174
|
/** Heading text for this side. Fully caller-supplied — this component has no opinion
|
|
1143
1175
|
* about what the two sides represent. */
|
|
1144
1176
|
label?: string;
|
|
1177
|
+
/** Copy shown in the full-panel drop overlay while a drag is over this side. Falls
|
|
1178
|
+
* back to a generic "Drop here" (plus `label`, if set) when omitted — set this for
|
|
1179
|
+
* exact per-side wording (e.g. "Drop to add to audience" / "Drop to remove from
|
|
1180
|
+
* audience"), since that phrasing is about what a drop here DOES, which only the
|
|
1181
|
+
* caller's domain actually knows. */
|
|
1182
|
+
dropLabel?: string;
|
|
1145
1183
|
}
|
|
1146
1184
|
interface TransferListProps<T> {
|
|
1147
1185
|
left: TransferListSideProps<T>;
|
|
@@ -1169,19 +1207,23 @@ interface TransferListProps<T> {
|
|
|
1169
1207
|
* lists is specific to that use, and baking in "available"/"selected" (or worse, this
|
|
1170
1208
|
* kit's actual first consumer's own vocabulary) would make every *other* two-list picker
|
|
1171
1209
|
* this kit will ever be asked for a second component instead of a second set of props. A
|
|
1172
|
-
* caller wanting domain words passes them through `label`.
|
|
1210
|
+
* caller wanting domain words passes them through `label`/`dropLabel`.
|
|
1173
1211
|
*
|
|
1174
|
-
*
|
|
1175
|
-
*
|
|
1176
|
-
*
|
|
1177
|
-
*
|
|
1178
|
-
*
|
|
1179
|
-
*
|
|
1180
|
-
*
|
|
1181
|
-
*
|
|
1182
|
-
*
|
|
1183
|
-
*
|
|
1184
|
-
*
|
|
1212
|
+
* A pointer-based custom drag, not native HTML5 DnD, and not a library: this kit ships
|
|
1213
|
+
* zero runtime dependencies on purpose, and a pointer-events implementation (pointerdown/
|
|
1214
|
+
* pointermove/pointerup driving a portaled ghost element) is still zero-dependency — just
|
|
1215
|
+
* more code than `draggable`. It replaced an earlier native-HTML5-DnD version once the
|
|
1216
|
+
* spec called for a real "card lifts out of the list and tilts, following the cursor"
|
|
1217
|
+
* feel: a native drag image (`dataTransfer.setDragImage`) is a static snapshot taken once
|
|
1218
|
+
* at dragstart, not a live element, so it can't sustain a persistent rotation that tracks
|
|
1219
|
+
* the pointer for the duration of the drag — only owning the pointer events ourselves can.
|
|
1220
|
+
* Each row's pointerdown (via EntityRow's `onPointerDown`) arms a potential drag; nothing
|
|
1221
|
+
* visually happens until the pointer actually moves past `DRAG_THRESHOLD_PX`, so a plain
|
|
1222
|
+
* click (on the row, or on its +/- action button) is never mistaken for one. Once armed,
|
|
1223
|
+
* window-level pointermove/pointerup/pointercancel listeners (not per-row ones, since the
|
|
1224
|
+
* row being dragged gets replaced by a placeholder mid-drag) track the gesture to
|
|
1225
|
+
* completion; which side the pointer is currently over is decided by hit-testing each
|
|
1226
|
+
* side's own bounding rect against the pointer position, not by any per-row target.
|
|
1185
1227
|
*
|
|
1186
1228
|
* The +/- action on every row is not a fallback bolted on for accessibility box-ticking:
|
|
1187
1229
|
* it is the same onMove call a drop makes, exposed as a first-class equivalent, because
|
package/dist/index.d.ts
CHANGED
|
@@ -924,6 +924,12 @@ interface SortMenuProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
924
924
|
onSort?: (key: string, dir: "asc" | "desc") => void;
|
|
925
925
|
/** Which edge the popover aligns to. Default "right". */
|
|
926
926
|
align?: "left" | "right";
|
|
927
|
+
/** Trigger button height, same scale as every other control in the kit (Button,
|
|
928
|
+
* Input). Default "md" — matches Input/SearchField's own default height, since
|
|
929
|
+
* this is most often placed directly alongside a SearchField in one header row
|
|
930
|
+
* (see TransferList) and the two need to line up. Pass "sm" for a denser,
|
|
931
|
+
* standalone placement. */
|
|
932
|
+
size?: "sm" | "md";
|
|
927
933
|
className?: string;
|
|
928
934
|
}
|
|
929
935
|
/**
|
|
@@ -941,7 +947,7 @@ interface SortMenuProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
941
947
|
* Purely presentational: reports intent through onSort(key, dir) and never holds sort
|
|
942
948
|
* state, so it stays honest against a real endpoint.
|
|
943
949
|
*/
|
|
944
|
-
declare function SortMenu({ fields, sort, onSort, align, className, ...rest }: SortMenuProps): React.JSX.Element;
|
|
950
|
+
declare function SortMenu({ fields, sort, onSort, align, size, className, ...rest }: SortMenuProps): React.JSX.Element;
|
|
945
951
|
|
|
946
952
|
interface Step {
|
|
947
953
|
id: string;
|
|
@@ -1033,8 +1039,19 @@ interface VirtualListProps<T> {
|
|
|
1033
1039
|
start?: boolean;
|
|
1034
1040
|
end?: boolean;
|
|
1035
1041
|
};
|
|
1036
|
-
/** Suppresses onNeedMore while a fetch the caller already started is in flight.
|
|
1042
|
+
/** Suppresses onNeedMore while a fetch the caller already started is in flight. Drives the
|
|
1043
|
+
* small pinned spinner at the bottom of the list — rows already mounted stay exactly as
|
|
1044
|
+
* they are, since this only ever means "more is being appended," never "what's on screen
|
|
1045
|
+
* might be stale." For the append-vs-replace distinction, see `refreshing` below. */
|
|
1037
1046
|
loading?: boolean;
|
|
1047
|
+
/** True while the caller is replacing the WHOLE result set (a search or sort change), as
|
|
1048
|
+
* opposed to `loading` appending more onto the end. `items` is expected to still be the
|
|
1049
|
+
* PREVIOUS result set while this is true — this renders it underneath a full-panel scrim
|
|
1050
|
+
* instead of clearing to empty, so a search/sort edit never blanks the list while the new
|
|
1051
|
+
* page is in flight. Swap `items` to the new rows once they land and this back to false. */
|
|
1052
|
+
refreshing?: boolean;
|
|
1053
|
+
/** Copy shown in the `refreshing` overlay's centered card, next to its spinner. */
|
|
1054
|
+
refreshingLabel?: string;
|
|
1038
1055
|
keyOf: (item: T) => string | number;
|
|
1039
1056
|
/** Viewport height in px. Default (400) is ten rows at the kit's --control-h-md (44px). */
|
|
1040
1057
|
height?: number;
|
|
@@ -1071,7 +1088,7 @@ interface VirtualListProps<T> {
|
|
|
1071
1088
|
* needed to compute the window. The caller owns fetching more rows (onNeedMore) and
|
|
1072
1089
|
* knowing when an edge is exhausted (hasMore).
|
|
1073
1090
|
*/
|
|
1074
|
-
declare function VirtualList<T>({ items, itemHeight, renderItem, onNeedMore, hasMore, loading, keyOf, height, emptyState, className, style, }: VirtualListProps<T>): React.JSX.Element;
|
|
1091
|
+
declare function VirtualList<T>({ items, itemHeight, renderItem, onNeedMore, hasMore, loading, refreshing, refreshingLabel, keyOf, height, emptyState, className, style, }: VirtualListProps<T>): React.JSX.Element;
|
|
1075
1092
|
|
|
1076
1093
|
interface EntityRowAction {
|
|
1077
1094
|
/** Phosphor icon name, e.g. "plus" */
|
|
@@ -1089,35 +1106,45 @@ interface EntityRowProps {
|
|
|
1089
1106
|
* title doesn't. Optional because plenty of rows are fine with just a name. */
|
|
1090
1107
|
meta?: React.ReactNode;
|
|
1091
1108
|
action?: EntityRowAction;
|
|
1092
|
-
/** Marks the row a
|
|
1093
|
-
*
|
|
1109
|
+
/** Marks the row a drag source: shows the grip icon and a grab cursor, and reports
|
|
1110
|
+
* `onPointerDown` so the caller's own pointer-based drag (see TransferList) can pick
|
|
1111
|
+
* the gesture up from there. Deliberately NOT the native HTML `draggable` attribute
|
|
1112
|
+
* (see the file doc comment for why) — this row never starts a native browser drag. */
|
|
1094
1113
|
draggable?: boolean;
|
|
1095
|
-
|
|
1096
|
-
onDragEnd?: (e: React.DragEvent<HTMLDivElement>) => void;
|
|
1114
|
+
onPointerDown?: (e: React.PointerEvent<HTMLDivElement>) => void;
|
|
1097
1115
|
style?: React.CSSProperties;
|
|
1098
1116
|
className?: string;
|
|
1099
1117
|
}
|
|
1100
1118
|
/**
|
|
1101
|
-
* EntityRow — a single
|
|
1102
|
-
*
|
|
1119
|
+
* EntityRow — a single row for a name plus an optional secondary line and an optional
|
|
1120
|
+
* action, meant to be stamped out by the hundreds inside a VirtualList.
|
|
1103
1121
|
*
|
|
1104
|
-
*
|
|
1105
|
-
*
|
|
1106
|
-
*
|
|
1122
|
+
* A real card per row, not flat text: its own surface distinct from the list's
|
|
1123
|
+
* background (`--surface-2` against the list's `--surface`), a hairline border, a soft
|
|
1124
|
+
* rest-state shadow that lifts on hover — the same `--r-md`/`--e-1`/`--e-2` elevation
|
|
1125
|
+
* vocabulary Card itself uses (see styles/components.css's ".fd-erow" rules), just at
|
|
1126
|
+
* the tighter radius a compact row reads better at than Card's own `--r-lg`. Height is
|
|
1127
|
+
* still left to the caller (it fills 100% of its parent) because VirtualList is what
|
|
1107
1128
|
* actually fixes row height, and duplicating that number here would be one more place a
|
|
1108
|
-
* future change has to remember to update
|
|
1129
|
+
* future change has to remember to update — the card treatment lives entirely in
|
|
1130
|
+
* padding/border/shadow, not height.
|
|
1109
1131
|
*
|
|
1110
1132
|
* The drag/drop split is deliberate: a row only ever needs to say "I am the thing being
|
|
1111
|
-
* dragged" (draggable +
|
|
1112
|
-
*
|
|
1113
|
-
*
|
|
1114
|
-
*
|
|
1115
|
-
* TransferList
|
|
1133
|
+
* dragged" (draggable + onPointerDown), never "something was dropped on me" — nothing in
|
|
1134
|
+
* this kit drops one row onto another to reorder it, only a row onto a list to move it
|
|
1135
|
+
* there. Putting the drop handling on every row would mean wiring the same drop logic N
|
|
1136
|
+
* times over instead of once on the list container that actually owns it (see
|
|
1137
|
+
* TransferList's own doc comment for why it drives a pointer-based custom drag rather than
|
|
1138
|
+
* native HTML5 DnD — in short, a native drag image is a static snapshot, not a live
|
|
1139
|
+
* element, so it can't sustain a persistent tilt that follows the cursor), so this only
|
|
1140
|
+
* exposes the source half of the contract: `onPointerDown` hands the gesture off to
|
|
1141
|
+
* whatever the caller wants to do with it (TransferList starts tracking a drag once the
|
|
1142
|
+
* pointer has moved past a small threshold, so a plain click still reads as a click).
|
|
1116
1143
|
* The action button exists precisely so drag-and-drop is never the only way to do the
|
|
1117
1144
|
* same move — pointer-only and keyboard users get an equally real affordance, not a
|
|
1118
1145
|
* degraded fallback.
|
|
1119
1146
|
*/
|
|
1120
|
-
declare function EntityRow({ title, meta, action, draggable,
|
|
1147
|
+
declare function EntityRow({ title, meta, action, draggable, onPointerDown, style, className }: EntityRowProps): React.JSX.Element;
|
|
1121
1148
|
|
|
1122
1149
|
type TransferListSide = "left" | "right";
|
|
1123
1150
|
interface TransferListSideProps<T> {
|
|
@@ -1126,6 +1153,11 @@ interface TransferListSideProps<T> {
|
|
|
1126
1153
|
/** Total matching count on the server, if known — shown next to the label. */
|
|
1127
1154
|
total?: number;
|
|
1128
1155
|
loading?: boolean;
|
|
1156
|
+
/** True while this side's WHOLE result set is being replaced (a search or sort
|
|
1157
|
+
* change), not merely appended to. `items` should still be the previous result set
|
|
1158
|
+
* while this is true — see VirtualList's own `refreshing` prop, which this threads
|
|
1159
|
+
* straight through. */
|
|
1160
|
+
refreshing?: boolean;
|
|
1129
1161
|
search: string;
|
|
1130
1162
|
onSearchChange: (value: string) => void;
|
|
1131
1163
|
sort?: {
|
|
@@ -1142,6 +1174,12 @@ interface TransferListSideProps<T> {
|
|
|
1142
1174
|
/** Heading text for this side. Fully caller-supplied — this component has no opinion
|
|
1143
1175
|
* about what the two sides represent. */
|
|
1144
1176
|
label?: string;
|
|
1177
|
+
/** Copy shown in the full-panel drop overlay while a drag is over this side. Falls
|
|
1178
|
+
* back to a generic "Drop here" (plus `label`, if set) when omitted — set this for
|
|
1179
|
+
* exact per-side wording (e.g. "Drop to add to audience" / "Drop to remove from
|
|
1180
|
+
* audience"), since that phrasing is about what a drop here DOES, which only the
|
|
1181
|
+
* caller's domain actually knows. */
|
|
1182
|
+
dropLabel?: string;
|
|
1145
1183
|
}
|
|
1146
1184
|
interface TransferListProps<T> {
|
|
1147
1185
|
left: TransferListSideProps<T>;
|
|
@@ -1169,19 +1207,23 @@ interface TransferListProps<T> {
|
|
|
1169
1207
|
* lists is specific to that use, and baking in "available"/"selected" (or worse, this
|
|
1170
1208
|
* kit's actual first consumer's own vocabulary) would make every *other* two-list picker
|
|
1171
1209
|
* this kit will ever be asked for a second component instead of a second set of props. A
|
|
1172
|
-
* caller wanting domain words passes them through `label`.
|
|
1210
|
+
* caller wanting domain words passes them through `label`/`dropLabel`.
|
|
1173
1211
|
*
|
|
1174
|
-
*
|
|
1175
|
-
*
|
|
1176
|
-
*
|
|
1177
|
-
*
|
|
1178
|
-
*
|
|
1179
|
-
*
|
|
1180
|
-
*
|
|
1181
|
-
*
|
|
1182
|
-
*
|
|
1183
|
-
*
|
|
1184
|
-
*
|
|
1212
|
+
* A pointer-based custom drag, not native HTML5 DnD, and not a library: this kit ships
|
|
1213
|
+
* zero runtime dependencies on purpose, and a pointer-events implementation (pointerdown/
|
|
1214
|
+
* pointermove/pointerup driving a portaled ghost element) is still zero-dependency — just
|
|
1215
|
+
* more code than `draggable`. It replaced an earlier native-HTML5-DnD version once the
|
|
1216
|
+
* spec called for a real "card lifts out of the list and tilts, following the cursor"
|
|
1217
|
+
* feel: a native drag image (`dataTransfer.setDragImage`) is a static snapshot taken once
|
|
1218
|
+
* at dragstart, not a live element, so it can't sustain a persistent rotation that tracks
|
|
1219
|
+
* the pointer for the duration of the drag — only owning the pointer events ourselves can.
|
|
1220
|
+
* Each row's pointerdown (via EntityRow's `onPointerDown`) arms a potential drag; nothing
|
|
1221
|
+
* visually happens until the pointer actually moves past `DRAG_THRESHOLD_PX`, so a plain
|
|
1222
|
+
* click (on the row, or on its +/- action button) is never mistaken for one. Once armed,
|
|
1223
|
+
* window-level pointermove/pointerup/pointercancel listeners (not per-row ones, since the
|
|
1224
|
+
* row being dragged gets replaced by a placeholder mid-drag) track the gesture to
|
|
1225
|
+
* completion; which side the pointer is currently over is decided by hit-testing each
|
|
1226
|
+
* side's own bounding rect against the pointer position, not by any per-row target.
|
|
1185
1227
|
*
|
|
1186
1228
|
* The +/- action on every row is not a fallback bolted on for accessibility box-ticking:
|
|
1187
1229
|
* it is the same onMove call a drop makes, exposed as a first-class equivalent, because
|