@2londres/shareable-preview 1.0.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 +72 -0
- package/dist/index.d.mts +159 -0
- package/dist/index.d.ts +159 -0
- package/dist/index.js +1184 -0
- package/dist/index.mjs +1155 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# @2londres/shareable-preview
|
|
2
|
+
|
|
3
|
+
React component for shareable data preview with debug/user modes.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @2londres/shareable-preview
|
|
9
|
+
# or
|
|
10
|
+
npm install @2londres/shareable-preview
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Peer dependencies
|
|
14
|
+
|
|
15
|
+
- `react` >= 18.0.0
|
|
16
|
+
- `react-dom` >= 18.0.0
|
|
17
|
+
|
|
18
|
+
Your project must have Tailwind CSS configured (the component uses Tailwind classes).
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { ShareablePreview } from "@2londres/shareable-preview";
|
|
24
|
+
|
|
25
|
+
<ShareablePreview
|
|
26
|
+
data={{ foo: "bar", count: 42 }}
|
|
27
|
+
title="My Preview"
|
|
28
|
+
actions={[
|
|
29
|
+
{ label: "Confirm", onClick: () => {} },
|
|
30
|
+
{ label: "Delete", onClick: () => {} },
|
|
31
|
+
]}
|
|
32
|
+
/>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Props
|
|
36
|
+
|
|
37
|
+
| Prop | Type | Description |
|
|
38
|
+
|------|------|-------------|
|
|
39
|
+
| `data` | `unknown` | Data to preview |
|
|
40
|
+
| `title` | `string` | Preview title |
|
|
41
|
+
| `description` | `string` | Optional description |
|
|
42
|
+
| `actions` | `ShareablePreviewAction[]` | Action buttons |
|
|
43
|
+
| `shareUrl` | `string` | URL to copy when sharing |
|
|
44
|
+
| `labels` | `Partial<Record<string, string>>` | Override default labels (i18n) |
|
|
45
|
+
| `onNotify` | `(type: 'success' \| 'error', key: string) => void` | Callback for notifications (copy, download, etc.) |
|
|
46
|
+
| `eyeDevMode` | `'development' \| 'production'` | Show/hide debug UI (default: `process.env.NODE_ENV`) |
|
|
47
|
+
| `mode` | `'debug' \| 'user'` | Default view mode |
|
|
48
|
+
| `inline` | `boolean` | Render inline without dialog |
|
|
49
|
+
| ... | | See component props for full API |
|
|
50
|
+
|
|
51
|
+
## Integration with i18n (react-i18next)
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { useTranslation } from "react-i18next";
|
|
55
|
+
import { ShareablePreview } from "@2londres/shareable-preview";
|
|
56
|
+
|
|
57
|
+
const keys = [
|
|
58
|
+
"shareablePreviewCopySuccess",
|
|
59
|
+
"shareablePreviewShareLinkCopied",
|
|
60
|
+
"shareablePreviewClipboardError",
|
|
61
|
+
// ... other keys
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
<ShareablePreview
|
|
65
|
+
data={data}
|
|
66
|
+
labels={Object.fromEntries(keys.map((k) => [k, t(k)]))}
|
|
67
|
+
onNotify={(type, key) => {
|
|
68
|
+
if (type === "success") notifSilence(key);
|
|
69
|
+
else notifSilenceError(key);
|
|
70
|
+
}}
|
|
71
|
+
/>
|
|
72
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React$1, { ButtonHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ValidationButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
withPulse?: boolean;
|
|
7
|
+
withIndicator?: boolean;
|
|
8
|
+
variant?: "green" | "blue" | "purple" | "orange" | "red";
|
|
9
|
+
icon?: React.ComponentType<{
|
|
10
|
+
className?: string;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Filtre un objet ou tableau de données selon les clés incluses/exclues.
|
|
16
|
+
* - includedKeys / includedNestedKeys : whitelist (seules ces clés sont conservées)
|
|
17
|
+
* - excludedKeys / excludedNestedKeys : blacklist (ces clés sont retirées)
|
|
18
|
+
* La whitelist prime sur la blacklist si les deux sont fournies.
|
|
19
|
+
*/
|
|
20
|
+
interface FilterKeysOptions {
|
|
21
|
+
includedKeys?: string[];
|
|
22
|
+
excludedKeys?: string[];
|
|
23
|
+
includedNestedKeys?: string[];
|
|
24
|
+
excludedNestedKeys?: string[];
|
|
25
|
+
maxDepth?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Filtre data selon les options de clés.
|
|
29
|
+
* Retourne une copie filtrée sans modifier l'original.
|
|
30
|
+
*/
|
|
31
|
+
declare function filterDataByKeys<T>(data: T, options: FilterKeysOptions): T;
|
|
32
|
+
|
|
33
|
+
type ShareablePreviewAction = {
|
|
34
|
+
label: string;
|
|
35
|
+
icon?: string | React$1.ComponentType<{
|
|
36
|
+
className?: string;
|
|
37
|
+
}> | React$1.ReactElement;
|
|
38
|
+
onClick: () => void;
|
|
39
|
+
variant?: ValidationButtonProps["variant"];
|
|
40
|
+
withPulse?: boolean;
|
|
41
|
+
withIndicator?: boolean;
|
|
42
|
+
buttonClassName?: string;
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
/** Ordre d'affichage (plus petit = à gauche) */
|
|
45
|
+
order?: number;
|
|
46
|
+
};
|
|
47
|
+
interface CustomViewFieldConfig extends FilterKeysOptions {
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
}
|
|
50
|
+
interface CustomViewConfig {
|
|
51
|
+
id: string;
|
|
52
|
+
label: string;
|
|
53
|
+
view: React$1.ComponentType<{
|
|
54
|
+
data: unknown;
|
|
55
|
+
className?: string;
|
|
56
|
+
expandByDefault?: boolean;
|
|
57
|
+
excludedKeys?: string[];
|
|
58
|
+
excludedNestedKeys?: string[];
|
|
59
|
+
includedKeys?: string[];
|
|
60
|
+
includedNestedKeys?: string[];
|
|
61
|
+
maxDepth?: number;
|
|
62
|
+
[key: string]: unknown;
|
|
63
|
+
}>;
|
|
64
|
+
viewProps?: CustomViewFieldConfig;
|
|
65
|
+
/** Boutons spécifiques à cette vue (priment sur les actions globales) */
|
|
66
|
+
actions?: ShareablePreviewAction[];
|
|
67
|
+
}
|
|
68
|
+
interface ShareablePreviewProps {
|
|
69
|
+
data: unknown;
|
|
70
|
+
title?: string;
|
|
71
|
+
description?: string;
|
|
72
|
+
actions?: ShareablePreviewAction[];
|
|
73
|
+
shareUrl?: string;
|
|
74
|
+
className?: string;
|
|
75
|
+
maxHeight?: string;
|
|
76
|
+
mode?: "debug" | "user";
|
|
77
|
+
expandByDefault?: boolean;
|
|
78
|
+
trigger?: React$1.ReactElement;
|
|
79
|
+
triggerLabel?: string;
|
|
80
|
+
triggerClassName?: string;
|
|
81
|
+
defaultOpen?: boolean;
|
|
82
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
83
|
+
eyeDevMode?: "development" | "production";
|
|
84
|
+
/** Vue personnalisée unique (rétrocompatibilité) */
|
|
85
|
+
customView?: React$1.ComponentType<{
|
|
86
|
+
data: unknown;
|
|
87
|
+
className?: string;
|
|
88
|
+
expandByDefault?: boolean;
|
|
89
|
+
excludedKeys?: string[];
|
|
90
|
+
excludedNestedKeys?: string[];
|
|
91
|
+
includedKeys?: string[];
|
|
92
|
+
includedNestedKeys?: string[];
|
|
93
|
+
maxDepth?: number;
|
|
94
|
+
[key: string]: unknown;
|
|
95
|
+
}>;
|
|
96
|
+
customViewProps?: CustomViewFieldConfig;
|
|
97
|
+
/** Liste de vues personnalisées avec sélecteur (customViews prime sur customView) */
|
|
98
|
+
customViews?: CustomViewConfig[];
|
|
99
|
+
inline?: boolean;
|
|
100
|
+
labels?: Partial<Record<string, string>>;
|
|
101
|
+
onNotify?: (type: "success" | "error", key: string) => void;
|
|
102
|
+
}
|
|
103
|
+
declare function ShareablePreview({ data, title, description, actions, shareUrl, className, maxHeight, mode, expandByDefault, trigger, triggerLabel, triggerClassName, defaultOpen, onOpenChange, eyeDevMode, customView, customViewProps, customViews, inline, labels: labelsOverride, onNotify, }: ShareablePreviewProps): react_jsx_runtime.JSX.Element;
|
|
104
|
+
|
|
105
|
+
/** Options pour créer des boutons type approbation/confirmation */
|
|
106
|
+
interface CreatePreviewActionsOptions {
|
|
107
|
+
onConfirm: () => void;
|
|
108
|
+
onReject?: () => void;
|
|
109
|
+
onCancel?: () => void;
|
|
110
|
+
labels?: {
|
|
111
|
+
confirm?: string;
|
|
112
|
+
reject?: string;
|
|
113
|
+
cancel?: string;
|
|
114
|
+
};
|
|
115
|
+
withIndicatorOnConfirm?: boolean;
|
|
116
|
+
withPulseOnConfirm?: boolean;
|
|
117
|
+
order?: "confirm-first" | "cancel-first";
|
|
118
|
+
}
|
|
119
|
+
/** Helper pour créer les boutons super (ValidationButton) type transaction/approbation */
|
|
120
|
+
declare function createPreviewActions(options: CreatePreviewActionsOptions): ShareablePreviewAction[];
|
|
121
|
+
|
|
122
|
+
interface UserViewLabels {
|
|
123
|
+
yes?: string;
|
|
124
|
+
no?: string;
|
|
125
|
+
shareablePreviewEmptyList?: string;
|
|
126
|
+
shareablePreviewEmptyObject?: string;
|
|
127
|
+
shareablePreviewNoValue?: string;
|
|
128
|
+
shareablePreviewItemLabel?: string;
|
|
129
|
+
shareablePreviewEntriesCount?: string;
|
|
130
|
+
shareablePreviewArrayLabel?: string;
|
|
131
|
+
shareablePreviewNestedObjectLabel?: string;
|
|
132
|
+
}
|
|
133
|
+
interface UserViewProps extends Partial<FilterKeysOptions> {
|
|
134
|
+
data: unknown;
|
|
135
|
+
className?: string;
|
|
136
|
+
expandByDefault?: boolean;
|
|
137
|
+
labels?: UserViewLabels;
|
|
138
|
+
}
|
|
139
|
+
declare function UserView({ data, className, labels: labelsOverride, includedKeys, excludedKeys, includedNestedKeys, excludedNestedKeys, maxDepth, }: UserViewProps): react_jsx_runtime.JSX.Element;
|
|
140
|
+
|
|
141
|
+
interface DebugViewProps {
|
|
142
|
+
data: unknown;
|
|
143
|
+
className?: string;
|
|
144
|
+
maxDepthLabel?: string;
|
|
145
|
+
}
|
|
146
|
+
declare function DebugView({ data, className, maxDepthLabel, }: DebugViewProps): react_jsx_runtime.JSX.Element;
|
|
147
|
+
|
|
148
|
+
interface DataTreeNodeProps {
|
|
149
|
+
nodeKey: string;
|
|
150
|
+
value: unknown;
|
|
151
|
+
level?: number;
|
|
152
|
+
maxLevel?: number;
|
|
153
|
+
maxDepthLabel?: string;
|
|
154
|
+
}
|
|
155
|
+
declare function DataTreeNode({ nodeKey, value, level, maxLevel, maxDepthLabel, }: DataTreeNodeProps): react_jsx_runtime.JSX.Element;
|
|
156
|
+
|
|
157
|
+
declare const DEFAULT_LABELS: Record<string, string>;
|
|
158
|
+
|
|
159
|
+
export { type CreatePreviewActionsOptions, type CustomViewConfig, type CustomViewFieldConfig, DEFAULT_LABELS, DataTreeNode, DebugView, type FilterKeysOptions, ShareablePreview, type ShareablePreviewAction, type ShareablePreviewProps, UserView, type UserViewLabels, createPreviewActions, filterDataByKeys };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React$1, { ButtonHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ValidationButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
withPulse?: boolean;
|
|
7
|
+
withIndicator?: boolean;
|
|
8
|
+
variant?: "green" | "blue" | "purple" | "orange" | "red";
|
|
9
|
+
icon?: React.ComponentType<{
|
|
10
|
+
className?: string;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Filtre un objet ou tableau de données selon les clés incluses/exclues.
|
|
16
|
+
* - includedKeys / includedNestedKeys : whitelist (seules ces clés sont conservées)
|
|
17
|
+
* - excludedKeys / excludedNestedKeys : blacklist (ces clés sont retirées)
|
|
18
|
+
* La whitelist prime sur la blacklist si les deux sont fournies.
|
|
19
|
+
*/
|
|
20
|
+
interface FilterKeysOptions {
|
|
21
|
+
includedKeys?: string[];
|
|
22
|
+
excludedKeys?: string[];
|
|
23
|
+
includedNestedKeys?: string[];
|
|
24
|
+
excludedNestedKeys?: string[];
|
|
25
|
+
maxDepth?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Filtre data selon les options de clés.
|
|
29
|
+
* Retourne une copie filtrée sans modifier l'original.
|
|
30
|
+
*/
|
|
31
|
+
declare function filterDataByKeys<T>(data: T, options: FilterKeysOptions): T;
|
|
32
|
+
|
|
33
|
+
type ShareablePreviewAction = {
|
|
34
|
+
label: string;
|
|
35
|
+
icon?: string | React$1.ComponentType<{
|
|
36
|
+
className?: string;
|
|
37
|
+
}> | React$1.ReactElement;
|
|
38
|
+
onClick: () => void;
|
|
39
|
+
variant?: ValidationButtonProps["variant"];
|
|
40
|
+
withPulse?: boolean;
|
|
41
|
+
withIndicator?: boolean;
|
|
42
|
+
buttonClassName?: string;
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
/** Ordre d'affichage (plus petit = à gauche) */
|
|
45
|
+
order?: number;
|
|
46
|
+
};
|
|
47
|
+
interface CustomViewFieldConfig extends FilterKeysOptions {
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
}
|
|
50
|
+
interface CustomViewConfig {
|
|
51
|
+
id: string;
|
|
52
|
+
label: string;
|
|
53
|
+
view: React$1.ComponentType<{
|
|
54
|
+
data: unknown;
|
|
55
|
+
className?: string;
|
|
56
|
+
expandByDefault?: boolean;
|
|
57
|
+
excludedKeys?: string[];
|
|
58
|
+
excludedNestedKeys?: string[];
|
|
59
|
+
includedKeys?: string[];
|
|
60
|
+
includedNestedKeys?: string[];
|
|
61
|
+
maxDepth?: number;
|
|
62
|
+
[key: string]: unknown;
|
|
63
|
+
}>;
|
|
64
|
+
viewProps?: CustomViewFieldConfig;
|
|
65
|
+
/** Boutons spécifiques à cette vue (priment sur les actions globales) */
|
|
66
|
+
actions?: ShareablePreviewAction[];
|
|
67
|
+
}
|
|
68
|
+
interface ShareablePreviewProps {
|
|
69
|
+
data: unknown;
|
|
70
|
+
title?: string;
|
|
71
|
+
description?: string;
|
|
72
|
+
actions?: ShareablePreviewAction[];
|
|
73
|
+
shareUrl?: string;
|
|
74
|
+
className?: string;
|
|
75
|
+
maxHeight?: string;
|
|
76
|
+
mode?: "debug" | "user";
|
|
77
|
+
expandByDefault?: boolean;
|
|
78
|
+
trigger?: React$1.ReactElement;
|
|
79
|
+
triggerLabel?: string;
|
|
80
|
+
triggerClassName?: string;
|
|
81
|
+
defaultOpen?: boolean;
|
|
82
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
83
|
+
eyeDevMode?: "development" | "production";
|
|
84
|
+
/** Vue personnalisée unique (rétrocompatibilité) */
|
|
85
|
+
customView?: React$1.ComponentType<{
|
|
86
|
+
data: unknown;
|
|
87
|
+
className?: string;
|
|
88
|
+
expandByDefault?: boolean;
|
|
89
|
+
excludedKeys?: string[];
|
|
90
|
+
excludedNestedKeys?: string[];
|
|
91
|
+
includedKeys?: string[];
|
|
92
|
+
includedNestedKeys?: string[];
|
|
93
|
+
maxDepth?: number;
|
|
94
|
+
[key: string]: unknown;
|
|
95
|
+
}>;
|
|
96
|
+
customViewProps?: CustomViewFieldConfig;
|
|
97
|
+
/** Liste de vues personnalisées avec sélecteur (customViews prime sur customView) */
|
|
98
|
+
customViews?: CustomViewConfig[];
|
|
99
|
+
inline?: boolean;
|
|
100
|
+
labels?: Partial<Record<string, string>>;
|
|
101
|
+
onNotify?: (type: "success" | "error", key: string) => void;
|
|
102
|
+
}
|
|
103
|
+
declare function ShareablePreview({ data, title, description, actions, shareUrl, className, maxHeight, mode, expandByDefault, trigger, triggerLabel, triggerClassName, defaultOpen, onOpenChange, eyeDevMode, customView, customViewProps, customViews, inline, labels: labelsOverride, onNotify, }: ShareablePreviewProps): react_jsx_runtime.JSX.Element;
|
|
104
|
+
|
|
105
|
+
/** Options pour créer des boutons type approbation/confirmation */
|
|
106
|
+
interface CreatePreviewActionsOptions {
|
|
107
|
+
onConfirm: () => void;
|
|
108
|
+
onReject?: () => void;
|
|
109
|
+
onCancel?: () => void;
|
|
110
|
+
labels?: {
|
|
111
|
+
confirm?: string;
|
|
112
|
+
reject?: string;
|
|
113
|
+
cancel?: string;
|
|
114
|
+
};
|
|
115
|
+
withIndicatorOnConfirm?: boolean;
|
|
116
|
+
withPulseOnConfirm?: boolean;
|
|
117
|
+
order?: "confirm-first" | "cancel-first";
|
|
118
|
+
}
|
|
119
|
+
/** Helper pour créer les boutons super (ValidationButton) type transaction/approbation */
|
|
120
|
+
declare function createPreviewActions(options: CreatePreviewActionsOptions): ShareablePreviewAction[];
|
|
121
|
+
|
|
122
|
+
interface UserViewLabels {
|
|
123
|
+
yes?: string;
|
|
124
|
+
no?: string;
|
|
125
|
+
shareablePreviewEmptyList?: string;
|
|
126
|
+
shareablePreviewEmptyObject?: string;
|
|
127
|
+
shareablePreviewNoValue?: string;
|
|
128
|
+
shareablePreviewItemLabel?: string;
|
|
129
|
+
shareablePreviewEntriesCount?: string;
|
|
130
|
+
shareablePreviewArrayLabel?: string;
|
|
131
|
+
shareablePreviewNestedObjectLabel?: string;
|
|
132
|
+
}
|
|
133
|
+
interface UserViewProps extends Partial<FilterKeysOptions> {
|
|
134
|
+
data: unknown;
|
|
135
|
+
className?: string;
|
|
136
|
+
expandByDefault?: boolean;
|
|
137
|
+
labels?: UserViewLabels;
|
|
138
|
+
}
|
|
139
|
+
declare function UserView({ data, className, labels: labelsOverride, includedKeys, excludedKeys, includedNestedKeys, excludedNestedKeys, maxDepth, }: UserViewProps): react_jsx_runtime.JSX.Element;
|
|
140
|
+
|
|
141
|
+
interface DebugViewProps {
|
|
142
|
+
data: unknown;
|
|
143
|
+
className?: string;
|
|
144
|
+
maxDepthLabel?: string;
|
|
145
|
+
}
|
|
146
|
+
declare function DebugView({ data, className, maxDepthLabel, }: DebugViewProps): react_jsx_runtime.JSX.Element;
|
|
147
|
+
|
|
148
|
+
interface DataTreeNodeProps {
|
|
149
|
+
nodeKey: string;
|
|
150
|
+
value: unknown;
|
|
151
|
+
level?: number;
|
|
152
|
+
maxLevel?: number;
|
|
153
|
+
maxDepthLabel?: string;
|
|
154
|
+
}
|
|
155
|
+
declare function DataTreeNode({ nodeKey, value, level, maxLevel, maxDepthLabel, }: DataTreeNodeProps): react_jsx_runtime.JSX.Element;
|
|
156
|
+
|
|
157
|
+
declare const DEFAULT_LABELS: Record<string, string>;
|
|
158
|
+
|
|
159
|
+
export { type CreatePreviewActionsOptions, type CustomViewConfig, type CustomViewFieldConfig, DEFAULT_LABELS, DataTreeNode, DebugView, type FilterKeysOptions, ShareablePreview, type ShareablePreviewAction, type ShareablePreviewProps, UserView, type UserViewLabels, createPreviewActions, filterDataByKeys };
|