@nebutra/ui 0.2.1 → 0.2.2

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 (55) hide show
  1. package/LICENSE +21 -676
  2. package/README.md +81 -86
  3. package/dist/agent/index.d.ts +119 -0
  4. package/dist/agent/index.js +135 -0
  5. package/dist/agent/index.js.map +1 -0
  6. package/dist/canonical-CrO71UPO.d.ts +4058 -0
  7. package/dist/components/index.d.ts +51 -56
  8. package/dist/components/index.js +1467 -1160
  9. package/dist/components/index.js.map +1 -1
  10. package/dist/hooks/index.d.ts +62 -15
  11. package/dist/hooks/index.js +56 -34
  12. package/dist/hooks/index.js.map +1 -1
  13. package/dist/index-CKLIGfiU.d.ts +19 -0
  14. package/dist/index-Dg4jRJV2.d.ts +57 -0
  15. package/dist/layout/index.d.ts +5 -1
  16. package/dist/layout/index.js +427 -533
  17. package/dist/layout/index.js.map +1 -1
  18. package/dist/layouts/index.js +11 -9
  19. package/dist/layouts/index.js.map +1 -1
  20. package/dist/patterns/index.d.ts +128 -2
  21. package/dist/patterns/index.js +1478 -786
  22. package/dist/patterns/index.js.map +1 -1
  23. package/dist/primitives/canonical.d.ts +25 -0
  24. package/dist/primitives/canonical.js +11903 -0
  25. package/dist/primitives/canonical.js.map +1 -0
  26. package/dist/primitives/index.d.ts +577 -3545
  27. package/dist/primitives/index.js +8002 -6159
  28. package/dist/primitives/index.js.map +1 -1
  29. package/dist/shared/animation/css/index.d.ts +1 -0
  30. package/dist/shared/animation/css/index.js +14 -0
  31. package/dist/shared/animation/css/index.js.map +1 -0
  32. package/dist/shared/animation/index.d.ts +6 -0
  33. package/dist/shared/animation/index.js +272 -0
  34. package/dist/shared/animation/index.js.map +1 -0
  35. package/dist/shared/animation/motion/index.d.ts +4 -0
  36. package/dist/shared/animation/motion/index.js +205 -0
  37. package/dist/shared/animation/motion/index.js.map +1 -0
  38. package/dist/styles/brand-override.css +11 -11
  39. package/dist/tailwind.preset.d.ts +10 -10
  40. package/dist/tailwind.preset.js +7 -4
  41. package/dist/tailwind.preset.js.map +1 -1
  42. package/dist/theme/index.d.ts +2 -2
  43. package/dist/tokens-EAC6uPem.d.ts +302 -0
  44. package/dist/typography/fonts.css +31 -12
  45. package/dist/typography/index.d.ts +27 -27
  46. package/dist/typography/index.js +24 -4
  47. package/dist/typography/index.js.map +1 -1
  48. package/dist/utils/index.d.ts +36 -14
  49. package/dist/utils/index.js +44 -10
  50. package/dist/utils/index.js.map +1 -1
  51. package/package.json +38 -12
  52. package/src/styles/brand-override.css +61 -0
  53. package/src/styles/preset.css +29 -0
  54. package/src/styles/sources.css +27 -0
  55. package/src/typography/fonts.css +129 -0
@@ -1,8 +1,9 @@
1
- import { HTMLMotionProps } from 'framer-motion';
2
1
  import * as React from 'react';
3
2
  import { RefObject } from 'react';
3
+ import { HTMLMotionProps } from 'framer-motion';
4
4
 
5
- interface DwellHintProps extends Omit<HTMLMotionProps<"div">, "children" | "initial" | "animate" | "exit" | "transition"> {
5
+ type DwellHintPosition = "top" | "bottom" | "center";
6
+ interface DwellHintProps extends Omit<HTMLMotionProps<"div">, "children" | "initial" | "animate" | "exit" | "transition" | "position"> {
6
7
  /** Whether the hint is visible */
7
8
  show: boolean;
8
9
  /** The hint message to display */
@@ -10,27 +11,73 @@ interface DwellHintProps extends Omit<HTMLMotionProps<"div">, "children" | "init
10
11
  /** Optional icon to display before the message */
11
12
  icon?: React.ReactNode;
12
13
  /** Position of the hint relative to content (default: "bottom") */
13
- position?: "top" | "bottom" | "center";
14
+ position?: DwellHintPosition;
14
15
  }
16
+ declare const DwellHint: React.ForwardRefExoticComponent<Omit<DwellHintProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
17
+
15
18
  /**
16
- * DwellHint - A contextual hint that appears when user dwells on content.
19
+ * Debounced Refresh Hook
17
20
  *
18
- * Use with useScrollDwell hook to show helpful messages when users
19
- * pause scrolling and appear to be reading content.
21
+ * Wraps usehooks-ts (already a workspace dependency) so the rest of the
22
+ * monorepo gets a single canonical debounced hook surface:
23
+ * - cancellable
24
+ * - configurable delay
25
+ * - leading / trailing modes
26
+ */
27
+ type DebouncedRefreshResult = {
28
+ schedule: () => void;
29
+ cancel: () => void;
30
+ isPending: () => boolean;
31
+ flush: () => void;
32
+ };
33
+ /**
34
+ * 防抖刷新 Hook
35
+ *
36
+ * 用于限制频繁触发的刷新操作
37
+ *
38
+ * @param callback - 要执行的回调函数
39
+ * @param delay - 延迟时间 (毫秒)
40
+ * @returns 控制对象 { schedule, cancel, isPending, flush }
20
41
  *
21
42
  * @example
22
- * const { hasTriggered } = useScrollDwell(sectionRef, { threshold: 1000 });
43
+ * const { schedule, cancel } = useDebouncedRefresh(() => {
44
+ * refetch();
45
+ * }, 400);
23
46
  *
24
- * <DwellHint
25
- * show={hasTriggered}
26
- * message="This is why production-ready matters."
27
- * icon={<Lightbulb className="w-4 h-4" />}
28
- * />
47
+ * // 在数据变化时调用
48
+ * useEffect(() => {
49
+ * schedule();
50
+ * }, [data]);
29
51
  */
30
- declare const DwellHint: React.ForwardRefExoticComponent<Omit<DwellHintProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
52
+ declare function useDebouncedRefresh(callback: () => void, delay?: number): DebouncedRefreshResult;
53
+ /**
54
+ * 防抖值 Hook
55
+ *
56
+ * Thin wrapper over usehooks-ts useDebounceValue so consumers can import
57
+ * the canonical hook from @nebutra/ui/hooks alongside useDebouncedRefresh.
58
+ *
59
+ * @param value - 要防抖的值
60
+ * @param delay - 延迟时间 (毫秒)
61
+ * @returns 防抖后的值
62
+ *
63
+ * @example
64
+ * const [searchTerm, setSearchTerm] = useState("");
65
+ * const debouncedSearch = useDebouncedValue(searchTerm, 300);
66
+ *
67
+ * useEffect(() => {
68
+ * if (debouncedSearch) {
69
+ * performSearch(debouncedSearch);
70
+ * }
71
+ * }, [debouncedSearch]);
72
+ */
73
+ declare function useDebouncedValue<T>(value: T, delay?: number): T;
31
74
 
32
75
  /**
33
- * Hook to detect media query matches
76
+ * Hook to detect media query matches.
77
+ *
78
+ * Delegates to usehooks-ts `useMediaQuery` with `initializeWithValue: false`
79
+ * so the initial render always returns `false` — SSR-safe, matching the
80
+ * previous hand-rolled behaviour (no `window` access during SSR/hydration).
34
81
  *
35
82
  * @example
36
83
  * ```tsx
@@ -103,4 +150,4 @@ interface DwellState {
103
150
  */
104
151
  declare function useScrollDwell(ref: RefObject<HTMLElement | null>, config?: DwellConfig): DwellState;
105
152
 
106
- export { type DwellConfig, DwellHint, type DwellHintProps, type DwellState, useMediaQuery, useReducedMotion, useScrollDwell };
153
+ export { type DwellConfig, DwellHint, type DwellHintProps, type DwellState, useDebouncedRefresh, useDebouncedValue, useMediaQuery, useReducedMotion, useScrollDwell };
@@ -1,39 +1,42 @@
1
1
  "use client";
2
- import { AnimatePresence, motion, useReducedMotion as useReducedMotion$1 } from 'framer-motion';
3
- import * as React2 from 'react';
4
- import { useState, useRef, useCallback, useEffect } from 'react';
2
+ import * as React from 'react';
3
+ import { useRef, useEffect, useCallback, useState } from 'react';
4
+ import { useReducedMotion, AnimatePresence, motion } from 'framer-motion';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
7
  import { jsx, jsxs } from 'react/jsx-runtime';
8
+ import { useDebounceCallback, useDebounceValue, useMediaQuery as useMediaQuery$1 } from 'usehooks-ts';
8
9
 
9
10
  // src/hooks/DwellHint.tsx
10
11
  function cn(...inputs) {
11
12
  return twMerge(clsx(inputs));
12
13
  }
13
- var DwellHint = React2.forwardRef(
14
+ var POSITION_CLASSES = {
15
+ top: "top-0 -translate-y-full mb-2",
16
+ bottom: "bottom-0 translate-y-full mt-2",
17
+ center: "top-1/2 -translate-y-1/2"
18
+ };
19
+ var DwellHint = React.forwardRef(
14
20
  ({ show, message, icon, position = "bottom", className, ...props }, ref) => {
15
- const positionClasses = {
16
- top: "top-0 -translate-y-full mb-2",
17
- bottom: "bottom-0 translate-y-full mt-2",
18
- center: "top-1/2 -translate-y-1/2"
19
- };
20
- return /* @__PURE__ */ jsx(AnimatePresence, { children: show && /* @__PURE__ */ jsx(
21
+ const shouldReduceMotion = useReducedMotion();
22
+ const resolvedPosition = position ?? "bottom";
23
+ return /* @__PURE__ */ jsx(AnimatePresence, { initial: !shouldReduceMotion, children: show && /* @__PURE__ */ jsx(
21
24
  motion.div,
22
25
  {
23
26
  ref,
24
27
  className: cn(
25
28
  "absolute left-1/2 -translate-x-1/2 z-10",
26
- positionClasses[position],
29
+ POSITION_CLASSES[resolvedPosition],
27
30
  className
28
31
  ),
29
- initial: {
32
+ initial: shouldReduceMotion ? { opacity: 1 } : {
30
33
  opacity: 0,
31
- y: position === "top" ? -10 : 10,
34
+ y: resolvedPosition === "top" ? -10 : 10,
32
35
  scale: 0.95
33
36
  },
34
- animate: { opacity: 1, y: 0, scale: 1 },
35
- exit: { opacity: 0, y: position === "top" ? -5 : 5, scale: 0.98 },
36
- transition: {
37
+ animate: shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0, scale: 1 },
38
+ exit: shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: resolvedPosition === "top" ? -5 : 5, scale: 0.98 },
39
+ transition: shouldReduceMotion ? { duration: 0 } : {
37
40
  duration: 0.4,
38
41
  ease: [0.34, 1.56, 0.64, 1]
39
42
  },
@@ -59,25 +62,44 @@ var DwellHint = React2.forwardRef(
59
62
  }
60
63
  );
61
64
  DwellHint.displayName = "DwellHint";
65
+ function useDebouncedRefresh(callback, delay = 400) {
66
+ const callbackRef = useRef(callback);
67
+ useEffect(() => {
68
+ callbackRef.current = callback;
69
+ }, [callback]);
70
+ const debounced = useDebounceCallback(
71
+ () => {
72
+ callbackRef.current();
73
+ },
74
+ delay,
75
+ { leading: false, trailing: true }
76
+ );
77
+ const schedule = useCallback(() => {
78
+ debounced();
79
+ }, [debounced]);
80
+ const cancel = useCallback(() => {
81
+ debounced.cancel();
82
+ }, [debounced]);
83
+ const isPending = useCallback(() => {
84
+ return debounced.isPending();
85
+ }, [debounced]);
86
+ const flush = useCallback(() => {
87
+ debounced.flush();
88
+ }, [debounced]);
89
+ useEffect(() => cancel, [cancel]);
90
+ return { schedule, cancel, isPending, flush };
91
+ }
92
+ function useDebouncedValue(value, delay = 500) {
93
+ const [debouncedValue] = useDebounceValue(value, delay);
94
+ return debouncedValue;
95
+ }
62
96
  function useMediaQuery(query) {
63
- const [matches, setMatches] = React2.useState(false);
64
- React2.useEffect(() => {
65
- const media = window.matchMedia(query);
66
- if (media.matches !== matches) {
67
- setMatches(media.matches);
68
- }
69
- const listener = (event) => {
70
- setMatches(event.matches);
71
- };
72
- media.addEventListener("change", listener);
73
- return () => {
74
- media.removeEventListener("change", listener);
75
- };
76
- }, [matches, query]);
77
- return matches;
97
+ return useMediaQuery$1(query, { initializeWithValue: false });
78
98
  }
79
- function useReducedMotion() {
80
- return useReducedMotion$1() ?? false;
99
+
100
+ // src/hooks/use-reduced-motion.ts
101
+ function useReducedMotion2() {
102
+ return useReducedMotion() ?? false;
81
103
  }
82
104
  function useScrollDwell(ref, config = {}) {
83
105
  const { threshold = 800, cooldown = 5e3, onDwell, requireVisible = true } = config;
@@ -177,6 +199,6 @@ function useScrollDwell(ref, config = {}) {
177
199
  };
178
200
  }
179
201
 
180
- export { DwellHint, useMediaQuery, useReducedMotion, useScrollDwell };
202
+ export { DwellHint, useDebouncedRefresh, useDebouncedValue, useMediaQuery, useReducedMotion2 as useReducedMotion, useScrollDwell };
181
203
  //# sourceMappingURL=index.js.map
182
204
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/cn.ts","../../src/hooks/DwellHint.tsx","../../src/hooks/use-media-query.ts","../../src/hooks/use-reduced-motion.ts","../../src/hooks/useScrollDwell.ts"],"names":["React","useFramerReducedMotion","useState","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport { AnimatePresence, type HTMLMotionProps, motion } from \"framer-motion\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface DwellHintProps\n extends Omit<HTMLMotionProps<\"div\">, \"children\" | \"initial\" | \"animate\" | \"exit\" | \"transition\"> {\n /** Whether the hint is visible */\n show: boolean;\n /** The hint message to display */\n message: string;\n /** Optional icon to display before the message */\n icon?: React.ReactNode;\n /** Position of the hint relative to content (default: \"bottom\") */\n position?: \"top\" | \"bottom\" | \"center\";\n}\n\n/**\n * DwellHint - A contextual hint that appears when user dwells on content.\n *\n * Use with useScrollDwell hook to show helpful messages when users\n * pause scrolling and appear to be reading content.\n *\n * @example\n * const { hasTriggered } = useScrollDwell(sectionRef, { threshold: 1000 });\n *\n * <DwellHint\n * show={hasTriggered}\n * message=\"This is why production-ready matters.\"\n * icon={<Lightbulb className=\"w-4 h-4\" />}\n * />\n */\nexport const DwellHint = React.forwardRef<HTMLDivElement, DwellHintProps>(\n ({ show, message, icon, position = \"bottom\", className, ...props }, ref) => {\n const positionClasses = {\n top: \"top-0 -translate-y-full mb-2\",\n bottom: \"bottom-0 translate-y-full mt-2\",\n center: \"top-1/2 -translate-y-1/2\",\n };\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n ref={ref}\n className={cn(\n \"absolute left-1/2 -translate-x-1/2 z-10\",\n positionClasses[position],\n className,\n )}\n initial={{\n opacity: 0,\n y: position === \"top\" ? -10 : 10,\n scale: 0.95,\n }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: position === \"top\" ? -5 : 5, scale: 0.98 }}\n transition={{\n duration: 0.4,\n ease: [0.34, 1.56, 0.64, 1],\n }}\n {...props}\n >\n <div\n className={cn(\n \"flex items-center gap-2 px-4 py-2.5\",\n \"bg-background/95 backdrop-blur-md\",\n \"border border-border/50 rounded-[var(--radius-lg)]\",\n \"shadow-lg shadow-black/5\",\n \"text-sm text-muted-foreground\",\n )}\n >\n {icon && <span className=\"text-primary/70 shrink-0\">{icon}</span>}\n <span>{message}</span>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n );\n },\n);\n\nDwellHint.displayName = \"DwellHint\";\n","import * as React from \"react\";\n\n/**\n * Hook to detect media query matches\n *\n * @example\n * ```tsx\n * const isMobile = useMediaQuery(\"(max-width: 768px)\");\n * const prefersDark = useMediaQuery(\"(prefers-color-scheme: dark)\");\n * ```\n */\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = React.useState(false);\n\n React.useEffect(() => {\n const media = window.matchMedia(query);\n\n // Set initial value\n if (media.matches !== matches) {\n setMatches(media.matches);\n }\n\n // Create listener\n const listener = (event: MediaQueryListEvent) => {\n setMatches(event.matches);\n };\n\n // Add listener\n media.addEventListener(\"change\", listener);\n\n // Cleanup\n return () => {\n media.removeEventListener(\"change\", listener);\n };\n }, [matches, query]);\n\n return matches;\n}\n","\"use client\";\n\nimport { useReducedMotion as useFramerReducedMotion } from \"framer-motion\";\n\n/**\n * Returns true if the user has enabled prefers-reduced-motion.\n * Use this to disable animations, skip transitions, or simplify motion.\n *\n * Wraps framer-motion's `useReducedMotion` so callers don't need framer-motion\n * as a direct import just for accessibility checks.\n *\n * @example\n * const shouldReduce = useReducedMotion();\n * const transition = shouldReduce ? { duration: 0 } : brandSpring.default;\n */\nexport function useReducedMotion(): boolean {\n return useFramerReducedMotion() ?? false;\n}\n","\"use client\";\n\nimport { type RefObject, useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface DwellConfig {\n /** Time in ms before dwell is triggered (default: 800) */\n threshold?: number;\n /** Cooldown in ms between triggers (default: 5000) */\n cooldown?: number;\n /** Callback when dwell is detected */\n onDwell?: () => void;\n /** Only trigger when element is in viewport (default: true) */\n requireVisible?: boolean;\n}\n\nexport interface DwellState {\n /** Whether the user is currently dwelling */\n isDwelling: boolean;\n /** Progress toward trigger threshold (0-1) */\n dwellProgress: number;\n /** Whether dwell was triggered (resets after cooldown) */\n hasTriggered: boolean;\n /** Manually reset the triggered state */\n reset: () => void;\n}\n\n/**\n * useScrollDwell - Detects when a user pauses scrolling over an element.\n *\n * This hook monitors scroll activity and detects \"dwell\" behavior where\n * the user stops scrolling for a specified duration. Useful for showing\n * contextual hints, tooltips, or triggering animations when a user\n * appears to be reading or studying content.\n *\n * @param ref - Reference to the element to monitor\n * @param config - Configuration options\n * @returns DwellState object with current dwell status\n *\n * @example\n * function FeatureSection() {\n * const sectionRef = useRef<HTMLDivElement>(null);\n * const { isDwelling, hasTriggered } = useScrollDwell(sectionRef, {\n * threshold: 1000,\n * cooldown: 10000,\n * onDwell: () => console.log(\"User is reading this section\"),\n * });\n *\n * return (\n * <div ref={sectionRef}>\n * {hasTriggered && <DwellHint message=\"Take a closer look!\" />}\n * </div>\n * );\n * }\n */\nexport function useScrollDwell(\n ref: RefObject<HTMLElement | null>,\n config: DwellConfig = {},\n): DwellState {\n const { threshold = 800, cooldown = 5000, onDwell, requireVisible = true } = config;\n\n const [isDwelling, setIsDwelling] = useState(false);\n const [dwellProgress, setDwellProgress] = useState(0);\n const [hasTriggered, setHasTriggered] = useState(false);\n\n const dwellTimerRef = useRef<NodeJS.Timeout | null>(null);\n const progressIntervalRef = useRef<NodeJS.Timeout | null>(null);\n const cooldownTimerRef = useRef<NodeJS.Timeout | null>(null);\n const lastScrollTimeRef = useRef<number>(Date.now());\n const isInCooldownRef = useRef(false);\n\n const clearTimers = useCallback(() => {\n if (dwellTimerRef.current) {\n clearTimeout(dwellTimerRef.current);\n dwellTimerRef.current = null;\n }\n if (progressIntervalRef.current) {\n clearInterval(progressIntervalRef.current);\n progressIntervalRef.current = null;\n }\n }, []);\n\n const reset = useCallback(() => {\n setHasTriggered(false);\n setIsDwelling(false);\n setDwellProgress(0);\n isInCooldownRef.current = false;\n if (cooldownTimerRef.current) {\n clearTimeout(cooldownTimerRef.current);\n cooldownTimerRef.current = null;\n }\n }, []);\n\n const isElementVisible = useCallback(() => {\n if (!ref.current) return false;\n const rect = ref.current.getBoundingClientRect();\n const windowHeight = window.innerHeight;\n\n // Element is visible if at least 50% is in viewport\n const visibleHeight = Math.min(rect.bottom, windowHeight) - Math.max(rect.top, 0);\n const elementHeight = rect.height;\n\n return visibleHeight / elementHeight > 0.5;\n }, [ref]);\n\n const startDwellTimer = useCallback(() => {\n if (isInCooldownRef.current || hasTriggered) return;\n if (requireVisible && !isElementVisible()) return;\n\n clearTimers();\n\n // Start progress tracking\n const startTime = Date.now();\n progressIntervalRef.current = setInterval(() => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / threshold, 1);\n setDwellProgress(progress);\n\n if (progress >= 1) {\n if (progressIntervalRef.current) clearInterval(progressIntervalRef.current);\n }\n }, 50);\n\n // Set up dwell trigger\n dwellTimerRef.current = setTimeout(() => {\n setIsDwelling(true);\n setHasTriggered(true);\n onDwell?.();\n\n // Start cooldown\n isInCooldownRef.current = true;\n cooldownTimerRef.current = setTimeout(() => {\n isInCooldownRef.current = false;\n setHasTriggered(false);\n setDwellProgress(0);\n }, cooldown);\n }, threshold);\n }, [threshold, cooldown, onDwell, requireVisible, hasTriggered, isElementVisible, clearTimers]);\n\n const handleScroll = useCallback(() => {\n lastScrollTimeRef.current = Date.now();\n setIsDwelling(false);\n setDwellProgress(0);\n clearTimers();\n\n // Restart dwell detection after a short delay\n setTimeout(() => {\n const timeSinceScroll = Date.now() - lastScrollTimeRef.current;\n if (timeSinceScroll >= 100) {\n startDwellTimer();\n }\n }, 100);\n }, [clearTimers, startDwellTimer]);\n\n useEffect(() => {\n window.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n // Start initial dwell timer if element is already visible\n if (requireVisible && isElementVisible()) {\n startDwellTimer();\n } else if (!requireVisible) {\n startDwellTimer();\n }\n\n return () => {\n window.removeEventListener(\"scroll\", handleScroll);\n clearTimers();\n if (cooldownTimerRef.current) {\n clearTimeout(cooldownTimerRef.current);\n }\n };\n }, [handleScroll, startDwellTimer, requireVisible, isElementVisible, clearTimers]);\n\n return {\n isDwelling,\n dwellProgress,\n hasTriggered,\n reset,\n };\n}\n\nexport default useScrollDwell;\n"]}
1
+ {"version":3,"sources":["../../src/utils/cn.ts","../../src/hooks/DwellHint.tsx","../../src/hooks/use-debounced-refresh.ts","../../src/hooks/use-media-query.ts","../../src/hooks/use-reduced-motion.ts","../../src/hooks/useScrollDwell.ts"],"names":["useMediaQueryBase","useReducedMotion","useRef","useCallback","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport {\n AnimatePresence,\n type HTMLMotionProps,\n motion,\n useReducedMotion,\n} from \"../shared/animation/motion\";\nimport { cn } from \"../utils/cn\";\n\nexport type DwellHintPosition = \"top\" | \"bottom\" | \"center\";\n\nexport interface DwellHintProps\n extends Omit<\n HTMLMotionProps<\"div\">,\n \"children\" | \"initial\" | \"animate\" | \"exit\" | \"transition\" | \"position\"\n > {\n /** Whether the hint is visible */\n show: boolean;\n /** The hint message to display */\n message: string;\n /** Optional icon to display before the message */\n icon?: React.ReactNode;\n /** Position of the hint relative to content (default: \"bottom\") */\n position?: DwellHintPosition;\n}\n\n/**\n * DwellHint - A contextual hint that appears when user dwells on content.\n *\n * Use with useScrollDwell hook to show helpful messages when users\n * pause scrolling and appear to be reading content.\n *\n * @example\n * const { hasTriggered } = useScrollDwell(sectionRef, { threshold: 1000 });\n *\n * <DwellHint\n * show={hasTriggered}\n * message=\"This is why production-ready matters.\"\n * icon={<Lightbulb className=\"w-4 h-4\" />}\n * />\n */\nconst POSITION_CLASSES: Record<DwellHintPosition, string> = {\n top: \"top-0 -translate-y-full mb-2\",\n bottom: \"bottom-0 translate-y-full mt-2\",\n center: \"top-1/2 -translate-y-1/2\",\n};\n\nexport const DwellHint = React.forwardRef<HTMLDivElement, DwellHintProps>(\n ({ show, message, icon, position = \"bottom\", className, ...props }, ref) => {\n const shouldReduceMotion = useReducedMotion();\n // Narrow after destructure: HTMLMotionProps intersections can widen\n // `position` to `any` under tsup DTS emit, which then fails TS7053.\n const resolvedPosition: DwellHintPosition = position ?? \"bottom\";\n\n return (\n <AnimatePresence initial={!shouldReduceMotion}>\n {show && (\n <motion.div\n ref={ref}\n className={cn(\n \"absolute left-1/2 -translate-x-1/2 z-10\",\n POSITION_CLASSES[resolvedPosition],\n className,\n )}\n initial={\n shouldReduceMotion\n ? { opacity: 1 }\n : {\n opacity: 0,\n y: resolvedPosition === \"top\" ? -10 : 10,\n scale: 0.95,\n }\n }\n animate={shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0, scale: 1 }}\n exit={\n shouldReduceMotion\n ? { opacity: 0 }\n : { opacity: 0, y: resolvedPosition === \"top\" ? -5 : 5, scale: 0.98 }\n }\n transition={\n shouldReduceMotion\n ? { duration: 0 }\n : {\n duration: 0.4,\n ease: [0.34, 1.56, 0.64, 1],\n }\n }\n {...props}\n >\n <div\n className={cn(\n \"flex items-center gap-2 px-4 py-2.5\",\n \"bg-background/95 backdrop-blur-md\",\n \"border border-border/50 rounded-[var(--radius-lg)]\",\n \"shadow-lg shadow-black/5\",\n \"text-sm text-muted-foreground\",\n )}\n >\n {icon && <span className=\"text-primary/70 shrink-0\">{icon}</span>}\n <span>{message}</span>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n );\n },\n);\n\nDwellHint.displayName = \"DwellHint\";\n","/**\n * Debounced Refresh Hook\n *\n * Wraps usehooks-ts (already a workspace dependency) so the rest of the\n * monorepo gets a single canonical debounced hook surface:\n * - cancellable\n * - configurable delay\n * - leading / trailing modes\n */\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport { useDebounceCallback, useDebounceValue } from \"usehooks-ts\";\n\ntype DebouncedRefreshResult = {\n schedule: () => void;\n cancel: () => void;\n isPending: () => boolean;\n flush: () => void;\n};\n\n/**\n * 防抖刷新 Hook\n *\n * 用于限制频繁触发的刷新操作\n *\n * @param callback - 要执行的回调函数\n * @param delay - 延迟时间 (毫秒)\n * @returns 控制对象 { schedule, cancel, isPending, flush }\n *\n * @example\n * const { schedule, cancel } = useDebouncedRefresh(() => {\n * refetch();\n * }, 400);\n *\n * // 在数据变化时调用\n * useEffect(() => {\n * schedule();\n * }, [data]);\n */\nexport function useDebouncedRefresh(callback: () => void, delay = 400): DebouncedRefreshResult {\n const callbackRef = useRef(callback);\n\n // 保持回调引用最新\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n // 使用 usehooks-ts 的 useDebounceCallback\n const debounced = useDebounceCallback(\n () => {\n callbackRef.current();\n },\n delay,\n { leading: false, trailing: true },\n );\n\n const schedule = useCallback(() => {\n debounced();\n }, [debounced]);\n\n const cancel = useCallback(() => {\n debounced.cancel();\n }, [debounced]);\n\n const isPending = useCallback(() => {\n return debounced.isPending();\n }, [debounced]);\n\n const flush = useCallback(() => {\n debounced.flush();\n }, [debounced]);\n\n // 组件卸载时取消\n useEffect(() => cancel, [cancel]);\n\n return { schedule, cancel, isPending, flush };\n}\n\n/**\n * 防抖值 Hook\n *\n * Thin wrapper over usehooks-ts useDebounceValue so consumers can import\n * the canonical hook from @nebutra/ui/hooks alongside useDebouncedRefresh.\n *\n * @param value - 要防抖的值\n * @param delay - 延迟时间 (毫秒)\n * @returns 防抖后的值\n *\n * @example\n * const [searchTerm, setSearchTerm] = useState(\"\");\n * const debouncedSearch = useDebouncedValue(searchTerm, 300);\n *\n * useEffect(() => {\n * if (debouncedSearch) {\n * performSearch(debouncedSearch);\n * }\n * }, [debouncedSearch]);\n */\nexport function useDebouncedValue<T>(value: T, delay = 500): T {\n const [debouncedValue] = useDebounceValue(value, delay);\n return debouncedValue;\n}\n","import { useMediaQuery as useMediaQueryBase } from \"usehooks-ts\";\n\n/**\n * Hook to detect media query matches.\n *\n * Delegates to usehooks-ts `useMediaQuery` with `initializeWithValue: false`\n * so the initial render always returns `false` — SSR-safe, matching the\n * previous hand-rolled behaviour (no `window` access during SSR/hydration).\n *\n * @example\n * ```tsx\n * const isMobile = useMediaQuery(\"(max-width: 768px)\");\n * const prefersDark = useMediaQuery(\"(prefers-color-scheme: dark)\");\n * ```\n */\nexport function useMediaQuery(query: string): boolean {\n return useMediaQueryBase(query, { initializeWithValue: false });\n}\n","\"use client\";\n\nimport { useReducedMotion as useSharedReducedMotion } from \"../shared/animation/motion\";\n\n/**\n * Returns true if the user has enabled prefers-reduced-motion.\n * Use this to disable animations, skip transitions, or simplify motion.\n *\n * Wraps framer-motion's `useReducedMotion` so callers don't need framer-motion\n * as a direct import just for accessibility checks.\n *\n * @example\n * const shouldReduce = useReducedMotion();\n * const transition = shouldReduce ? { duration: 0 } : brandSpring.default;\n */\nexport function useReducedMotion(): boolean {\n return useSharedReducedMotion() ?? false;\n}\n","\"use client\";\n\nimport { type RefObject, useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface DwellConfig {\n /** Time in ms before dwell is triggered (default: 800) */\n threshold?: number;\n /** Cooldown in ms between triggers (default: 5000) */\n cooldown?: number;\n /** Callback when dwell is detected */\n onDwell?: () => void;\n /** Only trigger when element is in viewport (default: true) */\n requireVisible?: boolean;\n}\n\nexport interface DwellState {\n /** Whether the user is currently dwelling */\n isDwelling: boolean;\n /** Progress toward trigger threshold (0-1) */\n dwellProgress: number;\n /** Whether dwell was triggered (resets after cooldown) */\n hasTriggered: boolean;\n /** Manually reset the triggered state */\n reset: () => void;\n}\n\n/**\n * useScrollDwell - Detects when a user pauses scrolling over an element.\n *\n * This hook monitors scroll activity and detects \"dwell\" behavior where\n * the user stops scrolling for a specified duration. Useful for showing\n * contextual hints, tooltips, or triggering animations when a user\n * appears to be reading or studying content.\n *\n * @param ref - Reference to the element to monitor\n * @param config - Configuration options\n * @returns DwellState object with current dwell status\n *\n * @example\n * function FeatureSection() {\n * const sectionRef = useRef<HTMLDivElement>(null);\n * const { isDwelling, hasTriggered } = useScrollDwell(sectionRef, {\n * threshold: 1000,\n * cooldown: 10000,\n * onDwell: () => console.log(\"User is reading this section\"),\n * });\n *\n * return (\n * <div ref={sectionRef}>\n * {hasTriggered && <DwellHint message=\"Take a closer look!\" />}\n * </div>\n * );\n * }\n */\nexport function useScrollDwell(\n ref: RefObject<HTMLElement | null>,\n config: DwellConfig = {},\n): DwellState {\n const { threshold = 800, cooldown = 5000, onDwell, requireVisible = true } = config;\n\n const [isDwelling, setIsDwelling] = useState(false);\n const [dwellProgress, setDwellProgress] = useState(0);\n const [hasTriggered, setHasTriggered] = useState(false);\n\n const dwellTimerRef = useRef<NodeJS.Timeout | null>(null);\n const progressIntervalRef = useRef<NodeJS.Timeout | null>(null);\n const cooldownTimerRef = useRef<NodeJS.Timeout | null>(null);\n const lastScrollTimeRef = useRef<number>(Date.now());\n const isInCooldownRef = useRef(false);\n\n const clearTimers = useCallback(() => {\n if (dwellTimerRef.current) {\n clearTimeout(dwellTimerRef.current);\n dwellTimerRef.current = null;\n }\n if (progressIntervalRef.current) {\n clearInterval(progressIntervalRef.current);\n progressIntervalRef.current = null;\n }\n }, []);\n\n const reset = useCallback(() => {\n setHasTriggered(false);\n setIsDwelling(false);\n setDwellProgress(0);\n isInCooldownRef.current = false;\n if (cooldownTimerRef.current) {\n clearTimeout(cooldownTimerRef.current);\n cooldownTimerRef.current = null;\n }\n }, []);\n\n const isElementVisible = useCallback(() => {\n if (!ref.current) return false;\n const rect = ref.current.getBoundingClientRect();\n const windowHeight = window.innerHeight;\n\n // Element is visible if at least 50% is in viewport\n const visibleHeight = Math.min(rect.bottom, windowHeight) - Math.max(rect.top, 0);\n const elementHeight = rect.height;\n\n return visibleHeight / elementHeight > 0.5;\n }, [ref]);\n\n const startDwellTimer = useCallback(() => {\n if (isInCooldownRef.current || hasTriggered) return;\n if (requireVisible && !isElementVisible()) return;\n\n clearTimers();\n\n // Start progress tracking\n const startTime = Date.now();\n progressIntervalRef.current = setInterval(() => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / threshold, 1);\n setDwellProgress(progress);\n\n if (progress >= 1) {\n if (progressIntervalRef.current) clearInterval(progressIntervalRef.current);\n }\n }, 50);\n\n // Set up dwell trigger\n dwellTimerRef.current = setTimeout(() => {\n setIsDwelling(true);\n setHasTriggered(true);\n onDwell?.();\n\n // Start cooldown\n isInCooldownRef.current = true;\n cooldownTimerRef.current = setTimeout(() => {\n isInCooldownRef.current = false;\n setHasTriggered(false);\n setDwellProgress(0);\n }, cooldown);\n }, threshold);\n }, [threshold, cooldown, onDwell, requireVisible, hasTriggered, isElementVisible, clearTimers]);\n\n const handleScroll = useCallback(() => {\n lastScrollTimeRef.current = Date.now();\n setIsDwelling(false);\n setDwellProgress(0);\n clearTimers();\n\n // Restart dwell detection after a short delay\n setTimeout(() => {\n const timeSinceScroll = Date.now() - lastScrollTimeRef.current;\n if (timeSinceScroll >= 100) {\n startDwellTimer();\n }\n }, 100);\n }, [clearTimers, startDwellTimer]);\n\n useEffect(() => {\n window.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n // Start initial dwell timer if element is already visible\n if (requireVisible && isElementVisible()) {\n startDwellTimer();\n } else if (!requireVisible) {\n startDwellTimer();\n }\n\n return () => {\n window.removeEventListener(\"scroll\", handleScroll);\n clearTimers();\n if (cooldownTimerRef.current) {\n clearTimeout(cooldownTimerRef.current);\n }\n };\n }, [handleScroll, startDwellTimer, requireVisible, isElementVisible, clearTimers]);\n\n return {\n isDwelling,\n dwellProgress,\n hasTriggered,\n reset,\n };\n}\n\nexport default useScrollDwell;\n"]}
@@ -0,0 +1,19 @@
1
+ declare const cssTransition: {
2
+ readonly color: "transition-colors duration-micro ease-out motion-reduce:transition-none";
3
+ readonly background: "transition-colors duration-micro ease-out motion-reduce:transition-none";
4
+ readonly border: "transition-colors duration-micro ease-out motion-reduce:transition-none";
5
+ readonly shadow: "transition-shadow duration-flow ease-out motion-reduce:transition-none";
6
+ readonly opacity: "transition-opacity duration-micro ease-out motion-reduce:transition-none";
7
+ readonly transform: "transition-transform duration-flow ease-out motion-reduce:transition-none";
8
+ };
9
+ declare const interactiveCssTransition = "transition-[color,background-color,border-color,box-shadow,opacity,transform] duration-flow ease-out motion-reduce:transition-none";
10
+ type CssTransition = keyof typeof cssTransition;
11
+
12
+ type index_CssTransition = CssTransition;
13
+ declare const index_cssTransition: typeof cssTransition;
14
+ declare const index_interactiveCssTransition: typeof interactiveCssTransition;
15
+ declare namespace index {
16
+ export { type index_CssTransition as CssTransition, index_cssTransition as cssTransition, index_interactiveCssTransition as interactiveCssTransition };
17
+ }
18
+
19
+ export { type CssTransition as C, interactiveCssTransition as a, cssTransition as c, index as i };
@@ -0,0 +1,57 @@
1
+ import { AnimatePresence, HTMLMotionProps, LayoutGroup, LazyMotion, MotionConfig, MotionProps, MotionStyle, MotionValue, Transition, Variants, animate, domAnimation, m, motion, useAnimationFrame, useInView, useMotionTemplate, useMotionValue, useReducedMotion, useScroll, useSpring, useTransform, useVelocity } from 'framer-motion';
2
+ import { A as AnimatedCard, a as AnimatedDrawer, b as AnimatedList, c as AnimatedModal, d as AnimatedPopover, e as AnimationDuration, f as AnimationTransition, F as FadeIn, P as PageTransition, S as ScaleIn, g as SlideIn, h as animatedList, i as animatedListItem, j as animationDistances, k as animationDurations, l as animationEasings, m as animationSprings, n as animationTransitions, o as drawerSurface, p as fadeIn, q as modalSurface, r as pageTransition, s as popoverSurface, t as reducedMotionVariants, u as scaleIn, v as slideIn } from './tokens-EAC6uPem.js';
3
+
4
+ declare const index_AnimatePresence: typeof AnimatePresence;
5
+ declare const index_AnimatedCard: typeof AnimatedCard;
6
+ declare const index_AnimatedDrawer: typeof AnimatedDrawer;
7
+ declare const index_AnimatedList: typeof AnimatedList;
8
+ declare const index_AnimatedModal: typeof AnimatedModal;
9
+ declare const index_AnimatedPopover: typeof AnimatedPopover;
10
+ declare const index_AnimationDuration: typeof AnimationDuration;
11
+ declare const index_AnimationTransition: typeof AnimationTransition;
12
+ declare const index_FadeIn: typeof FadeIn;
13
+ declare const index_HTMLMotionProps: typeof HTMLMotionProps;
14
+ declare const index_LayoutGroup: typeof LayoutGroup;
15
+ declare const index_LazyMotion: typeof LazyMotion;
16
+ declare const index_MotionConfig: typeof MotionConfig;
17
+ declare const index_MotionProps: typeof MotionProps;
18
+ declare const index_MotionStyle: typeof MotionStyle;
19
+ declare const index_MotionValue: typeof MotionValue;
20
+ declare const index_PageTransition: typeof PageTransition;
21
+ declare const index_ScaleIn: typeof ScaleIn;
22
+ declare const index_SlideIn: typeof SlideIn;
23
+ declare const index_Transition: typeof Transition;
24
+ declare const index_Variants: typeof Variants;
25
+ declare const index_animate: typeof animate;
26
+ declare const index_animatedList: typeof animatedList;
27
+ declare const index_animatedListItem: typeof animatedListItem;
28
+ declare const index_animationDistances: typeof animationDistances;
29
+ declare const index_animationDurations: typeof animationDurations;
30
+ declare const index_animationEasings: typeof animationEasings;
31
+ declare const index_animationSprings: typeof animationSprings;
32
+ declare const index_animationTransitions: typeof animationTransitions;
33
+ declare const index_domAnimation: typeof domAnimation;
34
+ declare const index_drawerSurface: typeof drawerSurface;
35
+ declare const index_fadeIn: typeof fadeIn;
36
+ declare const index_m: typeof m;
37
+ declare const index_modalSurface: typeof modalSurface;
38
+ declare const index_motion: typeof motion;
39
+ declare const index_pageTransition: typeof pageTransition;
40
+ declare const index_popoverSurface: typeof popoverSurface;
41
+ declare const index_reducedMotionVariants: typeof reducedMotionVariants;
42
+ declare const index_scaleIn: typeof scaleIn;
43
+ declare const index_slideIn: typeof slideIn;
44
+ declare const index_useAnimationFrame: typeof useAnimationFrame;
45
+ declare const index_useInView: typeof useInView;
46
+ declare const index_useMotionTemplate: typeof useMotionTemplate;
47
+ declare const index_useMotionValue: typeof useMotionValue;
48
+ declare const index_useReducedMotion: typeof useReducedMotion;
49
+ declare const index_useScroll: typeof useScroll;
50
+ declare const index_useSpring: typeof useSpring;
51
+ declare const index_useTransform: typeof useTransform;
52
+ declare const index_useVelocity: typeof useVelocity;
53
+ declare namespace index {
54
+ export { index_AnimatePresence as AnimatePresence, index_AnimatedCard as AnimatedCard, index_AnimatedDrawer as AnimatedDrawer, index_AnimatedList as AnimatedList, index_AnimatedModal as AnimatedModal, index_AnimatedPopover as AnimatedPopover, index_AnimationDuration as AnimationDuration, index_AnimationTransition as AnimationTransition, index_FadeIn as FadeIn, index_HTMLMotionProps as HTMLMotionProps, index_LayoutGroup as LayoutGroup, index_LazyMotion as LazyMotion, index_MotionConfig as MotionConfig, index_MotionProps as MotionProps, index_MotionStyle as MotionStyle, index_MotionValue as MotionValue, index_PageTransition as PageTransition, index_ScaleIn as ScaleIn, index_SlideIn as SlideIn, index_Transition as Transition, index_Variants as Variants, index_animate as animate, index_animatedList as animatedList, index_animatedListItem as animatedListItem, index_animationDistances as animationDistances, index_animationDurations as animationDurations, index_animationEasings as animationEasings, index_animationSprings as animationSprings, index_animationTransitions as animationTransitions, index_domAnimation as domAnimation, index_drawerSurface as drawerSurface, index_fadeIn as fadeIn, index_m as m, index_modalSurface as modalSurface, index_motion as motion, index_pageTransition as pageTransition, index_popoverSurface as popoverSurface, index_reducedMotionVariants as reducedMotionVariants, index_scaleIn as scaleIn, index_slideIn as slideIn, index_useAnimationFrame as useAnimationFrame, index_useInView as useInView, index_useMotionTemplate as useMotionTemplate, index_useMotionValue as useMotionValue, index_useReducedMotion as useReducedMotion, index_useScroll as useScroll, index_useSpring as useSpring, index_useTransform as useTransform, index_useVelocity as useVelocity };
55
+ }
56
+
57
+ export { index as i };
@@ -22,6 +22,10 @@ interface AppShellProps {
22
22
  defaultCollapsed?: boolean;
23
23
  /** Fires whenever the collapsed state changes (both controlled + uncontrolled). */
24
24
  onCollapsedChange?: (collapsed: boolean) => void;
25
+ /** Render the desktop sidebar as a floating overlay (absolute, z-40) instead of
26
+ * an in-flow rail that compresses main — for full-bleed builder routes that
27
+ * drive their own toggle. When collapsed to 0 width it's simply invisible. */
28
+ overlay?: boolean;
25
29
  /** Height in pixels of the sticky header row. Defaults to 48. */
26
30
  headerHeight?: number;
27
31
  /** Override the default container styles applied to `<main>`. */
@@ -52,7 +56,7 @@ interface AppShellProps {
52
56
  * </AppShell>
53
57
  * ```
54
58
  */
55
- declare function AppShell({ sidebar, header, children, sidebarWidth, sidebarCollapsedWidth, collapsed, defaultCollapsed, onCollapsedChange, headerHeight, contentClassName, className, }: AppShellProps): react_jsx_runtime.JSX.Element;
59
+ declare function AppShell({ sidebar, header, children, sidebarWidth, sidebarCollapsedWidth, collapsed, defaultCollapsed, onCollapsedChange, headerHeight, contentClassName, className, overlay, }: AppShellProps): react_jsx_runtime.JSX.Element;
56
60
 
57
61
  interface CardProps {
58
62
  children: React__default.ReactNode;