@fayz-ai/pos 0.26.1 → 0.27.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.js CHANGED
@@ -4969,6 +4969,9 @@ function lateness(p, now) {
4969
4969
  var GHOST_MS = 300;
4970
4970
  var TOUCH_HOLD_MS = 280;
4971
4971
  var DRAG_SLOP_PX = 6;
4972
+ var MAX_TILT_DEG = 9;
4973
+ var TILT_PER_SPEED = 6;
4974
+ var SETTLE_MS = 260;
4972
4975
  function DeliveryBoard({ orders, activeId, onSelect, now, channelsConnected, historyOpen, onToggleHistory, loading, stepOf, onMove, onRefuse, waiting }) {
4973
4976
  const seen = useRef({});
4974
4977
  const [ghosts, setGhosts] = useState([]);
@@ -4993,6 +4996,39 @@ function DeliveryBoard({ orders, activeId, onSelect, now, channelsConnected, his
4993
4996
  const [drag, setDrag] = useState(null);
4994
4997
  const dragging = useRef(false);
4995
4998
  const swallowClick = useRef(false);
4999
+ const ghostRef = useRef(null);
5000
+ const anchor = useRef({ x0: 0, y0: 0, left: 0, top: 0 });
5001
+ const motion = useRef({ x: 0, y: 0, lastX: 0, lastT: 0, vx: 0, tilt: 0, spin: 0, raf: 0 });
5002
+ const [settling, setSettling] = useState(false);
5003
+ const settleTimer = useRef(void 0);
5004
+ const calm = () => typeof window !== "undefined" && !!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
5005
+ const paint = (scale = 1.04) => {
5006
+ const el = ghostRef.current;
5007
+ if (!el) return;
5008
+ const m = motion.current;
5009
+ const a = anchor.current;
5010
+ el.style.transform = `translate3d(${m.x - a.x0}px, ${m.y - a.y0}px, 0) rotate(${m.tilt.toFixed(2)}deg) scale(${scale})`;
5011
+ };
5012
+ const step = (t) => {
5013
+ const m = motion.current;
5014
+ const dt = Math.min(64, Math.max(1, t - (m.lastT || t - 16)));
5015
+ m.vx += ((m.x - m.lastX) / dt - m.vx) * 0.3;
5016
+ m.lastX = m.x;
5017
+ m.lastT = t;
5018
+ const lean = calm() ? 0 : Math.max(-MAX_TILT_DEG, Math.min(MAX_TILT_DEG, m.vx * TILT_PER_SPEED));
5019
+ m.spin = (m.spin + (lean - m.tilt) * 0.16) * 0.78;
5020
+ m.tilt += m.spin;
5021
+ paint();
5022
+ m.raf = requestAnimationFrame(step);
5023
+ };
5024
+ const stopMotion = () => {
5025
+ if (motion.current.raf) cancelAnimationFrame(motion.current.raf);
5026
+ motion.current.raf = 0;
5027
+ };
5028
+ useEffect(() => () => {
5029
+ stopMotion();
5030
+ window.clearTimeout(settleTimer.current);
5031
+ }, []);
4996
5032
  useEffect(() => {
4997
5033
  if (!drag) return;
4998
5034
  const hold = (e) => {
@@ -5015,29 +5051,68 @@ function DeliveryBoard({ orders, activeId, onSelect, now, channelsConnected, his
5015
5051
  p.el.setPointerCapture(p.pointerId);
5016
5052
  } catch {
5017
5053
  }
5054
+ window.clearTimeout(settleTimer.current);
5055
+ setSettling(false);
5056
+ anchor.current = { x0: p.x, y0: p.y, left: r.left, top: r.top };
5057
+ motion.current = { x, y, lastX: x, lastT: 0, vx: 0, tilt: 0, spin: 0, raf: 0 };
5018
5058
  setDrag({ id: p.id, x0: p.x, y0: p.y, x, y, left: r.left, top: r.top, width: r.width, over: columnAt(x, y) });
5059
+ stopMotion();
5060
+ motion.current.raf = requestAnimationFrame(step);
5019
5061
  };
5020
- const release = () => {
5062
+ const endGesture = () => {
5021
5063
  const p = press.current;
5022
5064
  if (p?.timer) window.clearTimeout(p.timer);
5023
5065
  press.current = null;
5024
5066
  dragging.current = false;
5067
+ };
5068
+ const release = () => {
5069
+ endGesture();
5070
+ stopMotion();
5071
+ window.clearTimeout(settleTimer.current);
5072
+ setSettling(false);
5025
5073
  setDrag(null);
5026
5074
  };
5075
+ const settle = (to) => {
5076
+ stopMotion();
5077
+ const el = ghostRef.current;
5078
+ if (!el || calm()) {
5079
+ release();
5080
+ return;
5081
+ }
5082
+ const a = anchor.current;
5083
+ const dx = to ? to.left - a.left : 0;
5084
+ const dy = to ? to.top - a.top : 0;
5085
+ setSettling(true);
5086
+ requestAnimationFrame(() => {
5087
+ el.style.transform = `translate3d(${dx}px, ${dy}px, 0) rotate(0deg) scale(1)`;
5088
+ if (to) el.style.opacity = "0";
5089
+ });
5090
+ window.clearTimeout(settleTimer.current);
5091
+ settleTimer.current = window.setTimeout(release, SETTLE_MS);
5092
+ };
5093
+ const slotOf = (column) => {
5094
+ const col = document.querySelector(`[data-col="${column.replace(/["\\]/g, "\\$&")}"]`);
5095
+ if (!col) return null;
5096
+ const r = col.getBoundingClientRect();
5097
+ const head = col.firstElementChild;
5098
+ const headH = head ? head.getBoundingClientRect().height : 0;
5099
+ return { left: r.left + 8, top: r.top + headH + 8 };
5100
+ };
5027
5101
  const drop = (o, target) => {
5028
5102
  const from = columnOfOrder(o);
5029
- if (!target || target === from) return;
5030
- const step = stepOf(o);
5031
- const stepColumn = step.next ? deliveryColumnOf(step.next)?.name : void 0;
5032
- if (step.next && stepColumn === target) {
5103
+ if (!target || target === from) return false;
5104
+ const next = stepOf(o);
5105
+ const stepColumn = next.next ? deliveryColumnOf(next.next)?.name : void 0;
5106
+ if (next.next && stepColumn === target) {
5033
5107
  haptic("tap");
5034
- onMove(o, step.next);
5035
- return;
5108
+ onMove(o, next.next);
5109
+ return true;
5036
5110
  }
5037
5111
  haptic("warn");
5038
5112
  const order = DELIVERY_COLUMNS.map((c) => c.name);
5039
- const text = step.held ? "Quem leva este pedido \xE9 o entregador do canal: Em rota e Entregue v\xEAm dele, n\xE3o da loja." : !step.next ? "Este pedido n\xE3o tem pr\xF3xima etapa." : order.indexOf(target) < order.indexOf(from ?? "") ? "O pedido s\xF3 anda para frente." : `Uma etapa por vez: a pr\xF3xima \xE9 \xAB${stepColumn}\xBB.`;
5113
+ const text = next.held ? "Quem leva este pedido \xE9 o entregador do canal: Em rota e Entregue v\xEAm dele, n\xE3o da loja." : !next.next ? "Este pedido n\xE3o tem pr\xF3xima etapa." : order.indexOf(target) < order.indexOf(from ?? "") ? "O pedido s\xF3 anda para frente." : `Uma etapa por vez: a pr\xF3xima \xE9 \xAB${stepColumn}\xBB.`;
5040
5114
  onRefuse?.(text);
5115
+ return false;
5041
5116
  };
5042
5117
  const dragHandlers = (o) => !canDrag ? {} : {
5043
5118
  onPointerDown: (e) => {
@@ -5066,16 +5141,24 @@ function DeliveryBoard({ orders, activeId, onSelect, now, channelsConnected, his
5066
5141
  if (travel < DRAG_SLOP_PX) return;
5067
5142
  begin(e.clientX, e.clientY);
5068
5143
  }
5069
- setDrag((d) => d && { ...d, x: e.clientX, y: e.clientY, over: columnAt(e.clientX, e.clientY) });
5144
+ motion.current.x = e.clientX;
5145
+ motion.current.y = e.clientY;
5146
+ const over = columnAt(e.clientX, e.clientY);
5147
+ setDrag((d) => d && d.over !== over ? { ...d, over } : d);
5070
5148
  },
5071
5149
  onPointerUp: (e) => {
5072
5150
  const p = press.current;
5073
5151
  if (!p || p.pointerId !== e.pointerId) return;
5074
5152
  const was = dragging.current;
5075
- release();
5076
- if (!was) return;
5153
+ if (!was) {
5154
+ release();
5155
+ return;
5156
+ }
5157
+ endGesture();
5077
5158
  swallowClick.current = true;
5078
- drop(o, columnAt(e.clientX, e.clientY));
5159
+ const target = columnAt(e.clientX, e.clientY);
5160
+ const moved = drop(o, target);
5161
+ settle(moved && target ? slotOf(target) : null);
5079
5162
  },
5080
5163
  onPointerCancel: () => {
5081
5164
  release();
@@ -5203,14 +5286,17 @@ function DeliveryBoard({ orders, activeId, onSelect, now, channelsConnected, his
5203
5286
  drag && dragged && /* @__PURE__ */ jsxs(
5204
5287
  "span",
5205
5288
  {
5289
+ ref: ghostRef,
5206
5290
  className: "pos-card pos-card--drag",
5291
+ "data-settling": settling || void 0,
5207
5292
  "aria-hidden": true,
5208
5293
  style: {
5209
5294
  position: "fixed",
5210
5295
  left: drag.left,
5211
5296
  top: drag.top,
5212
5297
  width: drag.width,
5213
- transform: `translate(${drag.x - drag.x0}px, ${drag.y - drag.y0}px)`
5298
+ // Painted every frame by the motion loop; this is only the first frame.
5299
+ transform: "translate3d(0, 0, 0) scale(1.04)"
5214
5300
  },
5215
5301
  children: [
5216
5302
  /* @__PURE__ */ jsxs("span", { className: "pos-card__top", children: [