featuredrop 2.6.1 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +21 -0
- package/README.md +77 -11
- package/context7.json +15 -0
- package/dist/index.d.cts +89 -1
- package/dist/index.d.ts +89 -1
- package/dist/preact.cjs +19 -10
- package/dist/preact.cjs.map +1 -1
- package/dist/preact.d.cts +93 -1
- package/dist/preact.d.ts +93 -1
- package/dist/preact.js +19 -10
- package/dist/preact.js.map +1 -1
- package/dist/react-hooks.cjs +472 -0
- package/dist/react-hooks.cjs.map +1 -0
- package/dist/react-hooks.d.cts +540 -0
- package/dist/react-hooks.d.ts +540 -0
- package/dist/react-hooks.js +461 -0
- package/dist/react-hooks.js.map +1 -0
- package/dist/react.cjs +19 -10
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +93 -1
- package/dist/react.d.ts +93 -1
- package/dist/react.js +19 -10
- package/dist/react.js.map +1 -1
- package/dist/tailwind.cjs +148 -0
- package/dist/tailwind.cjs.map +1 -0
- package/dist/tailwind.d.cts +38 -0
- package/dist/tailwind.d.ts +38 -0
- package/dist/tailwind.js +146 -0
- package/dist/tailwind.js.map +1 -0
- package/dist/testing.cjs +19 -10
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +90 -0
- package/dist/testing.d.ts +90 -0
- package/dist/testing.js +19 -10
- package/dist/testing.js.map +1 -1
- package/package.json +32 -1
- package/skills/featuredrop-setup/SKILL.md +124 -0
- package/src/ai/claude-skill.md +109 -0
- package/src/ai/cursorrules.txt +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "featuredrop",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.1",
|
|
4
4
|
"description": "Lightweight feature discovery system. Show 'New' badges that auto-expire.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -195,6 +195,26 @@
|
|
|
195
195
|
"types": "./dist/testing.d.cts",
|
|
196
196
|
"default": "./dist/testing.cjs"
|
|
197
197
|
}
|
|
198
|
+
},
|
|
199
|
+
"./react/hooks": {
|
|
200
|
+
"import": {
|
|
201
|
+
"types": "./dist/react-hooks.d.ts",
|
|
202
|
+
"default": "./dist/react-hooks.js"
|
|
203
|
+
},
|
|
204
|
+
"require": {
|
|
205
|
+
"types": "./dist/react-hooks.d.cts",
|
|
206
|
+
"default": "./dist/react-hooks.cjs"
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
"./tailwind": {
|
|
210
|
+
"import": {
|
|
211
|
+
"types": "./dist/tailwind.d.ts",
|
|
212
|
+
"default": "./dist/tailwind.js"
|
|
213
|
+
},
|
|
214
|
+
"require": {
|
|
215
|
+
"types": "./dist/tailwind.d.cts",
|
|
216
|
+
"default": "./dist/tailwind.cjs"
|
|
217
|
+
}
|
|
198
218
|
}
|
|
199
219
|
},
|
|
200
220
|
"typesVersions": {
|
|
@@ -246,6 +266,12 @@
|
|
|
246
266
|
],
|
|
247
267
|
"flags": [
|
|
248
268
|
"./dist/flags.d.ts"
|
|
269
|
+
],
|
|
270
|
+
"react/hooks": [
|
|
271
|
+
"./dist/react-hooks.d.ts"
|
|
272
|
+
],
|
|
273
|
+
"tailwind": [
|
|
274
|
+
"./dist/tailwind.d.ts"
|
|
249
275
|
]
|
|
250
276
|
}
|
|
251
277
|
},
|
|
@@ -255,6 +281,11 @@
|
|
|
255
281
|
"dist/**/*.d.ts",
|
|
256
282
|
"dist/**/*.d.cts",
|
|
257
283
|
"dist/**/*.map",
|
|
284
|
+
".claude-plugin/**",
|
|
285
|
+
"skills/**",
|
|
286
|
+
"context7.json",
|
|
287
|
+
"src/ai/cursorrules.txt",
|
|
288
|
+
"src/ai/claude-skill.md",
|
|
258
289
|
"README.md",
|
|
259
290
|
"LICENSE"
|
|
260
291
|
],
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: featuredrop-setup
|
|
3
|
+
description: >
|
|
4
|
+
Configure FeatureDrop product adoption toolkit in any project. Use when adding
|
|
5
|
+
changelogs, feature badges, onboarding tours, checklists, hotspots, feedback
|
|
6
|
+
widgets, or surveys to an application.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# FeatureDrop — Product Adoption Toolkit
|
|
10
|
+
|
|
11
|
+
Open-source, zero-dependency library for in-app feature discovery. < 3 kB core.
|
|
12
|
+
|
|
13
|
+
## Setup Pattern
|
|
14
|
+
|
|
15
|
+
1. `npm install featuredrop`
|
|
16
|
+
2. Create a JSON manifest: `[{ id, label, description, releasedAt, showNewUntil? }]`
|
|
17
|
+
3. Wrap root: `<FeatureDropProvider manifest={features} storage={new LocalStorageAdapter()}>`
|
|
18
|
+
4. Add components or use headless hooks.
|
|
19
|
+
|
|
20
|
+
## Imports (ALWAYS use subpath imports)
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
// Core (no React, no UI)
|
|
24
|
+
import { isNew, getNewFeatures, createManifest, LocalStorageAdapter } from 'featuredrop'
|
|
25
|
+
|
|
26
|
+
// React components (ready-made UI)
|
|
27
|
+
import { NewBadge, ChangelogWidget, Tour, Checklist, Banner, Toast } from 'featuredrop/react'
|
|
28
|
+
|
|
29
|
+
// Headless hooks (data + actions, no JSX — for custom design systems / shadcn)
|
|
30
|
+
import { useChangelog, useNewFeature, useNewCount, useTour, useChecklist } from 'featuredrop/react/hooks'
|
|
31
|
+
|
|
32
|
+
// Storage adapters
|
|
33
|
+
import { PostgresAdapter, RedisAdapter, IndexedDBAdapter, HybridAdapter } from 'featuredrop/adapters'
|
|
34
|
+
|
|
35
|
+
// Validation
|
|
36
|
+
import { validateManifest } from 'featuredrop/schema'
|
|
37
|
+
|
|
38
|
+
// Testing helpers
|
|
39
|
+
import { createMockManifest, createMockStorage, TestProvider } from 'featuredrop/testing'
|
|
40
|
+
|
|
41
|
+
// Tailwind plugin
|
|
42
|
+
import { featureDropPlugin } from 'featuredrop/tailwind'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Hooks (prefer these for custom UI / shadcn projects)
|
|
46
|
+
|
|
47
|
+
| Hook | Returns |
|
|
48
|
+
|------|---------|
|
|
49
|
+
| `useNewFeature(id)` | `{ isNew, feature, dismiss }` |
|
|
50
|
+
| `useNewCount()` | `number` — unread badge count |
|
|
51
|
+
| `useChangelog()` | `{ features, newFeatures, newCount, dismiss, dismissAll, markAllSeen, getByCategory }` |
|
|
52
|
+
| `useTour(id)` | `{ currentStep, stepIndex, totalSteps, isActive, start, next, prev, skip, complete, goTo }` |
|
|
53
|
+
| `useChecklist(id)` | `{ tasks, completedCount, totalCount, progress, isComplete, completeTask, resetTask }` |
|
|
54
|
+
| `useSurvey(id)` | `{ isVisible, questions, submit, askLater, dismiss }` |
|
|
55
|
+
| `useFeatureDrop()` | Full provider context (features, count, dismiss, throttle controls, engine) |
|
|
56
|
+
| `useTabNotification()` | Browser tab title: `"(3) My App"` |
|
|
57
|
+
|
|
58
|
+
## Components (ready-made UI)
|
|
59
|
+
|
|
60
|
+
NewBadge, ChangelogWidget, ChangelogPage, Tour, Checklist, Spotlight, SpotlightChain,
|
|
61
|
+
Hotspot, TooltipGroup, Banner, Toast, AnnouncementModal, Survey, FeedbackWidget,
|
|
62
|
+
FeatureRequestButton, FeatureRequestForm
|
|
63
|
+
|
|
64
|
+
## Feature Manifest Format
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
{
|
|
68
|
+
id: string // unique identifier
|
|
69
|
+
label: string // display title
|
|
70
|
+
description: string // what changed
|
|
71
|
+
releasedAt: string // ISO date
|
|
72
|
+
showNewUntil?: string // ISO date — auto-expire badge
|
|
73
|
+
category?: string // group: "ui", "api", "billing"
|
|
74
|
+
type?: string // "feature" | "improvement" | "fix" | "deprecation"
|
|
75
|
+
priority?: string // "low" | "medium" | "high" | "critical"
|
|
76
|
+
cta?: { label: string; url: string }
|
|
77
|
+
audience?: Record<string, string[]> // user segmentation
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Storage Adapters
|
|
82
|
+
|
|
83
|
+
Default: `LocalStorageAdapter` (browser). Server: `PostgresAdapter`, `RedisAdapter`.
|
|
84
|
+
Offline: `IndexedDBAdapter`. Hybrid: `HybridAdapter` (local + remote sync).
|
|
85
|
+
Custom: implement `{ getWatermark, setWatermark, getDismissedIds, addDismissedId }`.
|
|
86
|
+
|
|
87
|
+
## Provider Props
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<FeatureDropProvider
|
|
91
|
+
manifest={features} // required
|
|
92
|
+
storage={adapter} // required
|
|
93
|
+
analytics={{ onFeatureSeen, onFeatureDismissed, onFeatureClicked }}
|
|
94
|
+
userContext={{ plan, role, region }} // for audience targeting
|
|
95
|
+
appVersion="2.1.0" // semver gating
|
|
96
|
+
throttle={{ maxToastsPerSession: 3, modalCooldownMs: 120_000 }}
|
|
97
|
+
locale="en" // i18n (en/es/fr/de/pt/zh-cn/ja/ko/ar/hi)
|
|
98
|
+
animation="normal" // "none" | "subtle" | "normal" | "playful"
|
|
99
|
+
engine={engineInstance} // optional: FeatureDropEngine for smart delivery
|
|
100
|
+
/>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Tailwind Integration
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// tailwind.config.ts
|
|
107
|
+
import { featureDropPlugin } from 'featuredrop/tailwind'
|
|
108
|
+
|
|
109
|
+
export default {
|
|
110
|
+
plugins: [featureDropPlugin({ prefix: 'fd' })],
|
|
111
|
+
}
|
|
112
|
+
// Adds: fd-badge, fd-badge-dot, fd-badge-count, fd-animate-pulse, fd-animate-fade-in
|
|
113
|
+
// CSS vars: --fd-new, --fd-changelog-bg, --fd-tour-bg (auto dark mode)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Rules
|
|
117
|
+
|
|
118
|
+
- Always use subpath imports (`featuredrop/react`, not just `featuredrop`)
|
|
119
|
+
- Prefer hooks from `featuredrop/react/hooks` when the project uses shadcn, Radix, or custom design system
|
|
120
|
+
- Features auto-expire via `showNewUntil` — don't build manual expiry logic
|
|
121
|
+
- Zero production dependencies — don't add external deps
|
|
122
|
+
- TypeScript strict mode — no `any` types
|
|
123
|
+
- All components support headless mode via render props
|
|
124
|
+
- Core < 3 kB, React ~12 kB, fully tree-shakeable
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# FeatureDrop — Setup & Configuration Skill
|
|
2
|
+
|
|
3
|
+
## What it is
|
|
4
|
+
Open-source product adoption toolkit. Changelogs, badges, tours, checklists, feedback.
|
|
5
|
+
Zero dependencies. < 3 kB core. MIT licensed.
|
|
6
|
+
|
|
7
|
+
## Quick Setup
|
|
8
|
+
1. `npm install featuredrop`
|
|
9
|
+
2. Create features.json manifest
|
|
10
|
+
3. Wrap root in `<FeatureDropProvider manifest={features} storage={new LocalStorageAdapter()}>`
|
|
11
|
+
4. Drop components or use hooks
|
|
12
|
+
|
|
13
|
+
## Imports (ALWAYS use subpath imports)
|
|
14
|
+
```
|
|
15
|
+
featuredrop — core functions (isNew, getNewFeatures, createManifest)
|
|
16
|
+
featuredrop/react — components + hooks (NewBadge, ChangelogWidget, Tour, Checklist)
|
|
17
|
+
featuredrop/react/hooks — headless hooks only (useChangelog, useTour, useChecklist, useNewFeature)
|
|
18
|
+
featuredrop/adapters — storage (PostgresAdapter, RedisAdapter, IndexedDBAdapter, etc.)
|
|
19
|
+
featuredrop/schema — Zod validation (featureEntrySchema, validateManifest)
|
|
20
|
+
featuredrop/testing — test helpers (createMockManifest, createMockStorage, createTestProvider)
|
|
21
|
+
featuredrop/tailwind — Tailwind plugin (featureDropPlugin)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Hooks Reference (prefer these for custom UI)
|
|
25
|
+
```
|
|
26
|
+
useNewFeature(sidebarKey) → { isNew, feature, dismiss }
|
|
27
|
+
useNewCount() → number
|
|
28
|
+
useChangelog() → { features, newFeatures, newCount, dismiss, dismissAll, markAllSeen, getByCategory }
|
|
29
|
+
useTour(id) → { currentStep, stepIndex, totalSteps, isActive, start, next, prev, skip, complete }
|
|
30
|
+
useChecklist(id) → { tasks, progress, isComplete, completeTask, resetChecklist }
|
|
31
|
+
useSurvey(id) → { isOpen, show, hide, askLater, submitted, canShow }
|
|
32
|
+
useFeatureDrop() → full provider context (low-level)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Components (ready-made UI with headless render prop mode)
|
|
36
|
+
NewBadge, ChangelogWidget, ChangelogPage, Tour, Checklist, Spotlight, SpotlightChain,
|
|
37
|
+
Hotspot, TooltipGroup, Banner, Toast, AnnouncementModal, Survey, FeedbackWidget,
|
|
38
|
+
FeatureRequestButton, FeatureRequestForm
|
|
39
|
+
|
|
40
|
+
## Manifest Format
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"id": "dark-mode",
|
|
44
|
+
"label": "Dark Mode",
|
|
45
|
+
"description": "Toggle between light and dark themes.",
|
|
46
|
+
"releasedAt": "2026-02-20",
|
|
47
|
+
"showNewUntil": "2026-04-20",
|
|
48
|
+
"category": "ui",
|
|
49
|
+
"priority": "normal",
|
|
50
|
+
"type": "feature"
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Storage Adapters
|
|
55
|
+
- LocalStorageAdapter (browser default, zero-config)
|
|
56
|
+
- MemoryAdapter (testing, SSR)
|
|
57
|
+
- IndexedDBAdapter (offline-first PWAs)
|
|
58
|
+
- PostgresAdapter, RedisAdapter, MySQLAdapter, MongoAdapter, SQLiteAdapter (server)
|
|
59
|
+
- SupabaseAdapter (Supabase with optional realtime)
|
|
60
|
+
- RemoteAdapter (HTTP API with retry + circuit breaker)
|
|
61
|
+
- HybridAdapter (local + remote with batched sync)
|
|
62
|
+
|
|
63
|
+
## Provider Props
|
|
64
|
+
```tsx
|
|
65
|
+
<FeatureDropProvider
|
|
66
|
+
manifest={features} // required: FeatureEntry[]
|
|
67
|
+
storage={adapter} // required: StorageAdapter
|
|
68
|
+
userContext={{ plan, role }} // optional: audience targeting
|
|
69
|
+
analytics={{ onFeatureSeen }} // optional: event callbacks
|
|
70
|
+
locale="en" // optional: i18n
|
|
71
|
+
animation="normal" // optional: "none" | "subtle" | "normal" | "playful"
|
|
72
|
+
throttle={{ sessionCooldown: 5000 }} // optional: rate limiting
|
|
73
|
+
/>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Common Patterns
|
|
77
|
+
|
|
78
|
+
### Using with shadcn/ui
|
|
79
|
+
```tsx
|
|
80
|
+
import { useChangelog } from 'featuredrop/react/hooks'
|
|
81
|
+
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet'
|
|
82
|
+
import { Badge } from '@/components/ui/badge'
|
|
83
|
+
|
|
84
|
+
function MyChangelog() {
|
|
85
|
+
const { newFeatures, newCount, dismiss, markAllSeen } = useChangelog()
|
|
86
|
+
return (
|
|
87
|
+
<Sheet onOpenChange={() => markAllSeen()}>
|
|
88
|
+
<SheetTrigger>
|
|
89
|
+
What's New {newCount > 0 && <Badge>{newCount}</Badge>}
|
|
90
|
+
</SheetTrigger>
|
|
91
|
+
<SheetContent>
|
|
92
|
+
{newFeatures.map(f => (
|
|
93
|
+
<div key={f.id} onClick={() => dismiss(f.id)}>
|
|
94
|
+
<h3>{f.label}</h3>
|
|
95
|
+
<p>{f.description}</p>
|
|
96
|
+
</div>
|
|
97
|
+
))}
|
|
98
|
+
</SheetContent>
|
|
99
|
+
</Sheet>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Rules
|
|
105
|
+
- Always use subpath imports (never bare 'featuredrop' for React code)
|
|
106
|
+
- Prefer hooks over components when user has a custom design system
|
|
107
|
+
- Features auto-expire via showNewUntil — don't build manual expiry logic
|
|
108
|
+
- Zero production dependencies must be maintained
|
|
109
|
+
- TypeScript strict — no any types
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
When working with FeatureDrop:
|
|
2
|
+
- FeatureDrop is a product adoption library (changelogs, badges, tours, checklists, feedback)
|
|
3
|
+
- ALWAYS import from subpaths: 'featuredrop/react', 'featuredrop/react/hooks', 'featuredrop/adapters'
|
|
4
|
+
- For custom UI: use hooks from 'featuredrop/react/hooks' (useChangelog, useTour, useChecklist)
|
|
5
|
+
- For ready-made UI: use components from 'featuredrop/react' (NewBadge, ChangelogWidget, Tour)
|
|
6
|
+
- Features are defined in JSON: { id, label, description, releasedAt, showNewUntil? }
|
|
7
|
+
- Wrap app in <FeatureDropProvider manifest={features} storage={new LocalStorageAdapter()}>
|
|
8
|
+
- Storage default: LocalStorageAdapter. Server: PostgresAdapter, RedisAdapter from 'featuredrop/adapters'
|
|
9
|
+
- Core < 3 kB, React ~12 kB, zero production deps, fully tree-shakable
|
|
10
|
+
- All components support headless mode via render props
|
|
11
|
+
- For shadcn projects: use hooks from 'featuredrop/react/hooks' + shadcn primitives
|
|
12
|
+
- TypeScript strict mode, no 'any' types
|
|
13
|
+
- Zero production dependencies — do not add external deps
|