@pixelmatters/markup 1.1.0 → 1.3.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/README.md +112 -37
- package/dist/widget.js +850 -746
- package/package.json +3 -21
- package/dist/react.d.ts +0 -21
- package/dist/react.js +0 -4792
package/README.md
CHANGED
|
@@ -17,25 +17,45 @@ Pin-anchored feedback for live web apps. Drop in a script tag (or one React comp
|
|
|
17
17
|
- **Respects the platform** — honours `prefers-reduced-motion` and `prefers-color-scheme`; full keyboard navigation with focus traps in popovers.
|
|
18
18
|
- **Tiny surface, tiny config** — `init({ apiUrl, apiKey })` is enough to start. No global CSS to import, no provider to wrap.
|
|
19
19
|
|
|
20
|
-
Built with [Preact](https://preactjs.com). Ships as ESM with a
|
|
20
|
+
Built with [Preact](https://preactjs.com). Ships as a single ESM bundle — wire it into any framework with a one-liner in your root component (snippets below).
|
|
21
21
|
|
|
22
22
|
## Install
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
# pnpm
|
|
26
|
-
pnpm
|
|
26
|
+
pnpm add @pixelmatters/markup
|
|
27
27
|
# or yarn
|
|
28
28
|
yarn add @pixelmatters/markup
|
|
29
29
|
# or npm
|
|
30
30
|
npm install @pixelmatters/markup
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
CDN drop-in (
|
|
33
|
+
CDN drop-in (no build step) — paste this just before `</body>`:
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<script type="module">
|
|
37
|
+
// Pin the exact version — esm.sh resolves it from npm
|
|
38
|
+
import { init } from 'https://esm.sh/@pixelmatters/markup@1.3.0'
|
|
39
|
+
// or
|
|
40
|
+
// import { init } from 'https://esm.run/@pixelmatters/markup@1.3.0'
|
|
41
|
+
|
|
42
|
+
init({
|
|
43
|
+
apiUrl: 'https://your-deployment.convex.site',
|
|
44
|
+
apiKey: 'markup_...',
|
|
45
|
+
position: 'bottom-right', // optional
|
|
46
|
+
theme: 'auto', // optional
|
|
47
|
+
})
|
|
48
|
+
</script>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
> **Why pin the version?** CDN URLs without a version (`@pixelmatters/markup`) resolve to whatever's `latest` on npm — a future major release will break your page silently. Always pin (`@pixelmatters/markup@1.3.0`).
|
|
52
|
+
|
|
53
|
+
If your platform doesn't allow inline JS (some CMS / page-builder editors), use the auto-init form instead — point a `<script src=…>` at the bundle and pass config via `data-*` attributes:
|
|
34
54
|
|
|
35
55
|
```html
|
|
36
56
|
<script
|
|
37
57
|
type="module"
|
|
38
|
-
src="https://
|
|
58
|
+
src="https://esm.sh/@pixelmatters/markup@1.3.0"
|
|
39
59
|
data-markup-widget="true"
|
|
40
60
|
data-api-url="https://your-deployment.convex.site"
|
|
41
61
|
data-api-key="markup_..."
|
|
@@ -43,7 +63,7 @@ CDN drop-in (auto-init on `DOMContentLoaded`):
|
|
|
43
63
|
></script>
|
|
44
64
|
```
|
|
45
65
|
|
|
46
|
-
|
|
66
|
+
`data-markup-widget="true"` is required — it's how the bootstrap finds its own `<script>` tag (since `document.currentScript` is `null` for `type="module"`).
|
|
47
67
|
|
|
48
68
|
## Quickstart
|
|
49
69
|
|
|
@@ -63,23 +83,60 @@ const stop = init({
|
|
|
63
83
|
stop() // equivalent to destroy()
|
|
64
84
|
```
|
|
65
85
|
|
|
66
|
-
### React
|
|
86
|
+
### React
|
|
67
87
|
|
|
68
88
|
```tsx
|
|
69
|
-
import {
|
|
89
|
+
import { useEffect } from 'react'
|
|
90
|
+
import { init } from '@pixelmatters/markup'
|
|
70
91
|
|
|
71
92
|
export default function App() {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
return init({
|
|
95
|
+
apiUrl: import.meta.env.VITE_MARKUP_API_URL,
|
|
96
|
+
apiKey: import.meta.env.VITE_MARKUP_API_KEY,
|
|
97
|
+
position: 'bottom-right', // optional
|
|
98
|
+
theme: 'auto', // optional
|
|
99
|
+
})
|
|
100
|
+
}, [])
|
|
101
|
+
|
|
102
|
+
return <>{/* your app */}</>
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Vue 3
|
|
107
|
+
|
|
108
|
+
```vue
|
|
109
|
+
<script setup lang="ts">
|
|
110
|
+
import { onMounted, onBeforeUnmount } from 'vue'
|
|
111
|
+
import { init } from '@pixelmatters/markup'
|
|
112
|
+
|
|
113
|
+
let stop: (() => void) | undefined
|
|
114
|
+
onMounted(() => {
|
|
115
|
+
stop = init({
|
|
116
|
+
apiUrl: import.meta.env.VITE_MARKUP_API_URL,
|
|
117
|
+
apiKey: import.meta.env.VITE_MARKUP_API_KEY,
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
onBeforeUnmount(() => stop?.())
|
|
121
|
+
</script>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### SolidJS
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import { onMount, onCleanup } from 'solid-js'
|
|
128
|
+
import { init } from '@pixelmatters/markup'
|
|
129
|
+
|
|
130
|
+
export default function App() {
|
|
131
|
+
onMount(() => {
|
|
132
|
+
const stop = init({
|
|
133
|
+
apiUrl: import.meta.env.VITE_MARKUP_API_URL,
|
|
134
|
+
apiKey: import.meta.env.VITE_MARKUP_API_KEY,
|
|
135
|
+
})
|
|
136
|
+
onCleanup(stop)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
return <>{/* your app */}</>
|
|
83
140
|
}
|
|
84
141
|
```
|
|
85
142
|
|
|
@@ -89,23 +146,25 @@ export default function App() {
|
|
|
89
146
|
|
|
90
147
|
Mounts the widget. Idempotent: re-calling with the same config is a no-op; calling with a different config tears down the previous instance first. Returns the `destroy` function.
|
|
91
148
|
|
|
92
|
-
| Option | Type | Default | Description
|
|
93
|
-
| ---------- | --------------------------------- | ---------------- |
|
|
94
|
-
| `apiUrl` | `string` | required | Convex deployment site URL (`https://*.convex.site`)
|
|
95
|
-
| `apiKey` | `string` | required | Project API key — mint one in the dashboard
|
|
96
|
-
| `position` | `'bottom-right' \| 'bottom-left'` | `'bottom-right'` |
|
|
97
|
-
| `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Visual theme — `'light'` or `'dark'`, or `'auto'` (default) to follow the host's `prefers-color-scheme`
|
|
149
|
+
| Option | Type | Default | Description |
|
|
150
|
+
| ---------- | --------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
151
|
+
| `apiUrl` | `string` | required | Convex deployment site URL (`https://*.convex.site`) |
|
|
152
|
+
| `apiKey` | `string` | required | Project API key — mint one in the dashboard |
|
|
153
|
+
| `position` | `'bottom-right' \| 'bottom-left'` | `'bottom-right'` | Initial corner for the floating action button — users can drag it across the viewport midline to flip corners at runtime |
|
|
154
|
+
| `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Visual theme — `'light'` or `'dark'`, or `'auto'` (default) to follow the host's `prefers-color-scheme` |
|
|
98
155
|
|
|
99
156
|
### `destroy()`
|
|
100
157
|
|
|
101
158
|
Unmounts the widget and removes the host element. Safe to call when nothing is mounted.
|
|
102
159
|
|
|
103
|
-
### Keyboard
|
|
160
|
+
### Keyboard & mouse
|
|
104
161
|
|
|
105
|
-
| Shortcut
|
|
106
|
-
|
|
|
107
|
-
| `cmd/ctrl + .`
|
|
108
|
-
| `cmd/ctrl + click`
|
|
162
|
+
| Shortcut | Action |
|
|
163
|
+
| --------------------- | ---------------------------------------------------------------------- |
|
|
164
|
+
| `cmd/ctrl + .` | Toggle HUD visibility |
|
|
165
|
+
| `cmd/ctrl + click` | Click the FAB to hide the HUD with a hint toast |
|
|
166
|
+
| Drag the FAB | Snap it to whichever bottom corner the pointer ends in |
|
|
167
|
+
| Drag a popover header | Move the open thread / new-thread popover; resets to the pin on reopen |
|
|
109
168
|
|
|
110
169
|
## How it works
|
|
111
170
|
|
|
@@ -154,8 +213,6 @@ A drop-in feedback widget published on npm as `@pixelmatters/markup`. It mounts
|
|
|
154
213
|
|
|
155
214
|
```ts
|
|
156
215
|
import { init, destroy } from '@pixelmatters/markup'
|
|
157
|
-
// or:
|
|
158
|
-
import { MarkupWidget } from '@pixelmatters/markup/react'
|
|
159
216
|
|
|
160
217
|
init({
|
|
161
218
|
apiUrl: string, // required
|
|
@@ -165,12 +222,32 @@ init({
|
|
|
165
222
|
}) // returns a destroy() function — call it on unmount / logout / route teardown
|
|
166
223
|
```
|
|
167
224
|
|
|
168
|
-
For
|
|
225
|
+
For React/Vue/Solid hosts, call `init()` from a mount lifecycle hook
|
|
226
|
+
(`useEffect`, `onMounted`, `onMount`) and call the returned `destroy` on
|
|
227
|
+
cleanup. There's no framework-specific entrypoint — `init` is the entire
|
|
228
|
+
public surface.
|
|
229
|
+
|
|
230
|
+
For a `<script>` tag drop-in (no bundler), use the inline ESM form and **pin the version**:
|
|
231
|
+
|
|
232
|
+
```html
|
|
233
|
+
<script type="module">
|
|
234
|
+
import { init } from 'https://esm.sh/@pixelmatters/markup@1.3.0'
|
|
235
|
+
|
|
236
|
+
init({
|
|
237
|
+
apiUrl: '...',
|
|
238
|
+
apiKey: '...',
|
|
239
|
+
position: 'bottom-right',
|
|
240
|
+
theme: 'auto',
|
|
241
|
+
})
|
|
242
|
+
</script>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
If inline JS is disallowed (some CMS / page-builder editors), use the auto-init `<script src=…>` form with `data-*` attributes (`data-markup-widget="true"` is required):
|
|
169
246
|
|
|
170
247
|
```html
|
|
171
248
|
<script
|
|
172
249
|
type="module"
|
|
173
|
-
src="https://
|
|
250
|
+
src="https://esm.sh/@pixelmatters/markup@1.3.0"
|
|
174
251
|
data-markup-widget="true"
|
|
175
252
|
data-api-url="..."
|
|
176
253
|
data-api-key="..."
|
|
@@ -178,8 +255,6 @@ For a `<script>` tag drop-in (no bundler), use:
|
|
|
178
255
|
></script>
|
|
179
256
|
```
|
|
180
257
|
|
|
181
|
-
The `data-markup-widget="true"` attribute is required.
|
|
182
|
-
|
|
183
258
|
## Your task
|
|
184
259
|
|
|
185
260
|
1. Detect my framework (React, Vue, Svelte, Next.js, plain HTML, etc.) by inspecting the project.
|
|
@@ -193,7 +268,7 @@ Constraints:
|
|
|
193
268
|
|
|
194
269
|
- Do **not** add CSS imports or provider components — the widget needs neither.
|
|
195
270
|
- Do **not** hardcode the key.
|
|
196
|
-
- If the project has a CSP, add `https://
|
|
271
|
+
- If the project has a CSP, add `https://esm.sh` to `script-src` only if I'm using the `<script>` tag path.
|
|
197
272
|
````
|
|
198
273
|
|
|
199
274
|
## Browser support
|
|
@@ -204,7 +279,7 @@ Modern evergreen browsers (Chrome, Edge, Firefox, Safari) and their mobile equiv
|
|
|
204
279
|
|
|
205
280
|
```bash
|
|
206
281
|
pnpm dev # vite dev server with the playground page
|
|
207
|
-
pnpm build # production build → dist/
|
|
282
|
+
pnpm build # production build → dist/widget.{js,d.ts}
|
|
208
283
|
pnpm typecheck # tsc --noEmit
|
|
209
284
|
```
|
|
210
285
|
|