@photon-ai/pho-ui 1.2.0 → 1.2.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.
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { useCallback as u, useEffect as w, useRef as f } from "react";
3
+ import { useAnimationControls as E } from "motion/react";
4
+ var L = {
5
+ type: "spring",
6
+ stiffness: 700,
7
+ damping: 32,
8
+ mass: 0.06
9
+ }, R = 0.96;
10
+ function S(l) {
11
+ const p = l?.scale ?? 0.96, t = l?.disabled ?? !1, s = l?.transition ?? L, n = E(), i = f(!1), d = f(null), r = f(null);
12
+ w(() => () => r.current?.(), []);
13
+ const o = u(() => {
14
+ t || (i.current = !0, d.current = n.start({
15
+ scale: p,
16
+ transition: s
17
+ }));
18
+ }, [
19
+ n,
20
+ t,
21
+ p,
22
+ s
23
+ ]), c = u(async () => {
24
+ if (!i.current) return;
25
+ i.current = !1;
26
+ const e = d.current;
27
+ await e, !(i.current || d.current !== e) && n.start({
28
+ scale: 1,
29
+ transition: s
30
+ });
31
+ }, [n, s]);
32
+ return {
33
+ pulse: u(() => {
34
+ o(), c();
35
+ }, [o, c]),
36
+ motionProps: {
37
+ initial: !1,
38
+ animate: n,
39
+ onPointerDown: u((e) => {
40
+ if (t || e.button !== 0 || !e.isPrimary) return;
41
+ o(), r.current?.();
42
+ const a = (m) => {
43
+ m.pointerId === e.pointerId && (r.current?.(), c());
44
+ };
45
+ window.addEventListener("pointerup", a), window.addEventListener("pointercancel", a), r.current = () => {
46
+ window.removeEventListener("pointerup", a), window.removeEventListener("pointercancel", a), r.current = null;
47
+ };
48
+ }, [
49
+ t,
50
+ o,
51
+ c
52
+ ])
53
+ }
54
+ };
55
+ }
56
+ export {
57
+ L as n,
58
+ S as r,
59
+ R as t
60
+ };
61
+
62
+ //# sourceMappingURL=use-press-pulse-8iorQPsh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-press-pulse-8iorQPsh.js","names":[],"sources":["../../src/utils/use-press-pulse.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\nimport { useAnimationControls, type Transition } from \"motion/react\";\n\n/**\n * Press feedback for selection controls (Select trigger, Checkbox…) — the same\n * spring family as Button's effect press, and the same pointer-following\n * behavior: press in on pointer-down, stay compressed while held, spring back\n * on release. One deliberate refinement over a bare `whileTap`: a fast tap\n * never truncates the press-in leg — it always reaches full depth before\n * springing back, so even the quickest click reads as a complete tick.\n */\nexport const CONTROL_PRESS_SPRING = {\n type: \"spring\",\n stiffness: 700,\n damping: 32,\n mass: 0.06,\n} as const;\n\n/** Default press depth — shallow; each control can tune its own. */\nexport const CONTROL_PRESS_SCALE = 0.96;\n\n/**\n * Pointer-following press driven by Motion controls. Spread `motionProps` onto\n * a `motion.*` element (via Base UI `render`): pointer-down (primary button)\n * compresses and holds; release springs back once the press-in leg has\n * finished. Release is tracked on `window`, so dragging off the control before\n * letting go still restores it.\n */\nexport function usePressPulse(opts?: {\n scale?: number;\n disabled?: boolean;\n /** Spring override for both legs of the press. @default CONTROL_PRESS_SPRING */\n transition?: Transition;\n}) {\n const scale = opts?.scale ?? CONTROL_PRESS_SCALE;\n const disabled = opts?.disabled ?? false;\n const transition = opts?.transition ?? CONTROL_PRESS_SPRING;\n const controls = useAnimationControls();\n const pressed = useRef(false);\n const pressIn = useRef<Promise<unknown> | null>(null);\n const removeListeners = useRef<(() => void) | null>(null);\n\n useEffect(() => () => removeListeners.current?.(), []);\n\n const press = useCallback(() => {\n if (disabled) return;\n pressed.current = true;\n pressIn.current = controls.start({ scale, transition });\n }, [controls, disabled, scale, transition]);\n\n const release = useCallback(async () => {\n if (!pressed.current) return;\n pressed.current = false;\n const leg = pressIn.current;\n // Let the press-in leg play out in full before springing back, so a tap\n // shorter than the spring still shows the whole press.\n await leg;\n // A re-press started while we waited — its own release will restore.\n if (pressed.current || pressIn.current !== leg) return;\n void controls.start({ scale: 1, transition });\n }, [controls, transition]);\n\n /** Programmatic one-shot pulse (press in, then spring back). */\n const pulse = useCallback(() => {\n press();\n void release();\n }, [press, release]);\n\n const onPointerDown = useCallback(\n (event: { button: number; pointerId: number; isPrimary: boolean }) => {\n if (disabled || event.button !== 0 || !event.isPrimary) return;\n press();\n // The pointer may be released anywhere (including off the control after\n // dragging away), so listen on window rather than the element — but only\n // for the pointer that started this press, so another finger lifting\n // elsewhere doesn't spring the control back early.\n removeListeners.current?.();\n const end = (e: PointerEvent) => {\n if (e.pointerId !== event.pointerId) return;\n removeListeners.current?.();\n void release();\n };\n window.addEventListener(\"pointerup\", end);\n window.addEventListener(\"pointercancel\", end);\n removeListeners.current = () => {\n window.removeEventListener(\"pointerup\", end);\n window.removeEventListener(\"pointercancel\", end);\n removeListeners.current = null;\n };\n },\n [disabled, press, release],\n );\n\n return {\n pulse,\n motionProps: { initial: false as const, animate: controls, onPointerDown },\n };\n}\n"],"mappings":";;;AAWA,IAAa,IAAuB;AAAA,EAClC,MAAM;AAAA,EACN,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM;AACR,GAGa,IAAsB;AASnC,SAAgB,EAAc,GAK3B;AACD,QAAM,IAAQ,GAAM,SAAA,MACd,IAAW,GAAM,YAAY,IAC7B,IAAa,GAAM,cAAc,GACjC,IAAW,EAAqB,GAChC,IAAU,EAAO,EAAK,GACtB,IAAU,EAAgC,IAAI,GAC9C,IAAkB,EAA4B,IAAI;AAExD,EAAA,EAAA,MAAA,MAAsB,EAAgB,UAAU,GAAG,CAAC,CAAC;AAErD,QAAM,IAAQ,EAAA,MAAkB;AAC9B,IAAI,MACJ,EAAQ,UAAU,IAClB,EAAQ,UAAU,EAAS,MAAM;AAAA,MAAE,OAAA;AAAA,MAAO,YAAA;AAAA,IAAW,CAAC;AAAA,EACxD,GAAG;AAAA,IAAC;AAAA,IAAU;AAAA,IAAU;AAAA,IAAO;AAAA,EAAU,CAAC,GAEpC,IAAU,EAAY,YAAY;AACtC,QAAI,CAAC,EAAQ,QAAS;AACtB,IAAA,EAAQ,UAAU;AAClB,UAAM,IAAM,EAAQ;AAKpB,IAFA,MAAM,GAEF,EAAA,EAAQ,WAAW,EAAQ,YAAY,MAC3C,EAAc,MAAM;AAAA,MAAE,OAAO;AAAA,MAAG,YAAA;AAAA,IAAW,CAAC;AAAA,EAC9C,GAAG,CAAC,GAAU,CAAU,CAAC;AAiCzB,SAAO;AAAA,IACL,OA/BY,EAAA,MAAkB;AAC9B,MAAA,EAAM,GACN,EAAa;AAAA,IACf,GAAG,CAAC,GAAO,CAAO,CA4BhB;AAAA,IACA,aAAa;AAAA,MAAE,SAAS;AAAA,MAAgB,SAAS;AAAA,MAAU,eA3BvC,EAAA,CACnB,MAAqE;AACpE,YAAI,KAAY,EAAM,WAAW,KAAK,CAAC,EAAM,UAAW;AACxD,QAAA,EAAM,GAKN,EAAgB,UAAU;AAC1B,cAAM,IAAA,CAAO,MAAoB;AAC/B,UAAI,EAAE,cAAc,EAAM,cAC1B,EAAgB,UAAU,GAC1B,EAAa;AAAA,QACf;AACA,eAAO,iBAAiB,aAAa,CAAG,GACxC,OAAO,iBAAiB,iBAAiB,CAAG,GAC5C,EAAgB,UAAA,MAAgB;AAC9B,iBAAO,oBAAoB,aAAa,CAAG,GAC3C,OAAO,oBAAoB,iBAAiB,CAAG,GAC/C,EAAgB,UAAU;AAAA,QAC5B;AAAA,MACF,GACA;AAAA,QAAC;AAAA,QAAU;AAAA,QAAO;AAAA,MAAO,CAKkC;AAAA,IAAc;AAAA,EAC3E;AACF"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { t as o } from "../chunks/cn-DTiB6ek_.js";
3
- import { r as p } from "../chunks/use-press-pulse-CMwPTOR2.js";
3
+ import { r as p } from "../chunks/use-press-pulse-8iorQPsh.js";
4
4
  import { t as u } from "../chunks/createReactComponent-BqCmnqfX.js";
5
5
  import { t as b } from "../chunks/IconCheck-D2WuculQ.js";
6
6
  import "react";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { t as a } from "../chunks/cn-DTiB6ek_.js";
3
- import { r as p } from "../chunks/use-press-pulse-CMwPTOR2.js";
3
+ import { r as p } from "../chunks/use-press-pulse-8iorQPsh.js";
4
4
  import { t as u } from "../chunks/IconCheck-D2WuculQ.js";
5
5
  import { createContext as m, useContext as g } from "react";
6
6
  import { jsx as r } from "react/jsx-runtime";
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { t } from "./chunks/cn-DTiB6ek_.js";
3
3
  import { n as o, r, t as S } from "./chunks/link-provider-9TFNyDqO.js";
4
4
  import { t as E } from "./chunks/resolve-variant-CcD8iG5l.js";
5
- import { n as i, r as _, t as m } from "./chunks/use-press-pulse-CMwPTOR2.js";
5
+ import { n as i, r as _, t as m } from "./chunks/use-press-pulse-8iorQPsh.js";
6
6
  import "./utils.js";
7
7
  import { a as e, c as A, d as B, f as O, i as f, l as p, n as u, o as C, r as N, s as D, t as L, u as c } from "./chunks/close-button-Bq9f-H15.js";
8
8
  import { a as l, c as U, i as V, n as d, o as G, r as g, s as k, t as F } from "./chunks/sidebar-BCqq58hV.js";
@@ -1,11 +1,11 @@
1
1
  import { Transition } from 'motion/react';
2
2
  /**
3
- * Press pulse for selection controls (Select trigger, Checkbox…) — the same
4
- * spring family as Button's effect press, with one deliberate difference:
5
- * Button compresses only while held (`whileTap`); these controls play ONE
6
- * FULL pulse (press in → spring back) from the moment of pointer-down, even
7
- * if the pointer lifts early — a discrete "it took" tick, kept shallow and
8
- * quick so it registers without drawing attention.
3
+ * Press feedback for selection controls (Select trigger, Checkbox…) — the same
4
+ * spring family as Button's effect press, and the same pointer-following
5
+ * behavior: press in on pointer-down, stay compressed while held, spring back
6
+ * on release. One deliberate refinement over a bare `whileTap`: a fast tap
7
+ * never truncates the press-in leg — it always reaches full depth before
8
+ * springing back, so even the quickest click reads as a complete tick.
9
9
  */
10
10
  export declare const CONTROL_PRESS_SPRING: {
11
11
  readonly type: "spring";
@@ -13,17 +13,19 @@ export declare const CONTROL_PRESS_SPRING: {
13
13
  readonly damping: 32;
14
14
  readonly mass: 0.06;
15
15
  };
16
- /** Default pulse depth — shallow; each control can tune its own. */
16
+ /** Default press depth — shallow; each control can tune its own. */
17
17
  export declare const CONTROL_PRESS_SCALE = 0.96;
18
18
  /**
19
- * One-shot scale pulse driven by Motion controls. Spread `motionProps` onto a
20
- * `motion.*` element (via Base UI `render`): pointer-down (primary button)
21
- * plays press → rest in full; re-presses during the pulse are coalesced.
19
+ * Pointer-following press driven by Motion controls. Spread `motionProps` onto
20
+ * a `motion.*` element (via Base UI `render`): pointer-down (primary button)
21
+ * compresses and holds; release springs back once the press-in leg has
22
+ * finished. Release is tracked on `window`, so dragging off the control before
23
+ * letting go still restores it.
22
24
  */
23
25
  export declare function usePressPulse(opts?: {
24
26
  scale?: number;
25
27
  disabled?: boolean;
26
- /** Spring override for both legs of the pulse. @default CONTROL_PRESS_SPRING */
28
+ /** Spring override for both legs of the press. @default CONTROL_PRESS_SPRING */
27
29
  transition?: Transition;
28
30
  }): {
29
31
  pulse: () => void;
@@ -32,6 +34,8 @@ export declare function usePressPulse(opts?: {
32
34
  animate: import('motion/react').LegacyAnimationControls;
33
35
  onPointerDown: (event: {
34
36
  button: number;
37
+ pointerId: number;
38
+ isPrimary: boolean;
35
39
  }) => void;
36
40
  };
37
41
  };
package/dist/utils.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { t as s } from "./chunks/cn-DTiB6ek_.js";
3
3
  import { n as t, r as e, t as a } from "./chunks/link-provider-9TFNyDqO.js";
4
4
  import { t as i } from "./chunks/resolve-variant-CcD8iG5l.js";
5
- import { n as p, r as P, t as R } from "./chunks/use-press-pulse-CMwPTOR2.js";
5
+ import { n as p, r as P, t as R } from "./chunks/use-press-pulse-8iorQPsh.js";
6
6
  export {
7
7
  R as CONTROL_PRESS_SCALE,
8
8
  p as CONTROL_PRESS_SPRING,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@photon-ai/pho-ui",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Pho Design System — Photon's React component library, built on Base UI",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -1,44 +0,0 @@
1
- "use client";
2
- import { useCallback as o, useRef as c } from "react";
3
- import { useAnimationControls as u } from "motion/react";
4
- var f = {
5
- type: "spring",
6
- stiffness: 700,
7
- damping: 32,
8
- mass: 0.06
9
- }, p = 0.96;
10
- function R(s) {
11
- const a = s?.scale ?? 0.96, i = s?.disabled ?? !1, t = s?.transition ?? f, n = u(), e = c(!1), r = o(() => {
12
- i || e.current || (e.current = !0, n.start({
13
- scale: a,
14
- transition: t
15
- }).then(() => n.start({
16
- scale: 1,
17
- transition: t
18
- })).finally(() => {
19
- e.current = !1;
20
- }));
21
- }, [
22
- n,
23
- i,
24
- a,
25
- t
26
- ]);
27
- return {
28
- pulse: r,
29
- motionProps: {
30
- initial: !1,
31
- animate: n,
32
- onPointerDown: o((l) => {
33
- l.button === 0 && r();
34
- }, [r])
35
- }
36
- };
37
- }
38
- export {
39
- f as n,
40
- R as r,
41
- p as t
42
- };
43
-
44
- //# sourceMappingURL=use-press-pulse-CMwPTOR2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-press-pulse-CMwPTOR2.js","names":[],"sources":["../../src/utils/use-press-pulse.ts"],"sourcesContent":["import { useCallback, useRef } from \"react\";\nimport { useAnimationControls, type Transition } from \"motion/react\";\n\n/**\n * Press pulse for selection controls (Select trigger, Checkbox…) — the same\n * spring family as Button's effect press, with one deliberate difference:\n * Button compresses only while held (`whileTap`); these controls play ONE\n * FULL pulse (press in → spring back) from the moment of pointer-down, even\n * if the pointer lifts early — a discrete \"it took\" tick, kept shallow and\n * quick so it registers without drawing attention.\n */\nexport const CONTROL_PRESS_SPRING = {\n type: \"spring\",\n stiffness: 700,\n damping: 32,\n mass: 0.06,\n} as const;\n\n/** Default pulse depth — shallow; each control can tune its own. */\nexport const CONTROL_PRESS_SCALE = 0.96;\n\n/**\n * One-shot scale pulse driven by Motion controls. Spread `motionProps` onto a\n * `motion.*` element (via Base UI `render`): pointer-down (primary button)\n * plays press → rest in full; re-presses during the pulse are coalesced.\n */\nexport function usePressPulse(opts?: {\n scale?: number;\n disabled?: boolean;\n /** Spring override for both legs of the pulse. @default CONTROL_PRESS_SPRING */\n transition?: Transition;\n}) {\n const scale = opts?.scale ?? CONTROL_PRESS_SCALE;\n const disabled = opts?.disabled ?? false;\n const transition = opts?.transition ?? CONTROL_PRESS_SPRING;\n const controls = useAnimationControls();\n const running = useRef(false);\n\n const pulse = useCallback(() => {\n if (disabled || running.current) return;\n running.current = true;\n void controls\n .start({ scale, transition })\n .then(() => controls.start({ scale: 1, transition }))\n .finally(() => {\n running.current = false;\n });\n }, [controls, disabled, scale, transition]);\n\n const onPointerDown = useCallback(\n (event: { button: number }) => {\n if (event.button === 0) pulse();\n },\n [pulse],\n );\n\n return {\n pulse,\n motionProps: { initial: false as const, animate: controls, onPointerDown },\n };\n}\n"],"mappings":";;;AAWA,IAAa,IAAuB;AAAA,EAClC,MAAM;AAAA,EACN,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM;AACR,GAGa,IAAsB;AAOnC,SAAgB,EAAc,GAK3B;AACD,QAAM,IAAQ,GAAM,SAAA,MACd,IAAW,GAAM,YAAY,IAC7B,IAAa,GAAM,cAAc,GACjC,IAAW,EAAqB,GAChC,IAAU,EAAO,EAAK,GAEtB,IAAQ,EAAA,MAAkB;AAC9B,IAAI,KAAY,EAAQ,YACxB,EAAQ,UAAU,IAClB,EACG,MAAM;AAAA,MAAE,OAAA;AAAA,MAAO,YAAA;AAAA,IAAW,CAAC,EAC3B,KAAA,MAAW,EAAS,MAAM;AAAA,MAAE,OAAO;AAAA,MAAG,YAAA;AAAA,IAAW,CAAC,CAAC,EACnD,QAAA,MAAc;AACb,MAAA,EAAQ,UAAU;AAAA,IACpB,CAAC;AAAA,EACL,GAAG;AAAA,IAAC;AAAA,IAAU;AAAA,IAAU;AAAA,IAAO;AAAA,EAAU,CAAC;AAS1C,SAAO;AAAA,IACL,OAAA;AAAA,IACA,aAAa;AAAA,MAAE,SAAS;AAAA,MAAgB,SAAS;AAAA,MAAU,eATvC,EAAA,CACnB,MAA8B;AAC7B,QAAI,EAAM,WAAW,KAAG,EAAM;AAAA,MAChC,GACA,CAAC,CAAK,CAKqD;AAAA,IAAc;AAAA,EAC3E;AACF"}