@2londres/shareable-preview 1.0.0 → 1.0.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.
- package/README.md +179 -5
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @2londres/shareable-preview
|
|
2
2
|
|
|
3
|
-
React component for shareable data preview with debug/user modes.
|
|
3
|
+
React component for shareable data preview with debug/user modes, custom views, field filtering, and validation buttons.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -17,7 +17,10 @@ npm install @2londres/shareable-preview
|
|
|
17
17
|
|
|
18
18
|
Your project must have Tailwind CSS configured (the component uses Tailwind classes).
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## Basic usage
|
|
21
|
+
|
|
22
|
+
<!-- TODO: Replace with your own recording -->
|
|
23
|
+

|
|
21
24
|
|
|
22
25
|
```tsx
|
|
23
26
|
import { ShareablePreview } from "@2londres/shareable-preview";
|
|
@@ -25,6 +28,17 @@ import { ShareablePreview } from "@2londres/shareable-preview";
|
|
|
25
28
|
<ShareablePreview
|
|
26
29
|
data={{ foo: "bar", count: 42 }}
|
|
27
30
|
title="My Preview"
|
|
31
|
+
description="Verify the information before validation"
|
|
32
|
+
mode="user"
|
|
33
|
+
/>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
With actions:
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<ShareablePreview
|
|
40
|
+
data={myData}
|
|
41
|
+
title="Preview"
|
|
28
42
|
actions={[
|
|
29
43
|
{ label: "Confirm", onClick: () => {} },
|
|
30
44
|
{ label: "Delete", onClick: () => {} },
|
|
@@ -46,9 +60,163 @@ import { ShareablePreview } from "@2londres/shareable-preview";
|
|
|
46
60
|
| `eyeDevMode` | `'development' \| 'production'` | Show/hide debug UI (default: `process.env.NODE_ENV`) |
|
|
47
61
|
| `mode` | `'debug' \| 'user'` | Default view mode |
|
|
48
62
|
| `inline` | `boolean` | Render inline without dialog |
|
|
49
|
-
|
|
|
63
|
+
| `customView` | `Component` | Single custom view component |
|
|
64
|
+
| `customViewProps` | `object` | Props passed to custom view (including field filters) |
|
|
65
|
+
| `customViews` | `Array` | Multiple views with tabs (id, label, view, viewProps, actions) |
|
|
66
|
+
| `defaultOpen` | `boolean` | Open dialog by default |
|
|
67
|
+
| `onOpenChange` | `(open: boolean) => void` | Callback when dialog open state changes |
|
|
68
|
+
|
|
69
|
+
## Action buttons (ValidationButton)
|
|
70
|
+
|
|
71
|
+
Actions display as gradient buttons with icons and visual effects at the bottom of the preview.
|
|
72
|
+
|
|
73
|
+
<!-- TODO: Replace with your own recording -->
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+
### Action props
|
|
77
|
+
|
|
78
|
+
| Prop | Type | Description |
|
|
79
|
+
|------|------|-------------|
|
|
80
|
+
| `label` | `string` | Button text |
|
|
81
|
+
| `onClick` | `() => void` | Click handler |
|
|
82
|
+
| `variant` | `"green" \| "red" \| "blue" \| "purple" \| "orange"` | Gradient color (auto-detected if absent) |
|
|
83
|
+
| `icon` | `LucideIcon \| string \| ReactElement` | Icon (auto-detected from label if absent) |
|
|
84
|
+
| `withPulse` | `boolean` | Pulse animation to draw attention |
|
|
85
|
+
| `withIndicator` | `boolean` | Animated yellow dot in top-right corner |
|
|
86
|
+
| `buttonClassName` | `string` | Additional CSS classes |
|
|
87
|
+
| `disabled` | `boolean` | Disable button |
|
|
88
|
+
| `order` | `number` | Display order (lower = left) |
|
|
89
|
+
|
|
90
|
+
### Auto-detection
|
|
91
|
+
|
|
92
|
+
- **Red variant**: labels containing "delete", "cancel", "reject", etc.
|
|
93
|
+
- **Green variant**: "confirm", "validate", "approve", etc.
|
|
94
|
+
- **Icon**: inferred from label (confirm → CheckCircle, cancel → XCircle, etc.)
|
|
95
|
+
|
|
96
|
+
### Example — Transaction approval
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<ShareablePreview
|
|
100
|
+
data={previewData}
|
|
101
|
+
title="Preview"
|
|
102
|
+
mode="user"
|
|
103
|
+
customView={MultipleTransactionsView}
|
|
104
|
+
defaultOpen
|
|
105
|
+
onOpenChange={(open) => !open && setShowPreview(false)}
|
|
106
|
+
actions={[
|
|
107
|
+
{ label: "Confirm", onClick: () => { setIsOpen(true); setShowPreview(false); }, variant: "green", withIndicator: true },
|
|
108
|
+
{ label: "Reject", onClick: () => { setIsRejectOpen(true); setShowPreview(false); }, variant: "red" },
|
|
109
|
+
{ label: "Cancel", onClick: () => setShowPreview(false), variant: "blue", order: 0 },
|
|
110
|
+
]}
|
|
111
|
+
/>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Custom views
|
|
115
|
+
|
|
116
|
+
<!-- TODO: Replace with your own recording -->
|
|
117
|
+

|
|
118
|
+
|
|
119
|
+
### Single view (`customView`)
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
<ShareablePreview
|
|
123
|
+
data={data}
|
|
124
|
+
customView={TransactionView}
|
|
125
|
+
customViewProps={{
|
|
126
|
+
excludedKeys: ["id", "host_id"],
|
|
127
|
+
excludedNestedKeys: ["transaction_rule", "country"],
|
|
128
|
+
maxDepth: 7,
|
|
129
|
+
}}
|
|
130
|
+
/>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Multiple views with tabs (`customViews`)
|
|
50
134
|
|
|
51
|
-
|
|
135
|
+
```tsx
|
|
136
|
+
import { ShareablePreview, UserView } from "@2londres/shareable-preview";
|
|
137
|
+
|
|
138
|
+
<ShareablePreview
|
|
139
|
+
data={data}
|
|
140
|
+
customViews={[
|
|
141
|
+
{
|
|
142
|
+
id: "summary",
|
|
143
|
+
label: "Summary",
|
|
144
|
+
view: UserView,
|
|
145
|
+
viewProps: { includedKeys: ["amount", "currency", "reference"] },
|
|
146
|
+
actions: [
|
|
147
|
+
{ label: "Validate", variant: "green", onClick: handleValidate },
|
|
148
|
+
{ label: "Cancel", variant: "red", onClick: handleCancel },
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: "full",
|
|
153
|
+
label: "Full details",
|
|
154
|
+
view: TransactionView,
|
|
155
|
+
viewProps: { excludedKeys: ["id"], maxDepth: 7 },
|
|
156
|
+
actions: [
|
|
157
|
+
{ label: "Confirm", variant: "green", onClick: handleConfirm },
|
|
158
|
+
{ label: "Reject", variant: "red", onClick: handleReject },
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
]}
|
|
162
|
+
/>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Each tab can have its **own actions**. If a view has no `actions`, the global actions are used.
|
|
166
|
+
|
|
167
|
+
## Field filtering
|
|
168
|
+
|
|
169
|
+
<!-- TODO: Replace with your own recording -->
|
|
170
|
+

|
|
171
|
+
|
|
172
|
+
Options passed via `customViewProps` or `viewProps` (in `customViews`). Compatible with `UserView`.
|
|
173
|
+
|
|
174
|
+
| Option | Type | Description |
|
|
175
|
+
|--------|------|-------------|
|
|
176
|
+
| `includedKeys` | `string[]` | **Whitelist**: only these top-level keys |
|
|
177
|
+
| `excludedKeys` | `string[]` | **Blacklist**: exclude these keys |
|
|
178
|
+
| `includedNestedKeys` | `string[]` | Whitelist for nested paths |
|
|
179
|
+
| `excludedNestedKeys` | `string[]` | Blacklist for nested paths |
|
|
180
|
+
| `maxDepth` | `number` | Maximum recursion depth |
|
|
181
|
+
|
|
182
|
+
## Helper `createPreviewActions`
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
import { createPreviewActions, ShareablePreview } from "@2londres/shareable-preview";
|
|
186
|
+
|
|
187
|
+
const actions = createPreviewActions({
|
|
188
|
+
onConfirm: () => { setIsOpen(true); setShowPreview(false); },
|
|
189
|
+
onReject: () => { setIsRejectOpen(true); setShowPreview(false); },
|
|
190
|
+
onCancel: () => setShowPreview(false),
|
|
191
|
+
labels: { confirm: "Confirm", reject: "Reject", cancel: "Cancel" },
|
|
192
|
+
withIndicatorOnConfirm: true,
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
<ShareablePreview data={previewData} actions={actions} mode="user" />
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Internationalization
|
|
199
|
+
|
|
200
|
+
The package uses `labels` and `onNotify` for i18n without depending on react-i18next:
|
|
201
|
+
|
|
202
|
+
<!-- TODO: Replace with your own recording -->
|
|
203
|
+

|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
<ShareablePreview
|
|
207
|
+
data={data}
|
|
208
|
+
labels={{
|
|
209
|
+
shareablePreviewDefaultTitle: "Preview",
|
|
210
|
+
shareablePreviewOpen: "Open preview",
|
|
211
|
+
}}
|
|
212
|
+
onNotify={(type, key) => {
|
|
213
|
+
if (type === "success") toast.success(key);
|
|
214
|
+
else toast.error(key);
|
|
215
|
+
}}
|
|
216
|
+
/>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### With react-i18next
|
|
52
220
|
|
|
53
221
|
```tsx
|
|
54
222
|
import { useTranslation } from "react-i18next";
|
|
@@ -58,7 +226,6 @@ const keys = [
|
|
|
58
226
|
"shareablePreviewCopySuccess",
|
|
59
227
|
"shareablePreviewShareLinkCopied",
|
|
60
228
|
"shareablePreviewClipboardError",
|
|
61
|
-
// ... other keys
|
|
62
229
|
];
|
|
63
230
|
|
|
64
231
|
<ShareablePreview
|
|
@@ -70,3 +237,10 @@ const keys = [
|
|
|
70
237
|
}}
|
|
71
238
|
/>
|
|
72
239
|
```
|
|
240
|
+
|
|
241
|
+
## Publishing to npm
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
pnpm build
|
|
245
|
+
npm publish --access public
|
|
246
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@2londres/shareable-preview",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "React component for shareable data preview with debug/user modes",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
"require": "./dist/index.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
-
"files": [
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
16
18
|
"scripts": {
|
|
17
19
|
"build": "tsup",
|
|
18
20
|
"dev": "tsup --watch"
|