@tour-kit/hints 0.2.0 → 0.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @tour-kit/hints
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add hints functionality with persistent state and improved performance optimizations
8
+
9
+ ## 0.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - ### @tour-kit/react
14
+
15
+ - Fix `Tour` component to properly render children content alongside tour steps
16
+ - Add `TourCard`, `TourOverlay`, and navigation components with Floating UI positioning
17
+ - Add primitive components: `TourPortal`, `TourArrow`
18
+
19
+ ### @tour-kit/core
20
+
21
+ - Export hooks and utilities for tour state management
22
+ - Add focus trap, keyboard navigation, and spotlight hooks
23
+
24
+ ### @tour-kit/hints
25
+
26
+ - Initial hints package setup
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies
31
+ - @tour-kit/core@0.3.0
32
+
3
33
  ## 0.2.0
4
34
 
5
35
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -1,25 +1,8 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __copyProps = (to, from, except, desc) => {
7
- if (from && typeof from === "object" || typeof from === "function") {
8
- for (let key of __getOwnPropNames(from))
9
- if (!__hasOwnProp.call(to, key) && key !== except)
10
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
- }
12
- return to;
13
- };
14
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
-
17
- // src/index.ts
18
- var index_exports = {};
19
- module.exports = __toCommonJS(index_exports);
20
- __reExport(index_exports, require("@tour-kit/core"), module.exports);
21
- // Annotate the CommonJS export names for ESM import in node:
22
- 0 && (module.exports = {
23
- ...require("@tour-kit/core")
24
- });
1
+ 'use strict';var a=require('react'),jsxRuntime=require('react/jsx-runtime'),core=require('@tour-kit/core'),react=require('@floating-ui/react');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var a__namespace=/*#__PURE__*/_interopNamespace(a);var m=a.createContext(null);m.displayName="HintsContext";function d(){let t=a.useContext(m);if(!t)throw new Error("useHintsContext must be used within a HintsProvider");return t}function U(t,e){let n=new Map(t.hints);return n.has(e)||n.set(e,{id:e,isOpen:false,isDismissed:false}),{...t,hints:n}}function z(t,e){let n=new Map(t.hints);return n.delete(e),{...t,hints:n,activeHint:t.activeHint===e?null:t.activeHint}}function B(t,e){let n=new Map(t.hints),i=n.get(e);if(i&&!i.isDismissed){if(t.activeHint&&t.activeHint!==e){let o=n.get(t.activeHint);o&&n.set(t.activeHint,{...o,isOpen:false});}return n.set(e,{...i,isOpen:true}),{hints:n,activeHint:e}}return t}function _(t,e){let n=new Map(t.hints),i=n.get(e);return i?(n.set(e,{...i,isOpen:false}),{hints:n,activeHint:t.activeHint===e?null:t.activeHint}):t}function K(t,e){let n=new Map(t.hints),i=n.get(e);return i?(n.set(e,{...i,isOpen:false,isDismissed:true}),{hints:n,activeHint:t.activeHint===e?null:t.activeHint}):t}function q(t,e){let n=new Map(t.hints),i=n.get(e);return i&&n.set(e,{...i,isDismissed:false}),{...t,hints:n}}function J(t){let e=new Map(t.hints);return e.forEach((n,i)=>{e.set(i,{...n,isDismissed:false});}),{...t,hints:e}}function Q(t,e){switch(e.type){case "REGISTER":return U(t,e.id);case "UNREGISTER":return z(t,e.id);case "SHOW":return B(t,e.id);case "HIDE":return _(t,e.id);case "DISMISS":return K(t,e.id);case "RESET":return q(t,e.id);case "RESET_ALL":return J(t);default:return t}}function X({children:t}){let[e,n]=a__namespace.useReducer(Q,{hints:new Map,activeHint:null}),i=a__namespace.useCallback(s=>n({type:"REGISTER",id:s}),[]),o=a__namespace.useCallback(s=>n({type:"UNREGISTER",id:s}),[]),p=a__namespace.useCallback(s=>n({type:"SHOW",id:s}),[]),c=a__namespace.useCallback(s=>n({type:"HIDE",id:s}),[]),l=a__namespace.useCallback(s=>n({type:"DISMISS",id:s}),[]),r=a__namespace.useCallback(s=>n({type:"RESET",id:s}),[]),H=a__namespace.useCallback(()=>n({type:"RESET_ALL"}),[]),f=a__namespace.useMemo(()=>({hints:e.hints,activeHint:e.activeHint,registerHint:i,unregisterHint:o,showHint:p,hideHint:c,dismissHint:l,resetHint:r,resetAllHints:H}),[e.hints,e.activeHint,i,o,p,c,l,r,H]);return jsxRuntime.jsx(m.Provider,{value:f,children:t})}function h(t){let{hints:e,registerHint:n,unregisterHint:i,showHint:o,hideHint:p,dismissHint:c,resetHint:l}=d(),r=e.get(t);return a.useEffect(()=>(n(t),()=>i(t)),[t,n,i]),{isOpen:r?.isOpen??false,isDismissed:r?.isDismissed??false,show:()=>o(t),hide:()=>p(t),dismiss:()=>c(t),reset:()=>l(t)}}function $(t,e){switch(t){case "top-left":return {top:e.top-4,left:e.left-4};case "top-right":return {top:e.top-4,left:e.right-4};case "bottom-left":return {top:e.bottom-4,left:e.left-4};case "bottom-right":return {top:e.bottom-4,left:e.right-4};case "center":return {top:e.top+e.height/2-6,left:e.left+e.width/2-6};default:return {top:e.top-4,left:e.right-4}}}var j=`
2
+ @keyframes tourkit-pulse {
3
+ 0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7); }
4
+ 50% { opacity: 1; box-shadow: 0 0 0 8px rgba(59, 130, 246, 0); }
5
+ }
6
+ `,g=a__namespace.forwardRef(function({targetRect:e,position:n,pulse:i=true,isOpen:o=false,onClick:p,className:c},l){let r=$(n,e);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("style",{children:j}),jsxRuntime.jsx("button",{ref:l,type:"button",onClick:p,className:c,style:{position:"fixed",zIndex:9999,top:r.top,left:r.left,width:20,height:20,borderRadius:"50%",backgroundColor:"#3b82f6",border:"3px solid #ffffff",boxShadow:"0 2px 8px rgba(0,0,0,0.3)",cursor:"pointer",padding:0,animation:i&&!o?"tourkit-pulse 1.5s ease-in-out infinite":"none"},"aria-label":"Show hint","aria-expanded":o})]})});function ft(t){return t.endsWith("-center")?t.replace("-center",""):t}function R({target:t,placement:e="bottom",children:n,onClose:i,className:o}){let p=ft(e),{refs:c,floatingStyles:l,context:r}=react.useFloating({elements:{reference:t},open:true,placement:p,middleware:[react.offset(8),react.flip(),react.shift({padding:8})],whileElementsMounted:react.autoUpdate}),H=react.useDismiss(r),f=react.useRole(r,{role:"tooltip"}),{getFloatingProps:s}=react.useInteractions([H,f]);return jsxRuntime.jsx(react.FloatingPortal,{children:jsxRuntime.jsxs("div",{ref:c.setFloating,style:{...l,zIndex:9999,maxWidth:280,borderRadius:8,border:"1px solid #e5e7eb",backgroundColor:"#ffffff",padding:12,fontSize:14,color:"#1f2937",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)"},className:o,...s(),children:[jsxRuntime.jsx("button",{type:"button",onClick:i,style:{position:"absolute",right:8,top:8,background:"none",border:"none",cursor:"pointer",padding:4,opacity:.7,borderRadius:4},"aria-label":"Dismiss hint",children:jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":"true",children:[jsxRuntime.jsx("title",{children:"Close"}),jsxRuntime.jsx("path",{d:"M18 6 6 18"}),jsxRuntime.jsx("path",{d:"m6 6 12 12"})]})}),jsxRuntime.jsx("div",{style:{paddingRight:16},children:n})]})})}function k({id:t,target:e,content:n,children:i,position:o="top-right",tooltipPlacement:p="bottom",pulse:c=true,autoShow:l=false,persist:r=false,onClick:H,onShow:f,onDismiss:s,className:I}){let{isOpen:y,isDismissed:S,show:b,hide:w,dismiss:O}=h(t),v=a__namespace.useRef(null),N=typeof e=="string"?e:null,A=typeof e=="object"?e?.current:null,{element:F,rect:C}=core.useElementPosition(N??A);a__namespace.useEffect(()=>{l&&!S&&(b(),f?.());},[l,S,b,f]);let L=()=>{H?.(),y?w():(b(),f?.());},V=()=>{r?O():w(),s?.();};return S||!F||!C?null:jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(g,{ref:v,targetRect:C,position:o,pulse:c,isOpen:y,onClick:L}),y&&v.current&&jsxRuntime.jsx(R,{target:v.current,placement:p,onClose:V,className:I,children:i??n})]})}function M(){let t=d();return {hints:Array.from(t.hints.values()),activeHint:t.activeHint,showHint:t.showHint,hideHint:t.hideHint,dismissHint:t.dismissHint,resetHint:t.resetHint,resetAllHints:t.resetAllHints,isHintVisible:e=>t.hints.get(e)?.isOpen??false,isHintDismissed:e=>t.hints.get(e)?.isDismissed??false}}
7
+ exports.Hint=k;exports.HintHotspot=g;exports.HintTooltip=R;exports.HintsContext=m;exports.HintsProvider=X;exports.useHint=h;exports.useHints=M;//# sourceMappingURL=index.cjs.map
25
8
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Re-export types from core\nexport * from '@tour-kit/core'\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA;AAAA;AACA,0BAAc,2BADd;","names":[]}
1
+ {"version":3,"sources":["../src/context/hints-context.ts","../src/context/hints-provider.tsx","../src/hooks/use-hint.ts","../src/components/hint-hotspot.tsx","../src/components/hint-tooltip.tsx","../src/components/hint.tsx","../src/hooks/use-hints.ts"],"names":["HintsContext","createContext","useHintsContext","context","useContext","handleRegister","state","id","newHints","handleUnregister","handleShow","hint","activeHint","handleHide","handleDismiss","handleReset","handleResetAll","hintsReducer","action","HintsProvider","children","dispatch","a","registerHint","unregisterHint","showHint","hideHint","dismissHint","resetHint","resetAllHints","contextValue","jsx","useHint","hints","useEffect","getHotspotPosition","position","rect","pulseKeyframes","HintHotspot","P","targetRect","pulse","isOpen","onClick","className","ref","pos","jsxs","Fragment","toFloatingPlacement","placement","HintTooltip","target","onClose","floatingPlacement","refs","floatingStyles","useFloating","offset","flip","shift","autoUpdate","dismiss","useDismiss","role","useRole","getFloatingProps","useInteractions","FloatingPortal","Hint","content","tooltipPlacement","autoShow","persist","onShow","onDismiss","isDismissed","show","hide","hotspotRef","x","targetSelector","targetRef","targetElement","useElementPosition","handleHotspotClick","useHints"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createContext, useContext } from 'react'\nimport type { HintsContextValue } from '../types'\n\nexport const HintsContext = createContext<HintsContextValue | null>(null)\n\nHintsContext.displayName = 'HintsContext'\n\nexport function useHintsContext(): HintsContextValue {\n const context = useContext(HintsContext)\n if (!context) {\n throw new Error('useHintsContext must be used within a HintsProvider')\n }\n return context\n}\n","import * as React from 'react'\nimport type { HintState, HintsContextValue } from '../types'\nimport { HintsContext } from './hints-context'\n\ntype HintsAction =\n | { type: 'REGISTER'; id: string }\n | { type: 'UNREGISTER'; id: string }\n | { type: 'SHOW'; id: string }\n | { type: 'HIDE'; id: string }\n | { type: 'DISMISS'; id: string }\n | { type: 'RESET'; id: string }\n | { type: 'RESET_ALL' }\n\ninterface HintsState {\n hints: Map<string, HintState>\n activeHint: string | null\n}\n\nfunction handleRegister(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n if (!newHints.has(id)) {\n newHints.set(id, {\n id,\n isOpen: false,\n isDismissed: false,\n })\n }\n return { ...state, hints: newHints }\n}\n\nfunction handleUnregister(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n newHints.delete(id)\n return {\n ...state,\n hints: newHints,\n activeHint: state.activeHint === id ? null : state.activeHint,\n }\n}\n\nfunction handleShow(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n const hint = newHints.get(id)\n if (hint && !hint.isDismissed) {\n // Close currently active hint\n if (state.activeHint && state.activeHint !== id) {\n const activeHint = newHints.get(state.activeHint)\n if (activeHint) {\n newHints.set(state.activeHint, { ...activeHint, isOpen: false })\n }\n }\n newHints.set(id, { ...hint, isOpen: true })\n return { hints: newHints, activeHint: id }\n }\n return state\n}\n\nfunction handleHide(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n const hint = newHints.get(id)\n if (hint) {\n newHints.set(id, { ...hint, isOpen: false })\n return {\n hints: newHints,\n activeHint: state.activeHint === id ? null : state.activeHint,\n }\n }\n return state\n}\n\nfunction handleDismiss(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n const hint = newHints.get(id)\n if (hint) {\n newHints.set(id, { ...hint, isOpen: false, isDismissed: true })\n return {\n hints: newHints,\n activeHint: state.activeHint === id ? null : state.activeHint,\n }\n }\n return state\n}\n\nfunction handleReset(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n const hint = newHints.get(id)\n if (hint) {\n newHints.set(id, { ...hint, isDismissed: false })\n }\n return { ...state, hints: newHints }\n}\n\nfunction handleResetAll(state: HintsState): HintsState {\n const newHints = new Map(state.hints)\n newHints.forEach((hint, id) => {\n newHints.set(id, { ...hint, isDismissed: false })\n })\n return { ...state, hints: newHints }\n}\n\nfunction hintsReducer(state: HintsState, action: HintsAction): HintsState {\n switch (action.type) {\n case 'REGISTER':\n return handleRegister(state, action.id)\n case 'UNREGISTER':\n return handleUnregister(state, action.id)\n case 'SHOW':\n return handleShow(state, action.id)\n case 'HIDE':\n return handleHide(state, action.id)\n case 'DISMISS':\n return handleDismiss(state, action.id)\n case 'RESET':\n return handleReset(state, action.id)\n case 'RESET_ALL':\n return handleResetAll(state)\n default:\n return state\n }\n}\n\ninterface HintsProviderProps {\n children: React.ReactNode\n}\n\nexport function HintsProvider({ children }: HintsProviderProps) {\n const [state, dispatch] = React.useReducer(hintsReducer, {\n hints: new Map(),\n activeHint: null,\n })\n\n // Stable callbacks that don't change between renders\n const registerHint = React.useCallback((id: string) => dispatch({ type: 'REGISTER', id }), [])\n const unregisterHint = React.useCallback((id: string) => dispatch({ type: 'UNREGISTER', id }), [])\n const showHint = React.useCallback((id: string) => dispatch({ type: 'SHOW', id }), [])\n const hideHint = React.useCallback((id: string) => dispatch({ type: 'HIDE', id }), [])\n const dismissHint = React.useCallback((id: string) => dispatch({ type: 'DISMISS', id }), [])\n const resetHint = React.useCallback((id: string) => dispatch({ type: 'RESET', id }), [])\n const resetAllHints = React.useCallback(() => dispatch({ type: 'RESET_ALL' }), [])\n\n const contextValue = React.useMemo<HintsContextValue>(\n () => ({\n hints: state.hints,\n activeHint: state.activeHint,\n registerHint,\n unregisterHint,\n showHint,\n hideHint,\n dismissHint,\n resetHint,\n resetAllHints,\n }),\n [\n state.hints,\n state.activeHint,\n registerHint,\n unregisterHint,\n showHint,\n hideHint,\n dismissHint,\n resetHint,\n resetAllHints,\n ]\n )\n\n return <HintsContext.Provider value={contextValue}>{children}</HintsContext.Provider>\n}\n","import { useEffect } from 'react'\nimport { useHintsContext } from '../context/hints-context'\n\nexport function useHint(id: string) {\n const { hints, registerHint, unregisterHint, showHint, hideHint, dismissHint, resetHint } =\n useHintsContext()\n const hint = hints.get(id)\n\n useEffect(() => {\n registerHint(id)\n return () => unregisterHint(id)\n }, [id, registerHint, unregisterHint])\n\n return {\n isOpen: hint?.isOpen ?? false,\n isDismissed: hint?.isDismissed ?? false,\n show: () => showHint(id),\n hide: () => hideHint(id),\n dismiss: () => dismissHint(id),\n reset: () => resetHint(id),\n }\n}\n","import * as React from 'react'\nimport type { HotspotPosition } from '../types'\n\ninterface HintHotspotProps {\n targetRect: DOMRect\n position: HotspotPosition\n pulse?: boolean\n isOpen?: boolean\n onClick: () => void\n className?: string\n}\n\nfunction getHotspotPosition(position: HotspotPosition, rect: DOMRect) {\n const offset = 4\n\n switch (position) {\n case 'top-left':\n return { top: rect.top - offset, left: rect.left - offset }\n case 'top-right':\n return { top: rect.top - offset, left: rect.right - offset }\n case 'bottom-left':\n return { top: rect.bottom - offset, left: rect.left - offset }\n case 'bottom-right':\n return { top: rect.bottom - offset, left: rect.right - offset }\n case 'center':\n return {\n top: rect.top + rect.height / 2 - 6,\n left: rect.left + rect.width / 2 - 6,\n }\n default:\n return { top: rect.top - offset, left: rect.right - offset }\n }\n}\n\nconst pulseKeyframes = `\n@keyframes tourkit-pulse {\n 0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7); }\n 50% { opacity: 1; box-shadow: 0 0 0 8px rgba(59, 130, 246, 0); }\n}\n`\n\nexport const HintHotspot = React.forwardRef<HTMLButtonElement, HintHotspotProps>(\n function HintHotspot(\n { targetRect, position, pulse = true, isOpen = false, onClick, className },\n ref\n ) {\n const pos = getHotspotPosition(position, targetRect)\n\n return (\n <>\n <style>{pulseKeyframes}</style>\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={className}\n style={{\n position: 'fixed',\n zIndex: 9999,\n top: pos.top,\n left: pos.left,\n width: 20,\n height: 20,\n borderRadius: '50%',\n backgroundColor: '#3b82f6',\n border: '3px solid #ffffff',\n boxShadow: '0 2px 8px rgba(0,0,0,0.3)',\n cursor: 'pointer',\n padding: 0,\n animation: pulse && !isOpen ? 'tourkit-pulse 1.5s ease-in-out infinite' : 'none',\n }}\n aria-label=\"Show hint\"\n aria-expanded={isOpen}\n />\n </>\n )\n }\n)\n","import {\n type Placement as FloatingPlacement,\n FloatingPortal,\n autoUpdate,\n flip,\n offset,\n shift,\n useDismiss,\n useFloating,\n useInteractions,\n useRole,\n} from '@floating-ui/react'\nimport type * as React from 'react'\nimport type { Placement } from '../types'\n\n// Convert core Placement to floating-ui Placement\n// Core has 'top-center', floating-ui uses just 'top' for center alignment\nfunction toFloatingPlacement(placement: Placement): FloatingPlacement {\n if (placement.endsWith('-center')) {\n return placement.replace('-center', '') as FloatingPlacement\n }\n return placement as FloatingPlacement\n}\n\ninterface HintTooltipProps {\n target: HTMLElement\n placement?: Placement\n children: React.ReactNode\n onClose: () => void\n className?: string\n}\n\nexport function HintTooltip({\n target,\n placement = 'bottom',\n children,\n onClose,\n className,\n}: HintTooltipProps) {\n const floatingPlacement = toFloatingPlacement(placement)\n\n const { refs, floatingStyles, context } = useFloating({\n elements: {\n reference: target,\n },\n open: true,\n placement: floatingPlacement,\n middleware: [offset(8), flip(), shift({ padding: 8 })],\n whileElementsMounted: autoUpdate,\n })\n\n const dismiss = useDismiss(context)\n const role = useRole(context, { role: 'tooltip' })\n const { getFloatingProps } = useInteractions([dismiss, role])\n\n return (\n <FloatingPortal>\n <div\n ref={refs.setFloating}\n style={{\n ...floatingStyles,\n zIndex: 9999,\n maxWidth: 280,\n borderRadius: 8,\n border: '1px solid #e5e7eb',\n backgroundColor: '#ffffff',\n padding: 12,\n fontSize: 14,\n color: '#1f2937',\n boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n }}\n className={className}\n {...getFloatingProps()}\n >\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n position: 'absolute',\n right: 8,\n top: 8,\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: 4,\n opacity: 0.7,\n borderRadius: 4,\n }}\n aria-label=\"Dismiss hint\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <title>Close</title>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n <div style={{ paddingRight: 16 }}>{children}</div>\n </div>\n </FloatingPortal>\n )\n}\n","import { useElementPosition } from '@tour-kit/core'\nimport * as React from 'react'\nimport { useHint } from '../hooks/use-hint'\nimport type { HintConfig } from '../types'\nimport { HintHotspot } from './hint-hotspot'\nimport { HintTooltip } from './hint-tooltip'\n\ntype HintProps = HintConfig & {\n children?: React.ReactNode\n className?: string\n}\n\nexport function Hint({\n id,\n target,\n content,\n children,\n position = 'top-right',\n tooltipPlacement = 'bottom',\n pulse = true,\n autoShow = false,\n persist = false,\n onClick,\n onShow,\n onDismiss,\n className,\n}: HintProps) {\n const { isOpen, isDismissed, show, hide, dismiss } = useHint(id)\n const hotspotRef = React.useRef<HTMLButtonElement>(null)\n\n const targetSelector = typeof target === 'string' ? target : null\n const targetRef = typeof target === 'object' ? target?.current : null\n\n const { element: targetElement, rect: targetRect } = useElementPosition(\n targetSelector ?? targetRef\n )\n\n React.useEffect(() => {\n if (autoShow && !isDismissed) {\n show()\n onShow?.()\n }\n }, [autoShow, isDismissed, show, onShow])\n\n const handleHotspotClick = () => {\n onClick?.()\n if (isOpen) {\n hide()\n } else {\n show()\n onShow?.()\n }\n }\n\n const handleDismiss = () => {\n if (persist) {\n dismiss()\n } else {\n hide()\n }\n onDismiss?.()\n }\n\n if (isDismissed || !targetElement || !targetRect) {\n return null\n }\n\n return (\n <>\n <HintHotspot\n ref={hotspotRef}\n targetRect={targetRect}\n position={position}\n pulse={pulse}\n isOpen={isOpen}\n onClick={handleHotspotClick}\n />\n {isOpen && hotspotRef.current && (\n <HintTooltip\n target={hotspotRef.current}\n placement={tooltipPlacement}\n onClose={handleDismiss}\n className={className}\n >\n {children ?? content}\n </HintTooltip>\n )}\n </>\n )\n}\n","import { useHintsContext } from '../context/hints-context'\n\nexport function useHints() {\n const context = useHintsContext()\n\n return {\n hints: Array.from(context.hints.values()),\n activeHint: context.activeHint,\n showHint: context.showHint,\n hideHint: context.hideHint,\n dismissHint: context.dismissHint,\n resetHint: context.resetHint,\n resetAllHints: context.resetAllHints,\n isHintVisible: (id: string) => context.hints.get(id)?.isOpen ?? false,\n isHintDismissed: (id: string) => context.hints.get(id)?.isDismissed ?? false,\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1 +1,60 @@
1
- export * from '@tour-kit/core';
1
+ import * as React from 'react';
2
+ import * as _tour_kit_core from '@tour-kit/core';
3
+ import { HintsContextValue, HintConfig, HotspotPosition, Placement } from '@tour-kit/core';
4
+ export { HintConfig, HintState, HintsContextValue, HotspotPosition } from '@tour-kit/core';
5
+ import * as react_jsx_runtime from 'react/jsx-runtime';
6
+
7
+ declare const HintsContext: React.Context<HintsContextValue | null>;
8
+
9
+ interface HintsProviderProps {
10
+ children: React.ReactNode;
11
+ }
12
+ declare function HintsProvider({ children }: HintsProviderProps): react_jsx_runtime.JSX.Element;
13
+
14
+ type HintProps = HintConfig & {
15
+ children?: React.ReactNode;
16
+ className?: string;
17
+ };
18
+ declare function Hint({ id, target, content, children, position, tooltipPlacement, pulse, autoShow, persist, onClick, onShow, onDismiss, className, }: HintProps): react_jsx_runtime.JSX.Element | null;
19
+
20
+ interface HintHotspotProps {
21
+ targetRect: DOMRect;
22
+ position: HotspotPosition;
23
+ pulse?: boolean;
24
+ isOpen?: boolean;
25
+ onClick: () => void;
26
+ className?: string;
27
+ }
28
+ declare const HintHotspot: React.ForwardRefExoticComponent<HintHotspotProps & React.RefAttributes<HTMLButtonElement>>;
29
+
30
+ interface HintTooltipProps {
31
+ target: HTMLElement;
32
+ placement?: Placement;
33
+ children: React.ReactNode;
34
+ onClose: () => void;
35
+ className?: string;
36
+ }
37
+ declare function HintTooltip({ target, placement, children, onClose, className, }: HintTooltipProps): react_jsx_runtime.JSX.Element;
38
+
39
+ declare function useHint(id: string): {
40
+ isOpen: boolean;
41
+ isDismissed: boolean;
42
+ show: () => void;
43
+ hide: () => void;
44
+ dismiss: () => void;
45
+ reset: () => void;
46
+ };
47
+
48
+ declare function useHints(): {
49
+ hints: _tour_kit_core.HintState[];
50
+ activeHint: string | null;
51
+ showHint: (id: string) => void;
52
+ hideHint: (id: string) => void;
53
+ dismissHint: (id: string) => void;
54
+ resetHint: (id: string) => void;
55
+ resetAllHints: () => void;
56
+ isHintVisible: (id: string) => boolean;
57
+ isHintDismissed: (id: string) => boolean;
58
+ };
59
+
60
+ export { Hint, HintHotspot, HintTooltip, HintsContext, HintsProvider, useHint, useHints };
package/dist/index.d.ts CHANGED
@@ -1 +1,60 @@
1
- export * from '@tour-kit/core';
1
+ import * as React from 'react';
2
+ import * as _tour_kit_core from '@tour-kit/core';
3
+ import { HintsContextValue, HintConfig, HotspotPosition, Placement } from '@tour-kit/core';
4
+ export { HintConfig, HintState, HintsContextValue, HotspotPosition } from '@tour-kit/core';
5
+ import * as react_jsx_runtime from 'react/jsx-runtime';
6
+
7
+ declare const HintsContext: React.Context<HintsContextValue | null>;
8
+
9
+ interface HintsProviderProps {
10
+ children: React.ReactNode;
11
+ }
12
+ declare function HintsProvider({ children }: HintsProviderProps): react_jsx_runtime.JSX.Element;
13
+
14
+ type HintProps = HintConfig & {
15
+ children?: React.ReactNode;
16
+ className?: string;
17
+ };
18
+ declare function Hint({ id, target, content, children, position, tooltipPlacement, pulse, autoShow, persist, onClick, onShow, onDismiss, className, }: HintProps): react_jsx_runtime.JSX.Element | null;
19
+
20
+ interface HintHotspotProps {
21
+ targetRect: DOMRect;
22
+ position: HotspotPosition;
23
+ pulse?: boolean;
24
+ isOpen?: boolean;
25
+ onClick: () => void;
26
+ className?: string;
27
+ }
28
+ declare const HintHotspot: React.ForwardRefExoticComponent<HintHotspotProps & React.RefAttributes<HTMLButtonElement>>;
29
+
30
+ interface HintTooltipProps {
31
+ target: HTMLElement;
32
+ placement?: Placement;
33
+ children: React.ReactNode;
34
+ onClose: () => void;
35
+ className?: string;
36
+ }
37
+ declare function HintTooltip({ target, placement, children, onClose, className, }: HintTooltipProps): react_jsx_runtime.JSX.Element;
38
+
39
+ declare function useHint(id: string): {
40
+ isOpen: boolean;
41
+ isDismissed: boolean;
42
+ show: () => void;
43
+ hide: () => void;
44
+ dismiss: () => void;
45
+ reset: () => void;
46
+ };
47
+
48
+ declare function useHints(): {
49
+ hints: _tour_kit_core.HintState[];
50
+ activeHint: string | null;
51
+ showHint: (id: string) => void;
52
+ hideHint: (id: string) => void;
53
+ dismissHint: (id: string) => void;
54
+ resetHint: (id: string) => void;
55
+ resetAllHints: () => void;
56
+ isHintVisible: (id: string) => boolean;
57
+ isHintDismissed: (id: string) => boolean;
58
+ };
59
+
60
+ export { Hint, HintHotspot, HintTooltip, HintsContext, HintsProvider, useHint, useHints };
package/dist/index.js CHANGED
@@ -1,3 +1,8 @@
1
- // src/index.ts
2
- export * from "@tour-kit/core";
1
+ import*as a from'react';import {createContext,useEffect,useContext}from'react';import {jsxs,Fragment,jsx}from'react/jsx-runtime';import {useElementPosition}from'@tour-kit/core';import {useFloating,autoUpdate,offset,flip,shift,useDismiss,useRole,useInteractions,FloatingPortal}from'@floating-ui/react';var m=createContext(null);m.displayName="HintsContext";function d(){let t=useContext(m);if(!t)throw new Error("useHintsContext must be used within a HintsProvider");return t}function U(t,e){let n=new Map(t.hints);return n.has(e)||n.set(e,{id:e,isOpen:false,isDismissed:false}),{...t,hints:n}}function z(t,e){let n=new Map(t.hints);return n.delete(e),{...t,hints:n,activeHint:t.activeHint===e?null:t.activeHint}}function B(t,e){let n=new Map(t.hints),i=n.get(e);if(i&&!i.isDismissed){if(t.activeHint&&t.activeHint!==e){let o=n.get(t.activeHint);o&&n.set(t.activeHint,{...o,isOpen:false});}return n.set(e,{...i,isOpen:true}),{hints:n,activeHint:e}}return t}function _(t,e){let n=new Map(t.hints),i=n.get(e);return i?(n.set(e,{...i,isOpen:false}),{hints:n,activeHint:t.activeHint===e?null:t.activeHint}):t}function K(t,e){let n=new Map(t.hints),i=n.get(e);return i?(n.set(e,{...i,isOpen:false,isDismissed:true}),{hints:n,activeHint:t.activeHint===e?null:t.activeHint}):t}function q(t,e){let n=new Map(t.hints),i=n.get(e);return i&&n.set(e,{...i,isDismissed:false}),{...t,hints:n}}function J(t){let e=new Map(t.hints);return e.forEach((n,i)=>{e.set(i,{...n,isDismissed:false});}),{...t,hints:e}}function Q(t,e){switch(e.type){case "REGISTER":return U(t,e.id);case "UNREGISTER":return z(t,e.id);case "SHOW":return B(t,e.id);case "HIDE":return _(t,e.id);case "DISMISS":return K(t,e.id);case "RESET":return q(t,e.id);case "RESET_ALL":return J(t);default:return t}}function X({children:t}){let[e,n]=a.useReducer(Q,{hints:new Map,activeHint:null}),i=a.useCallback(s=>n({type:"REGISTER",id:s}),[]),o=a.useCallback(s=>n({type:"UNREGISTER",id:s}),[]),p=a.useCallback(s=>n({type:"SHOW",id:s}),[]),c=a.useCallback(s=>n({type:"HIDE",id:s}),[]),l=a.useCallback(s=>n({type:"DISMISS",id:s}),[]),r=a.useCallback(s=>n({type:"RESET",id:s}),[]),H=a.useCallback(()=>n({type:"RESET_ALL"}),[]),f=a.useMemo(()=>({hints:e.hints,activeHint:e.activeHint,registerHint:i,unregisterHint:o,showHint:p,hideHint:c,dismissHint:l,resetHint:r,resetAllHints:H}),[e.hints,e.activeHint,i,o,p,c,l,r,H]);return jsx(m.Provider,{value:f,children:t})}function h(t){let{hints:e,registerHint:n,unregisterHint:i,showHint:o,hideHint:p,dismissHint:c,resetHint:l}=d(),r=e.get(t);return useEffect(()=>(n(t),()=>i(t)),[t,n,i]),{isOpen:r?.isOpen??false,isDismissed:r?.isDismissed??false,show:()=>o(t),hide:()=>p(t),dismiss:()=>c(t),reset:()=>l(t)}}function $(t,e){switch(t){case "top-left":return {top:e.top-4,left:e.left-4};case "top-right":return {top:e.top-4,left:e.right-4};case "bottom-left":return {top:e.bottom-4,left:e.left-4};case "bottom-right":return {top:e.bottom-4,left:e.right-4};case "center":return {top:e.top+e.height/2-6,left:e.left+e.width/2-6};default:return {top:e.top-4,left:e.right-4}}}var j=`
2
+ @keyframes tourkit-pulse {
3
+ 0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7); }
4
+ 50% { opacity: 1; box-shadow: 0 0 0 8px rgba(59, 130, 246, 0); }
5
+ }
6
+ `,g=a.forwardRef(function({targetRect:e,position:n,pulse:i=true,isOpen:o=false,onClick:p,className:c},l){let r=$(n,e);return jsxs(Fragment,{children:[jsx("style",{children:j}),jsx("button",{ref:l,type:"button",onClick:p,className:c,style:{position:"fixed",zIndex:9999,top:r.top,left:r.left,width:20,height:20,borderRadius:"50%",backgroundColor:"#3b82f6",border:"3px solid #ffffff",boxShadow:"0 2px 8px rgba(0,0,0,0.3)",cursor:"pointer",padding:0,animation:i&&!o?"tourkit-pulse 1.5s ease-in-out infinite":"none"},"aria-label":"Show hint","aria-expanded":o})]})});function ft(t){return t.endsWith("-center")?t.replace("-center",""):t}function R({target:t,placement:e="bottom",children:n,onClose:i,className:o}){let p=ft(e),{refs:c,floatingStyles:l,context:r}=useFloating({elements:{reference:t},open:true,placement:p,middleware:[offset(8),flip(),shift({padding:8})],whileElementsMounted:autoUpdate}),H=useDismiss(r),f=useRole(r,{role:"tooltip"}),{getFloatingProps:s}=useInteractions([H,f]);return jsx(FloatingPortal,{children:jsxs("div",{ref:c.setFloating,style:{...l,zIndex:9999,maxWidth:280,borderRadius:8,border:"1px solid #e5e7eb",backgroundColor:"#ffffff",padding:12,fontSize:14,color:"#1f2937",boxShadow:"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)"},className:o,...s(),children:[jsx("button",{type:"button",onClick:i,style:{position:"absolute",right:8,top:8,background:"none",border:"none",cursor:"pointer",padding:4,opacity:.7,borderRadius:4},"aria-label":"Dismiss hint",children:jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2","aria-hidden":"true",children:[jsx("title",{children:"Close"}),jsx("path",{d:"M18 6 6 18"}),jsx("path",{d:"m6 6 12 12"})]})}),jsx("div",{style:{paddingRight:16},children:n})]})})}function k({id:t,target:e,content:n,children:i,position:o="top-right",tooltipPlacement:p="bottom",pulse:c=true,autoShow:l=false,persist:r=false,onClick:H,onShow:f,onDismiss:s,className:I}){let{isOpen:y,isDismissed:S,show:b,hide:w,dismiss:O}=h(t),v=a.useRef(null),N=typeof e=="string"?e:null,A=typeof e=="object"?e?.current:null,{element:F,rect:C}=useElementPosition(N??A);a.useEffect(()=>{l&&!S&&(b(),f?.());},[l,S,b,f]);let L=()=>{H?.(),y?w():(b(),f?.());},V=()=>{r?O():w(),s?.();};return S||!F||!C?null:jsxs(Fragment,{children:[jsx(g,{ref:v,targetRect:C,position:o,pulse:c,isOpen:y,onClick:L}),y&&v.current&&jsx(R,{target:v.current,placement:p,onClose:V,className:I,children:i??n})]})}function M(){let t=d();return {hints:Array.from(t.hints.values()),activeHint:t.activeHint,showHint:t.showHint,hideHint:t.hideHint,dismissHint:t.dismissHint,resetHint:t.resetHint,resetAllHints:t.resetAllHints,isHintVisible:e=>t.hints.get(e)?.isOpen??false,isHintDismissed:e=>t.hints.get(e)?.isDismissed??false}}
7
+ export{k as Hint,g as HintHotspot,R as HintTooltip,m as HintsContext,X as HintsProvider,h as useHint,M as useHints};//# sourceMappingURL=index.js.map
3
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Re-export types from core\nexport * from '@tour-kit/core'\n"],"mappings":";AACA,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/context/hints-context.ts","../src/context/hints-provider.tsx","../src/hooks/use-hint.ts","../src/components/hint-hotspot.tsx","../src/components/hint-tooltip.tsx","../src/components/hint.tsx","../src/hooks/use-hints.ts"],"names":["HintsContext","createContext","useHintsContext","context","useContext","handleRegister","state","id","newHints","handleUnregister","handleShow","hint","activeHint","handleHide","handleDismiss","handleReset","handleResetAll","hintsReducer","action","HintsProvider","children","dispatch","registerHint","unregisterHint","showHint","hideHint","dismissHint","resetHint","resetAllHints","contextValue","jsx","useHint","hints","useEffect","getHotspotPosition","position","rect","pulseKeyframes","HintHotspot","P","targetRect","pulse","isOpen","onClick","className","ref","pos","jsxs","Fragment","toFloatingPlacement","placement","HintTooltip","target","onClose","floatingPlacement","refs","floatingStyles","useFloating","offset","flip","shift","autoUpdate","dismiss","useDismiss","role","useRole","getFloatingProps","useInteractions","FloatingPortal","Hint","content","tooltipPlacement","autoShow","persist","onShow","onDismiss","isDismissed","show","hide","hotspotRef","x","targetSelector","targetRef","targetElement","useElementPosition","handleHotspotClick","useHints"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext } from 'react'\nimport type { HintsContextValue } from '../types'\n\nexport const HintsContext = createContext<HintsContextValue | null>(null)\n\nHintsContext.displayName = 'HintsContext'\n\nexport function useHintsContext(): HintsContextValue {\n const context = useContext(HintsContext)\n if (!context) {\n throw new Error('useHintsContext must be used within a HintsProvider')\n }\n return context\n}\n","import * as React from 'react'\nimport type { HintState, HintsContextValue } from '../types'\nimport { HintsContext } from './hints-context'\n\ntype HintsAction =\n | { type: 'REGISTER'; id: string }\n | { type: 'UNREGISTER'; id: string }\n | { type: 'SHOW'; id: string }\n | { type: 'HIDE'; id: string }\n | { type: 'DISMISS'; id: string }\n | { type: 'RESET'; id: string }\n | { type: 'RESET_ALL' }\n\ninterface HintsState {\n hints: Map<string, HintState>\n activeHint: string | null\n}\n\nfunction handleRegister(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n if (!newHints.has(id)) {\n newHints.set(id, {\n id,\n isOpen: false,\n isDismissed: false,\n })\n }\n return { ...state, hints: newHints }\n}\n\nfunction handleUnregister(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n newHints.delete(id)\n return {\n ...state,\n hints: newHints,\n activeHint: state.activeHint === id ? null : state.activeHint,\n }\n}\n\nfunction handleShow(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n const hint = newHints.get(id)\n if (hint && !hint.isDismissed) {\n // Close currently active hint\n if (state.activeHint && state.activeHint !== id) {\n const activeHint = newHints.get(state.activeHint)\n if (activeHint) {\n newHints.set(state.activeHint, { ...activeHint, isOpen: false })\n }\n }\n newHints.set(id, { ...hint, isOpen: true })\n return { hints: newHints, activeHint: id }\n }\n return state\n}\n\nfunction handleHide(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n const hint = newHints.get(id)\n if (hint) {\n newHints.set(id, { ...hint, isOpen: false })\n return {\n hints: newHints,\n activeHint: state.activeHint === id ? null : state.activeHint,\n }\n }\n return state\n}\n\nfunction handleDismiss(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n const hint = newHints.get(id)\n if (hint) {\n newHints.set(id, { ...hint, isOpen: false, isDismissed: true })\n return {\n hints: newHints,\n activeHint: state.activeHint === id ? null : state.activeHint,\n }\n }\n return state\n}\n\nfunction handleReset(state: HintsState, id: string): HintsState {\n const newHints = new Map(state.hints)\n const hint = newHints.get(id)\n if (hint) {\n newHints.set(id, { ...hint, isDismissed: false })\n }\n return { ...state, hints: newHints }\n}\n\nfunction handleResetAll(state: HintsState): HintsState {\n const newHints = new Map(state.hints)\n newHints.forEach((hint, id) => {\n newHints.set(id, { ...hint, isDismissed: false })\n })\n return { ...state, hints: newHints }\n}\n\nfunction hintsReducer(state: HintsState, action: HintsAction): HintsState {\n switch (action.type) {\n case 'REGISTER':\n return handleRegister(state, action.id)\n case 'UNREGISTER':\n return handleUnregister(state, action.id)\n case 'SHOW':\n return handleShow(state, action.id)\n case 'HIDE':\n return handleHide(state, action.id)\n case 'DISMISS':\n return handleDismiss(state, action.id)\n case 'RESET':\n return handleReset(state, action.id)\n case 'RESET_ALL':\n return handleResetAll(state)\n default:\n return state\n }\n}\n\ninterface HintsProviderProps {\n children: React.ReactNode\n}\n\nexport function HintsProvider({ children }: HintsProviderProps) {\n const [state, dispatch] = React.useReducer(hintsReducer, {\n hints: new Map(),\n activeHint: null,\n })\n\n // Stable callbacks that don't change between renders\n const registerHint = React.useCallback((id: string) => dispatch({ type: 'REGISTER', id }), [])\n const unregisterHint = React.useCallback((id: string) => dispatch({ type: 'UNREGISTER', id }), [])\n const showHint = React.useCallback((id: string) => dispatch({ type: 'SHOW', id }), [])\n const hideHint = React.useCallback((id: string) => dispatch({ type: 'HIDE', id }), [])\n const dismissHint = React.useCallback((id: string) => dispatch({ type: 'DISMISS', id }), [])\n const resetHint = React.useCallback((id: string) => dispatch({ type: 'RESET', id }), [])\n const resetAllHints = React.useCallback(() => dispatch({ type: 'RESET_ALL' }), [])\n\n const contextValue = React.useMemo<HintsContextValue>(\n () => ({\n hints: state.hints,\n activeHint: state.activeHint,\n registerHint,\n unregisterHint,\n showHint,\n hideHint,\n dismissHint,\n resetHint,\n resetAllHints,\n }),\n [\n state.hints,\n state.activeHint,\n registerHint,\n unregisterHint,\n showHint,\n hideHint,\n dismissHint,\n resetHint,\n resetAllHints,\n ]\n )\n\n return <HintsContext.Provider value={contextValue}>{children}</HintsContext.Provider>\n}\n","import { useEffect } from 'react'\nimport { useHintsContext } from '../context/hints-context'\n\nexport function useHint(id: string) {\n const { hints, registerHint, unregisterHint, showHint, hideHint, dismissHint, resetHint } =\n useHintsContext()\n const hint = hints.get(id)\n\n useEffect(() => {\n registerHint(id)\n return () => unregisterHint(id)\n }, [id, registerHint, unregisterHint])\n\n return {\n isOpen: hint?.isOpen ?? false,\n isDismissed: hint?.isDismissed ?? false,\n show: () => showHint(id),\n hide: () => hideHint(id),\n dismiss: () => dismissHint(id),\n reset: () => resetHint(id),\n }\n}\n","import * as React from 'react'\nimport type { HotspotPosition } from '../types'\n\ninterface HintHotspotProps {\n targetRect: DOMRect\n position: HotspotPosition\n pulse?: boolean\n isOpen?: boolean\n onClick: () => void\n className?: string\n}\n\nfunction getHotspotPosition(position: HotspotPosition, rect: DOMRect) {\n const offset = 4\n\n switch (position) {\n case 'top-left':\n return { top: rect.top - offset, left: rect.left - offset }\n case 'top-right':\n return { top: rect.top - offset, left: rect.right - offset }\n case 'bottom-left':\n return { top: rect.bottom - offset, left: rect.left - offset }\n case 'bottom-right':\n return { top: rect.bottom - offset, left: rect.right - offset }\n case 'center':\n return {\n top: rect.top + rect.height / 2 - 6,\n left: rect.left + rect.width / 2 - 6,\n }\n default:\n return { top: rect.top - offset, left: rect.right - offset }\n }\n}\n\nconst pulseKeyframes = `\n@keyframes tourkit-pulse {\n 0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7); }\n 50% { opacity: 1; box-shadow: 0 0 0 8px rgba(59, 130, 246, 0); }\n}\n`\n\nexport const HintHotspot = React.forwardRef<HTMLButtonElement, HintHotspotProps>(\n function HintHotspot(\n { targetRect, position, pulse = true, isOpen = false, onClick, className },\n ref\n ) {\n const pos = getHotspotPosition(position, targetRect)\n\n return (\n <>\n <style>{pulseKeyframes}</style>\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={className}\n style={{\n position: 'fixed',\n zIndex: 9999,\n top: pos.top,\n left: pos.left,\n width: 20,\n height: 20,\n borderRadius: '50%',\n backgroundColor: '#3b82f6',\n border: '3px solid #ffffff',\n boxShadow: '0 2px 8px rgba(0,0,0,0.3)',\n cursor: 'pointer',\n padding: 0,\n animation: pulse && !isOpen ? 'tourkit-pulse 1.5s ease-in-out infinite' : 'none',\n }}\n aria-label=\"Show hint\"\n aria-expanded={isOpen}\n />\n </>\n )\n }\n)\n","import {\n type Placement as FloatingPlacement,\n FloatingPortal,\n autoUpdate,\n flip,\n offset,\n shift,\n useDismiss,\n useFloating,\n useInteractions,\n useRole,\n} from '@floating-ui/react'\nimport type * as React from 'react'\nimport type { Placement } from '../types'\n\n// Convert core Placement to floating-ui Placement\n// Core has 'top-center', floating-ui uses just 'top' for center alignment\nfunction toFloatingPlacement(placement: Placement): FloatingPlacement {\n if (placement.endsWith('-center')) {\n return placement.replace('-center', '') as FloatingPlacement\n }\n return placement as FloatingPlacement\n}\n\ninterface HintTooltipProps {\n target: HTMLElement\n placement?: Placement\n children: React.ReactNode\n onClose: () => void\n className?: string\n}\n\nexport function HintTooltip({\n target,\n placement = 'bottom',\n children,\n onClose,\n className,\n}: HintTooltipProps) {\n const floatingPlacement = toFloatingPlacement(placement)\n\n const { refs, floatingStyles, context } = useFloating({\n elements: {\n reference: target,\n },\n open: true,\n placement: floatingPlacement,\n middleware: [offset(8), flip(), shift({ padding: 8 })],\n whileElementsMounted: autoUpdate,\n })\n\n const dismiss = useDismiss(context)\n const role = useRole(context, { role: 'tooltip' })\n const { getFloatingProps } = useInteractions([dismiss, role])\n\n return (\n <FloatingPortal>\n <div\n ref={refs.setFloating}\n style={{\n ...floatingStyles,\n zIndex: 9999,\n maxWidth: 280,\n borderRadius: 8,\n border: '1px solid #e5e7eb',\n backgroundColor: '#ffffff',\n padding: 12,\n fontSize: 14,\n color: '#1f2937',\n boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n }}\n className={className}\n {...getFloatingProps()}\n >\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n position: 'absolute',\n right: 8,\n top: 8,\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: 4,\n opacity: 0.7,\n borderRadius: 4,\n }}\n aria-label=\"Dismiss hint\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n >\n <title>Close</title>\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n <div style={{ paddingRight: 16 }}>{children}</div>\n </div>\n </FloatingPortal>\n )\n}\n","import { useElementPosition } from '@tour-kit/core'\nimport * as React from 'react'\nimport { useHint } from '../hooks/use-hint'\nimport type { HintConfig } from '../types'\nimport { HintHotspot } from './hint-hotspot'\nimport { HintTooltip } from './hint-tooltip'\n\ntype HintProps = HintConfig & {\n children?: React.ReactNode\n className?: string\n}\n\nexport function Hint({\n id,\n target,\n content,\n children,\n position = 'top-right',\n tooltipPlacement = 'bottom',\n pulse = true,\n autoShow = false,\n persist = false,\n onClick,\n onShow,\n onDismiss,\n className,\n}: HintProps) {\n const { isOpen, isDismissed, show, hide, dismiss } = useHint(id)\n const hotspotRef = React.useRef<HTMLButtonElement>(null)\n\n const targetSelector = typeof target === 'string' ? target : null\n const targetRef = typeof target === 'object' ? target?.current : null\n\n const { element: targetElement, rect: targetRect } = useElementPosition(\n targetSelector ?? targetRef\n )\n\n React.useEffect(() => {\n if (autoShow && !isDismissed) {\n show()\n onShow?.()\n }\n }, [autoShow, isDismissed, show, onShow])\n\n const handleHotspotClick = () => {\n onClick?.()\n if (isOpen) {\n hide()\n } else {\n show()\n onShow?.()\n }\n }\n\n const handleDismiss = () => {\n if (persist) {\n dismiss()\n } else {\n hide()\n }\n onDismiss?.()\n }\n\n if (isDismissed || !targetElement || !targetRect) {\n return null\n }\n\n return (\n <>\n <HintHotspot\n ref={hotspotRef}\n targetRect={targetRect}\n position={position}\n pulse={pulse}\n isOpen={isOpen}\n onClick={handleHotspotClick}\n />\n {isOpen && hotspotRef.current && (\n <HintTooltip\n target={hotspotRef.current}\n placement={tooltipPlacement}\n onClose={handleDismiss}\n className={className}\n >\n {children ?? content}\n </HintTooltip>\n )}\n </>\n )\n}\n","import { useHintsContext } from '../context/hints-context'\n\nexport function useHints() {\n const context = useHintsContext()\n\n return {\n hints: Array.from(context.hints.values()),\n activeHint: context.activeHint,\n showHint: context.showHint,\n hideHint: context.hideHint,\n dismissHint: context.dismissHint,\n resetHint: context.resetHint,\n resetAllHints: context.resetAllHints,\n isHintVisible: (id: string) => context.hints.get(id)?.isOpen ?? false,\n isHintDismissed: (id: string) => context.hints.get(id)?.isDismissed ?? false,\n }\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tour-kit/hints",
3
- "version": "0.2.0",
4
- "description": "Headless onboarding and product tour library for React - Hints package",
3
+ "version": "0.4.0",
4
+ "description": "Persistent hints and hotspots for TourKit",
5
5
  "author": "Tour Kit Team",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/DomiDex/tour-kit#readme",
@@ -15,15 +15,11 @@
15
15
  },
16
16
  "keywords": [
17
17
  "react",
18
- "onboarding",
19
- "tour",
20
- "product-tour",
21
- "walkthrough",
22
18
  "hints",
23
- "tooltip",
24
- "beacon",
25
- "headless",
26
- "shadcn"
19
+ "hotspot",
20
+ "tooltips",
21
+ "onboarding",
22
+ "tour-kit"
27
23
  ],
28
24
  "type": "module",
29
25
  "main": "./dist/index.cjs",
@@ -53,11 +49,14 @@
53
49
  "registry": "https://registry.npmjs.org/"
54
50
  },
55
51
  "dependencies": {
56
- "@tour-kit/core": "0.2.0"
52
+ "@floating-ui/react": "^0.26.0",
53
+ "clsx": "^2.1.0",
54
+ "tailwind-merge": "^2.3.0",
55
+ "@tour-kit/core": "0.3.0"
57
56
  },
58
57
  "peerDependencies": {
59
- "react": "^18.0.0 || >=19.2.0",
60
- "react-dom": "^18.0.0 || >=19.2.0"
58
+ "react": "^18.0.0 || ^19.0.0",
59
+ "react-dom": "^18.0.0 || ^19.0.0"
61
60
  },
62
61
  "devDependencies": {
63
62
  "@types/react": "^19.2.0",