@useinsider/guido 1.4.4-beta.b4adc85 → 1.4.4
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 +664 -295
- package/dist/components/Guido.vue.js +1 -1
- package/dist/components/Guido.vue2.js +89 -63
- package/dist/components/organisms/email-preview/desktop-preview/EmailHeaderInfo.vue2.js +13 -13
- package/dist/components/organisms/email-preview/mobile-preview/InboxView.vue.js +5 -5
- package/dist/components/organisms/email-preview/mobile-preview/InboxView.vue2.js +13 -13
- package/dist/components/organisms/header/LeftSlot.vue.js +1 -1
- package/dist/components/organisms/header/LeftSlot.vue2.js +15 -18
- package/dist/components/organisms/header/RightSlot.vue.js +10 -10
- package/dist/components/organisms/onboarding/NewVersionPopup.vue2.js +19 -22
- package/dist/components/organisms/unsubscribe/UnsubscribeBreadcrumb.vue.js +4 -4
- package/dist/components/organisms/unsubscribe/UnsubscribeBreadcrumb.vue2.js +8 -8
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue.js +3 -3
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue2.js +17 -17
- package/dist/components/organisms/unsubscribe/UnsubscribeWrapper.vue.js +10 -10
- package/dist/composables/useBlocksConfig.js +20 -23
- package/dist/composables/useConfig.js +5 -51
- package/dist/composables/useHtmlCompiler.js +19 -20
- package/dist/composables/useHtmlValidator.js +41 -41
- package/dist/composables/usePartner.js +9 -19
- package/dist/composables/useStripo.js +11 -11
- package/dist/composables/useTranslations.js +2 -3
- package/dist/config/compiler/unsubscribeCompilerRules.js +1 -1
- package/dist/enums/defaults.js +67 -3
- package/dist/enums/unsubscribe.js +20 -23
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +11 -12
- package/dist/guido.css +1 -1
- package/dist/library.js +2 -12
- package/dist/node_modules/lodash-es/_apply.js +16 -0
- package/dist/node_modules/lodash-es/_arrayLikeKeys.js +10 -10
- package/dist/node_modules/lodash-es/_assignMergeValue.js +8 -0
- package/dist/node_modules/lodash-es/_assignValue.js +10 -0
- package/dist/node_modules/lodash-es/_baseAssignValue.js +12 -0
- package/dist/node_modules/lodash-es/_baseCreate.js +17 -0
- package/dist/node_modules/lodash-es/_baseKeysIn.js +15 -0
- package/dist/node_modules/lodash-es/_baseMerge.js +20 -0
- package/dist/node_modules/lodash-es/_baseMergeDeep.js +31 -0
- package/dist/node_modules/lodash-es/_baseRest.js +9 -0
- package/dist/node_modules/lodash-es/_baseSetToString.js +14 -0
- package/dist/node_modules/lodash-es/_cloneArrayBuffer.js +8 -0
- package/dist/node_modules/lodash-es/_cloneBuffer.js +9 -0
- package/dist/node_modules/lodash-es/_cloneTypedArray.js +8 -0
- package/dist/node_modules/lodash-es/_copyArray.js +9 -0
- package/dist/node_modules/lodash-es/_copyObject.js +14 -0
- package/dist/node_modules/lodash-es/_createAssigner.js +15 -0
- package/dist/node_modules/lodash-es/_defineProperty.js +11 -0
- package/dist/node_modules/lodash-es/_getPrototype.js +5 -0
- package/dist/node_modules/lodash-es/_initCloneObject.js +9 -0
- package/dist/node_modules/lodash-es/_nativeKeysIn.js +10 -0
- package/dist/node_modules/lodash-es/_overRest.js +15 -0
- package/dist/node_modules/lodash-es/_safeGet.js +7 -0
- package/dist/node_modules/lodash-es/_setToString.js +6 -0
- package/dist/node_modules/lodash-es/_shortOut.js +16 -0
- package/dist/node_modules/lodash-es/constant.js +8 -0
- package/dist/node_modules/lodash-es/isArrayLikeObject.js +8 -0
- package/dist/node_modules/lodash-es/isPlainObject.js +16 -0
- package/dist/node_modules/lodash-es/keysIn.js +9 -0
- package/dist/node_modules/lodash-es/merge.js +8 -0
- package/dist/node_modules/lodash-es/toPlainObject.js +8 -0
- package/dist/node_modules/valibot/dist/index.js +103 -476
- package/dist/services/templateLibraryApi.js +18 -18
- package/dist/src/@types/generic.d.ts +45 -4
- package/dist/src/components/Guido.vue.d.ts +12 -13
- package/dist/src/components/wrappers/WpModal.vue.d.ts +1 -1
- package/dist/src/composables/useConfig.d.ts +2 -184
- package/dist/src/composables/usePartner.d.ts +0 -8
- package/dist/src/enums/defaults.d.ts +6 -4
- package/dist/src/enums/unsubscribe.d.ts +1 -5
- package/dist/src/library.d.ts +1 -3
- package/dist/src/stores/config.d.ts +102 -1547
- package/dist/stores/config.js +9 -141
- package/package.json +1 -1
- package/dist/@types/config/defaults.js +0 -44
- package/dist/@types/config/schemas.js +0 -229
- package/dist/@types/config/validator.js +0 -56
- package/dist/src/@types/config/defaults.d.ts +0 -68
- package/dist/src/@types/config/index.d.ts +0 -14
- package/dist/src/@types/config/schemas.d.ts +0 -505
- package/dist/src/@types/config/types.d.ts +0 -142
- package/dist/src/@types/config/validator.d.ts +0 -119
package/README.md
CHANGED
|
@@ -4,420 +4,789 @@
|
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
# @useinsider/guido
|
|
8
9
|
|
|
9
|
-
Guido is a Vue 2 + TypeScript wrapper for the Stripo Email Editor plugin. Easily embed the professional email editor in your Vue applications with a clean,
|
|
10
|
+
Guido is a Vue 2 + TypeScript wrapper for the Stripo Email Editor plugin. Easily embed the professional email editor in your Vue applications with a clean, customizable interface.
|
|
10
11
|
|
|
11
|
-
##
|
|
12
|
+
## 📦 Install
|
|
12
13
|
|
|
13
14
|
```bash
|
|
14
15
|
npm install @useinsider/guido
|
|
15
16
|
```
|
|
16
|
-
|
|
17
17
|
### Prerequisites
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
shared: {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
18
|
+
🍍 Your project should have `pinia`
|
|
19
|
+
You need to be sure those lines added in your config file:
|
|
20
|
+
|
|
21
|
+
ℹ️ It helps to optimize your dependencies and sharing by Guido. This is why Guido pretty fast and tiny.
|
|
22
|
+
|
|
23
|
+
#### For Webpack
|
|
24
|
+
`/webpack.config.js` or `/vue.config.js`
|
|
25
|
+
```js
|
|
26
|
+
// ... Previous Configs
|
|
27
|
+
shared: {
|
|
28
|
+
vue: { singleton: true },
|
|
29
|
+
pinia: { singleton: true },
|
|
30
|
+
},
|
|
31
|
+
// ... Upcoming Configs
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
##### For Vite:
|
|
35
|
+
`/vite.config.js`
|
|
36
|
+
```js
|
|
37
|
+
// ... Previous Configs
|
|
38
|
+
resolve: {
|
|
39
|
+
dedupe: ['vue', 'pinia'],
|
|
40
|
+
},
|
|
41
|
+
// ... Upcoming Configs
|
|
42
|
+
```
|
|
40
43
|
---
|
|
44
|
+
## 🚀 Usage
|
|
41
45
|
|
|
42
|
-
|
|
46
|
+
### Basic Usage
|
|
43
47
|
|
|
44
|
-
```
|
|
48
|
+
```html
|
|
45
49
|
<template>
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
<div>
|
|
51
|
+
<Guido
|
|
52
|
+
ref="guidoEditor"
|
|
53
|
+
:template-id="templateId"
|
|
54
|
+
:user-id="userId"
|
|
55
|
+
:migration-date="migrationDate"
|
|
56
|
+
:guido-config="guidoConfig"
|
|
57
|
+
:html="initialHtml"
|
|
58
|
+
:css="initialCss"
|
|
59
|
+
@dynamic-content:open="handleDynamicContentOpen"
|
|
60
|
+
@back="handleBack"
|
|
61
|
+
@save:start="handleSaveStart"
|
|
62
|
+
@save:complete="handleSaveComplete"
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
53
65
|
</template>
|
|
54
66
|
|
|
55
|
-
<script
|
|
56
|
-
import { ref } from 'vue';
|
|
67
|
+
<script lang="ts">
|
|
57
68
|
import { Guido } from '@useinsider/guido';
|
|
58
|
-
import type { GuidoConfigInput } from '@useinsider/guido';
|
|
59
|
-
|
|
60
|
-
const guidoRef = ref<InstanceType<typeof Guido> | null>(null);
|
|
61
69
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
userId: 'user-456',
|
|
66
|
-
},
|
|
67
|
-
partner: {
|
|
68
|
-
name: 'your-partner-name',
|
|
70
|
+
export default {
|
|
71
|
+
components: {
|
|
72
|
+
Guido
|
|
69
73
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
data() {
|
|
75
|
+
return {
|
|
76
|
+
templateId: 'template-123',
|
|
77
|
+
userId: 'user-456',
|
|
78
|
+
migrationDate: 1699488000,
|
|
79
|
+
initialHtml: '<p>Initial HTML content</p>',
|
|
80
|
+
initialCss: 'p { color: #333; }',
|
|
81
|
+
guidoConfig: {
|
|
82
|
+
translationsPath: 'window.trans.en',
|
|
83
|
+
htmlCompilerRules: [],
|
|
84
|
+
ignoreDefaultHtmlCompilerRules: false,
|
|
85
|
+
backButtonLabel?: "Back to Design",
|
|
86
|
+
features: {
|
|
87
|
+
dynamicContent: true,
|
|
88
|
+
saveAsTemplate: true,
|
|
89
|
+
versionHistory: true,
|
|
90
|
+
testMessage: true
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
dynamicContentModalVisible: false
|
|
94
|
+
};
|
|
73
95
|
},
|
|
74
|
-
});
|
|
75
96
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
97
|
+
methods: {
|
|
98
|
+
handleDynamicContentOpen(detail) {
|
|
99
|
+
console.log('Dynamic content requested:', detail);
|
|
100
|
+
this.dynamicContentModalVisible = true;
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
handleBack() {
|
|
104
|
+
console.log('User clicked back button');
|
|
105
|
+
// Handle navigation back
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
handleSaveStart() {
|
|
109
|
+
console.log('Save process started');
|
|
110
|
+
// Show loading indicator
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
handleSaveComplete(template) {
|
|
114
|
+
console.log('Save completed:', template);
|
|
115
|
+
// Handle saved template data
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// ⚠️ Your own Dynamic Content Modal should have this id: #guido-dynamic-content-modal
|
|
119
|
+
handleDynamicContentInsert() {
|
|
120
|
+
this.$refs.guidoEditor?.dynamicContent.insert({
|
|
121
|
+
text: 'Display Text',
|
|
122
|
+
value: 'actual-value',
|
|
123
|
+
fallback: 'Fallback Text'
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
this.dynamicContentModalVisible = false;
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
// ⚠️ It's mandatory. There is no way to understand if user closes the modal without selection.
|
|
130
|
+
handleDynamicContentClose() {
|
|
131
|
+
this.$refs.guidoEditor?.dynamicContent.close();
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
// If you need to trigger save manually like leave modal cases, you can use this method.
|
|
135
|
+
save () {
|
|
136
|
+
this.$refs.guidoEditor?.saveSilent();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
79
140
|
</script>
|
|
80
141
|
```
|
|
81
142
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
## Configuration
|
|
85
|
-
|
|
86
|
-
Guido uses a single, validated `config` prop organized by domain:
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
import type { GuidoConfigInput } from '@useinsider/guido';
|
|
90
|
-
|
|
91
|
-
const config: GuidoConfigInput = {
|
|
92
|
-
// Required: Identity
|
|
93
|
-
identity: {
|
|
94
|
-
templateId: string, // Required - Template identifier
|
|
95
|
-
userId: string, // Required - User identifier
|
|
96
|
-
variationId?: string, // Optional - A/B test variation
|
|
97
|
-
},
|
|
143
|
+
## 📚 API
|
|
98
144
|
|
|
99
|
-
|
|
100
|
-
partner: {
|
|
101
|
-
name: string, // Required - Partner name
|
|
102
|
-
productType?: number, // Optional - Default: 60 (Email)
|
|
103
|
-
messageType?: number, // Optional - Default: 1 (Promotional)
|
|
104
|
-
username?: string, // Optional - Default: 'Guido User'
|
|
105
|
-
},
|
|
145
|
+
### Guido Component Props
|
|
106
146
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
147
|
+
| Prop | Type | Required | Default | Description |
|
|
148
|
+
|------|------|----------|---------|-------------|
|
|
149
|
+
| `templateId` | `string` | ✅ | - | Unique identifier for the email template |
|
|
150
|
+
| `userId` | `string` | ✅ | - | Unique identifier for the user |
|
|
151
|
+
| `guidoConfig` | `GuidoConfig` | ✅ | - | Configuration object for the editor |
|
|
152
|
+
| `migrationDate` | `number` | ✅ | - | Stripo migration date in Unix timestamp (seconds). Retrieved from backend `/partner-settings` endpoint as `migrationDate`. Used for onboarding process |
|
|
153
|
+
| `partnerName` | `string` | ⚪ | From URL host | Partner identifier |
|
|
154
|
+
| `productType` | `string` | ⚪ | From URL path | Product type identifier |
|
|
155
|
+
| `username` | `string` | ⚪ | `'Guido User'` | Display name for the user |
|
|
156
|
+
| `html` | `string` | ⚪ | `''` | Initial HTML content for the template |
|
|
157
|
+
| `css` | `string` | ⚪ | `''` | Initial CSS styles for the template |
|
|
114
158
|
|
|
115
|
-
|
|
116
|
-
editor?: {
|
|
117
|
-
locale?: string, // Default: 'en'
|
|
118
|
-
translationsPath?: string, // Default: 'window.trans.en'
|
|
119
|
-
migrationDate?: number, // Stripo migration timestamp
|
|
120
|
-
emailHeader?: {
|
|
121
|
-
senderName?: string,
|
|
122
|
-
subject?: string,
|
|
123
|
-
},
|
|
124
|
-
},
|
|
159
|
+
### Guido Component Events
|
|
125
160
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
161
|
+
| Event | Payload | Description |
|
|
162
|
+
|-------|---------|-------------|
|
|
163
|
+
| `dynamic-content:open` | `DynamicContent \| null` | Fired when user requests to insert dynamic content |
|
|
164
|
+
| `back` | - | Fired when user clicks the back button |
|
|
165
|
+
| `save:start` | - | Fired when the save process begins |
|
|
166
|
+
| `save:complete` | `Omit<Template, 'forceRecreate'>` | Fired when template is successfully saved |
|
|
167
|
+
| `on-change` | void | It Fires once for managing leave modal etc. |
|
|
168
|
+
| `ready` | void | Fired when the editor is ready and template is loaded |
|
|
169
|
+
| `onboarding-finished` | void | Fired when the onboarding popup is dismissed or completed, allowing parent applications to track onboarding state |
|
|
170
|
+
| `test-email:click` | - | Fired when user clicks the test email button in the header |
|
|
171
|
+
|
|
172
|
+
### Guido Exposed Methods
|
|
173
|
+
```typescript
|
|
174
|
+
dynamicContent.insert(DynamicContent);
|
|
175
|
+
dynamicContent.close();
|
|
176
|
+
saveSilent();
|
|
177
|
+
```
|
|
131
178
|
|
|
132
|
-
|
|
133
|
-
features?: {
|
|
134
|
-
dynamicContent?: boolean, // Default: true
|
|
135
|
-
saveAsTemplate?: boolean, // Default: true
|
|
136
|
-
versionHistory?: boolean, // Default: true
|
|
137
|
-
testMessage?: boolean, // Default: true
|
|
138
|
-
displayConditions?: boolean, // Default: true
|
|
139
|
-
unsubscribe?: boolean, // Default: true
|
|
140
|
-
},
|
|
179
|
+
### Guido Interfaces
|
|
141
180
|
|
|
142
|
-
|
|
181
|
+
```typescript
|
|
182
|
+
interface GuidoConfig {
|
|
183
|
+
translationsPath: string;
|
|
184
|
+
htmlCompilerRules?: CompilerRule[];
|
|
185
|
+
ignoreDefaultHtmlCompilerRules?: boolean;
|
|
186
|
+
useHeader: boolean
|
|
187
|
+
emailHeader: {
|
|
188
|
+
senderName: string;
|
|
189
|
+
subject: string;
|
|
190
|
+
};
|
|
191
|
+
partner: {
|
|
192
|
+
partnerName: string;
|
|
193
|
+
productType: number;
|
|
194
|
+
messageType: number;
|
|
195
|
+
};
|
|
196
|
+
features: {
|
|
197
|
+
dynamicContent: boolean;
|
|
198
|
+
saveAsTemplate: boolean;
|
|
199
|
+
versionHistory: boolean;
|
|
200
|
+
testMessage: boolean;
|
|
201
|
+
displayConditions: boolean;
|
|
202
|
+
};
|
|
143
203
|
blocks?: {
|
|
144
|
-
excludeDefaults?:
|
|
145
|
-
includeCustoms?:
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Optional: HTML compiler
|
|
149
|
-
compiler?: {
|
|
150
|
-
customRules?: CompilerRule[],
|
|
151
|
-
ignoreDefaultRules?: boolean, // Default: false
|
|
152
|
-
},
|
|
153
|
-
};
|
|
204
|
+
excludeDefaults?: GuidoBlockType[];
|
|
205
|
+
includeCustoms?: GuidoCustomBlockType[];
|
|
206
|
+
};
|
|
207
|
+
}
|
|
154
208
|
```
|
|
155
209
|
|
|
210
|
+
| Property | Type | Default | Description |
|
|
211
|
+
|----------|------|---------|-------------|
|
|
212
|
+
| `translationsPath` | `string` | `'window.trans.en'` | JavaScript path to the translations object |
|
|
213
|
+
| `htmlCompilerRules` | `CompilerRule[]` | `[]` | Additional compiler rules to apply to HTML content. See [HTML Compiler Rules](#-html-compiler-rules) section below |
|
|
214
|
+
| `ignoreDefaultHtmlCompilerRules` | `boolean` | `false` | Skip default compiler rules and only use custom rules. Default rules: `src/config/compiler/htmlCompilerRules.ts` |
|
|
215
|
+
| `useHeader` | `boolean` | `true` | Adds extra spaces to height for adjusting. If you don't use Inone Page header, override as `false` |
|
|
216
|
+
| `features` | `Features` | `{ dynamicContent: true, saveAsTemplate: true, versionHistory: true }` | Feature flags to enable/disable editor functionality |
|
|
217
|
+
| `features.dynamicContent` | `boolean` | `true` | Enable dynamic content insertion feature |
|
|
218
|
+
| `features.saveAsTemplate` | `boolean` | `true` | Enable save as template feature |
|
|
219
|
+
| `features.versionHistory` | `boolean` | `true` | Enable version history feature |
|
|
220
|
+
| `features.displayConditions` | `boolean` | `true` | Enable display conditions |
|
|
221
|
+
| `blocks` | `BlocksConfig` | `{ excludeDefaults: [], includeCustoms: [] }` | Block configuration for excluding default blocks and including custom blocks. See [Blocks Configuration](#-blocks-configuration) section below |
|
|
222
|
+
| `blocks.excludeDefaults` | `GuidoBlockType[]` | `[]` | Array of default Stripo blocks to exclude from the editor |
|
|
223
|
+
| `blocks.includeCustoms` | `GuidoCustomBlockType[]` | `[]` | Array of custom blocks to include in the editor |
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
interface DynamicContent {
|
|
227
|
+
value: string;
|
|
228
|
+
text: string;
|
|
229
|
+
fallback?: string;
|
|
230
|
+
}
|
|
231
|
+
```
|
|
156
232
|
---
|
|
157
233
|
|
|
158
|
-
|
|
234
|
+
| Property | Type | Default | Description |
|
|
235
|
+
|----------|------|---------|-------------|
|
|
236
|
+
| `value` | `string` | '' | Value of the dynamic content |
|
|
237
|
+
| `text` | `string` | '' | Visible value of the dynamic content |
|
|
238
|
+
| `fallback?` | `string` | '' | Fallback value of the dynamic content. Optional |
|
|
159
239
|
|
|
160
|
-
|
|
161
|
-
|-------|---------|-------------|
|
|
162
|
-
| `ready` | - | Editor is loaded and ready |
|
|
163
|
-
| `dynamic-content:open` | `DynamicContent \| null` | User wants to insert dynamic content |
|
|
164
|
-
| `back` | - | Back button clicked |
|
|
165
|
-
| `save:start` | - | Save process started |
|
|
166
|
-
| `save:complete` | `Template` | Save completed successfully |
|
|
167
|
-
| `on-change` | - | Template was modified |
|
|
168
|
-
| `test-email:click` | - | Test email button clicked |
|
|
169
|
-
| `onboarding-finished` | - | Onboarding popup dismissed |
|
|
240
|
+
## 🧱 Blocks Configuration
|
|
170
241
|
|
|
171
|
-
|
|
242
|
+
Guido allows you to customize which blocks are available in the editor. You can exclude default Stripo blocks and selectively include custom blocks to create tailored editing experiences for different product types.
|
|
243
|
+
|
|
244
|
+
### Block Types
|
|
245
|
+
|
|
246
|
+
#### Default Blocks (GuidoBlockType)
|
|
172
247
|
|
|
173
|
-
|
|
248
|
+
These are the standard Stripo email editor blocks that can be excluded:
|
|
174
249
|
|
|
175
250
|
```typescript
|
|
176
|
-
|
|
251
|
+
type GuidoBlockType =
|
|
252
|
+
| 'amp-accordion' // AMP accordion component
|
|
253
|
+
| 'amp-carousel' // AMP image carousel
|
|
254
|
+
| 'amp-form-controls' // AMP form elements
|
|
255
|
+
| 'banner-block' // Banner/hero section
|
|
256
|
+
| 'button-block' // Call-to-action buttons
|
|
257
|
+
| 'html-block' // Custom HTML
|
|
258
|
+
| 'image-block' // Image elements
|
|
259
|
+
| 'menu-block' // Navigation menu
|
|
260
|
+
| 'social-block' // Social media links
|
|
261
|
+
| 'spacer-block' // Vertical spacing
|
|
262
|
+
| 'text-block' // Text content
|
|
263
|
+
| 'timer-block' // Countdown timer
|
|
264
|
+
| 'video-block' // Video embeds
|
|
265
|
+
```
|
|
177
266
|
|
|
178
|
-
|
|
179
|
-
guidoRef.value?.dynamicContent.insert({
|
|
180
|
-
text: 'Display Name',
|
|
181
|
-
value: 'variable_name',
|
|
182
|
-
fallback: 'Default Value',
|
|
183
|
-
});
|
|
267
|
+
#### Custom Blocks (GuidoCustomBlockType)
|
|
184
268
|
|
|
185
|
-
|
|
186
|
-
guidoRef.value?.dynamicContent.close();
|
|
269
|
+
These are custom blocks that can be selectively included:
|
|
187
270
|
|
|
188
|
-
|
|
189
|
-
|
|
271
|
+
```typescript
|
|
272
|
+
type GuidoCustomBlockType =
|
|
273
|
+
| 'dynamic-content' // Dynamic content merge tags
|
|
274
|
+
| 'checkbox-block' // Checkbox form input
|
|
275
|
+
| 'radio-button-block' // Radio button form input
|
|
276
|
+
| 'recommendation-block' // Product recommendations
|
|
277
|
+
| 'unsubscribe-block' // Unsubscribe link
|
|
278
|
+
| 'coupon-block' // Coupon/promo code
|
|
279
|
+
| 'items-block' // Cart items display
|
|
190
280
|
```
|
|
191
281
|
|
|
192
|
-
|
|
282
|
+
### Configuration Examples
|
|
193
283
|
|
|
194
|
-
|
|
284
|
+
#### Example 1: Exclude Specific Default Blocks
|
|
195
285
|
|
|
196
|
-
|
|
286
|
+
Disable button, image, and video blocks while keeping all custom blocks:
|
|
197
287
|
|
|
198
288
|
```typescript
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
| 'timer-block'
|
|
212
|
-
| 'video-block';
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Custom Blocks (opt-in)
|
|
216
|
-
|
|
217
|
-
```typescript
|
|
218
|
-
type CustomBlockType =
|
|
219
|
-
| 'dynamic-content'
|
|
220
|
-
| 'checkbox-block'
|
|
221
|
-
| 'radio-button-block'
|
|
222
|
-
| 'recommendation-block'
|
|
223
|
-
| 'unsubscribe-block'
|
|
224
|
-
| 'coupon-block'
|
|
225
|
-
| 'items-block';
|
|
289
|
+
const guidoConfig = {
|
|
290
|
+
translationsPath: 'window.trans.en',
|
|
291
|
+
features: {
|
|
292
|
+
dynamicContent: true,
|
|
293
|
+
saveAsTemplate: true,
|
|
294
|
+
versionHistory: true,
|
|
295
|
+
testMessage: true
|
|
296
|
+
},
|
|
297
|
+
blocks: {
|
|
298
|
+
excludeDefaults: ['button-block', 'image-block', 'video-block']
|
|
299
|
+
}
|
|
300
|
+
};
|
|
226
301
|
```
|
|
227
302
|
|
|
228
|
-
|
|
303
|
+
**Result:**
|
|
304
|
+
- Button, Image, Video blocks disabled
|
|
305
|
+
- All other default blocks enabled
|
|
306
|
+
- All custom blocks are disabled.
|
|
307
|
+
|
|
308
|
+
#### Example 2: Include Only Specific Custom Blocks
|
|
309
|
+
|
|
310
|
+
Enable only coupon and recommendation blocks:
|
|
229
311
|
|
|
230
312
|
```typescript
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
313
|
+
const guidoConfig = {
|
|
314
|
+
translationsPath: 'window.trans.en',
|
|
315
|
+
features: {
|
|
316
|
+
dynamicContent: true,
|
|
317
|
+
saveAsTemplate: true,
|
|
318
|
+
versionHistory: true,
|
|
319
|
+
testMessage: true
|
|
237
320
|
},
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
// Include custom blocks
|
|
241
|
-
const config: GuidoConfigInput = {
|
|
242
|
-
identity: { templateId: 'tpl-123', userId: 'user-456' },
|
|
243
|
-
partner: { name: 'partner' },
|
|
244
321
|
blocks: {
|
|
245
|
-
includeCustoms: ['
|
|
246
|
-
}
|
|
322
|
+
includeCustoms: ['coupon-block', 'recommendation-block']
|
|
323
|
+
}
|
|
247
324
|
};
|
|
248
325
|
```
|
|
249
326
|
|
|
250
|
-
|
|
327
|
+
**Result:**
|
|
328
|
+
- All default blocks enabled
|
|
329
|
+
- Only Coupon and Recommendation extensions enabled.
|
|
330
|
+
- Other custom blocks are disabled
|
|
251
331
|
|
|
252
|
-
|
|
332
|
+
### Default Behavior
|
|
253
333
|
|
|
254
|
-
|
|
334
|
+
When `blocks` is not provided or is `undefined`:
|
|
255
335
|
|
|
256
336
|
```typescript
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
id: 'replace-domain',
|
|
265
|
-
type: 'replace',
|
|
266
|
-
search: 'old-domain.com',
|
|
267
|
-
replacement: 'new-domain.com',
|
|
268
|
-
priority: 10,
|
|
269
|
-
},
|
|
270
|
-
// Regex rule
|
|
271
|
-
{
|
|
272
|
-
id: 'remove-comments',
|
|
273
|
-
type: 'regex',
|
|
274
|
-
pattern: '<!--.*?-->',
|
|
275
|
-
replacement: '',
|
|
276
|
-
flags: 'g',
|
|
277
|
-
priority: 20,
|
|
278
|
-
},
|
|
279
|
-
// Custom processor
|
|
280
|
-
{
|
|
281
|
-
id: 'add-tracking',
|
|
282
|
-
type: 'custom',
|
|
283
|
-
processor: (html) => html.replace('</body>', '<img src="track.gif"/></body>'),
|
|
284
|
-
priority: 30,
|
|
285
|
-
},
|
|
286
|
-
],
|
|
287
|
-
ignoreDefaultRules: false, // Set true to skip built-in rules
|
|
337
|
+
const guidoConfig = {
|
|
338
|
+
translationsPath: 'window.trans.en',
|
|
339
|
+
features: {
|
|
340
|
+
dynamicContent: true,
|
|
341
|
+
saveAsTemplate: true,
|
|
342
|
+
versionHistory: true,
|
|
343
|
+
testMessage: true
|
|
288
344
|
},
|
|
345
|
+
// No blocks config
|
|
289
346
|
};
|
|
290
347
|
```
|
|
291
348
|
|
|
292
|
-
|
|
349
|
+
**Result:**
|
|
350
|
+
- All 13 default Stripo blocks enabled
|
|
351
|
+
- All custom blocks are disabled.
|
|
352
|
+
|
|
353
|
+
### Block Configuration Interface
|
|
293
354
|
|
|
294
|
-
|
|
355
|
+
```typescript
|
|
356
|
+
interface BlocksConfig {
|
|
357
|
+
excludeDefaults?: GuidoBlockType[];
|
|
358
|
+
includeCustoms?: GuidoCustomBlockType[];
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### TypeScript Types
|
|
363
|
+
|
|
364
|
+
The library exports the following TypeScript types:
|
|
295
365
|
|
|
296
366
|
```typescript
|
|
297
|
-
//
|
|
367
|
+
// Main component
|
|
298
368
|
import { Guido } from '@useinsider/guido';
|
|
299
369
|
|
|
300
370
|
// Types
|
|
301
|
-
import type {
|
|
302
|
-
|
|
303
|
-
GuidoConfigInput,
|
|
304
|
-
IdentityConfig,
|
|
305
|
-
PartnerConfig,
|
|
306
|
-
TemplateConfig,
|
|
307
|
-
EditorConfig,
|
|
308
|
-
UIConfig,
|
|
309
|
-
FeaturesConfig,
|
|
310
|
-
BlocksConfig,
|
|
311
|
-
CompilerConfig,
|
|
312
|
-
DynamicContent,
|
|
313
|
-
DefaultBlockType,
|
|
314
|
-
CustomBlockType,
|
|
315
|
-
} from '@useinsider/guido';
|
|
316
|
-
|
|
317
|
-
// Utilities
|
|
318
|
-
import {
|
|
319
|
-
validateConfig,
|
|
320
|
-
parseConfig,
|
|
321
|
-
MessageType,
|
|
322
|
-
ProductType,
|
|
323
|
-
} from '@useinsider/guido';
|
|
324
|
-
|
|
325
|
-
// Styles
|
|
326
|
-
import '@useinsider/guido/style';
|
|
371
|
+
import type { GuidoConfig } from '@useinsider/guido';
|
|
372
|
+
import type { StripoEventType } from '@useinsider/guido';
|
|
327
373
|
```
|
|
328
374
|
|
|
329
|
-
|
|
375
|
+
## 🔨 HTML Compiler Rules
|
|
376
|
+
|
|
377
|
+
Guido includes a powerful HTML compiler system that allows you to transform HTML content with custom rules. You can define additional rules and optionally ignore the default rules.
|
|
330
378
|
|
|
331
|
-
|
|
379
|
+
### Rule Types
|
|
380
|
+
|
|
381
|
+
There are 4 types of compiler rules:
|
|
382
|
+
|
|
383
|
+
#### 1. Replace Rule
|
|
384
|
+
Replace specific strings in HTML content.
|
|
332
385
|
|
|
333
386
|
```typescript
|
|
334
|
-
|
|
387
|
+
{
|
|
388
|
+
id: 'fix-encoding',
|
|
389
|
+
description: 'Fix URL encoding issues',
|
|
390
|
+
type: 'replace',
|
|
391
|
+
search: '{%22', // String to find
|
|
392
|
+
replacement: '%7B%22', // String to replace with
|
|
393
|
+
replaceAll: true, // Replace all occurrences (default: true)
|
|
394
|
+
priority: 10 // Execution priority (lower = earlier)
|
|
395
|
+
}
|
|
396
|
+
```
|
|
335
397
|
|
|
336
|
-
|
|
337
|
-
|
|
398
|
+
#### 2. Regex Rule
|
|
399
|
+
Use regular expressions for complex pattern matching and replacement.
|
|
338
400
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
401
|
+
```typescript
|
|
402
|
+
{
|
|
403
|
+
id: 'remove-comments',
|
|
404
|
+
description: 'Remove HTML comments',
|
|
405
|
+
type: 'regex',
|
|
406
|
+
pattern: '<!--.*?-->', // Regex pattern
|
|
407
|
+
replacement: '', // Replacement string
|
|
408
|
+
flags: 'g', // Regex flags (default: 'g')
|
|
409
|
+
priority: 20
|
|
410
|
+
}
|
|
342
411
|
```
|
|
343
412
|
|
|
344
|
-
|
|
413
|
+
#### 3. Remove Rule
|
|
414
|
+
Remove specific strings or patterns from HTML content.
|
|
345
415
|
|
|
346
|
-
|
|
416
|
+
```typescript
|
|
417
|
+
{
|
|
418
|
+
id: 'cleanup-scripts',
|
|
419
|
+
description: 'Remove unwanted script tags',
|
|
420
|
+
type: 'remove',
|
|
421
|
+
targets: [ // Array of strings or RegExp objects
|
|
422
|
+
'<script src="unwanted.js"></script>',
|
|
423
|
+
/onclick="[^"]*"/g
|
|
424
|
+
],
|
|
425
|
+
priority: 30
|
|
426
|
+
}
|
|
427
|
+
```
|
|
347
428
|
|
|
348
|
-
|
|
429
|
+
#### 4. Custom Rule
|
|
430
|
+
Define complex transformation logic with a custom processor function.
|
|
349
431
|
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
|
|
432
|
+
```typescript
|
|
433
|
+
{
|
|
434
|
+
id: 'add-meta-tags',
|
|
435
|
+
description: 'Add custom meta tags to head',
|
|
436
|
+
type: 'custom',
|
|
437
|
+
processor: (html: string): string => {
|
|
438
|
+
// Custom transformation logic
|
|
439
|
+
const metaTags = '<meta name="custom" content="value">';
|
|
440
|
+
return html.replace('</head>', `${metaTags}</head>`);
|
|
441
|
+
},
|
|
442
|
+
priority: 40
|
|
443
|
+
}
|
|
444
|
+
```
|
|
353
445
|
|
|
354
|
-
|
|
355
|
-
<YourModal v-if="showModal" id="guido-dynamic-content-modal" @select="insertContent" @close="closeModal" />
|
|
356
|
-
</template>
|
|
446
|
+
### Using HTML Compiler Rules
|
|
357
447
|
|
|
358
|
-
|
|
359
|
-
const showModal = ref(false);
|
|
448
|
+
#### Basic Usage with Custom Rules
|
|
360
449
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
450
|
+
```typescript
|
|
451
|
+
const guidoConfig = {
|
|
452
|
+
translationsPath: 'window.trans.en',
|
|
453
|
+
features: {
|
|
454
|
+
dynamicContent: true,
|
|
455
|
+
saveAsTemplate: true,
|
|
456
|
+
versionHistory: false, // Disable version history
|
|
457
|
+
testMessage: true
|
|
458
|
+
},
|
|
459
|
+
htmlCompilerRules: [
|
|
460
|
+
{
|
|
461
|
+
id: 'replace-domain',
|
|
462
|
+
description: 'Replace old domain with new one',
|
|
463
|
+
type: 'replace',
|
|
464
|
+
search: 'old-domain.com',
|
|
465
|
+
replacement: 'new-domain.com',
|
|
466
|
+
replaceAll: true,
|
|
467
|
+
priority: 10
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
id: 'remove-tracking',
|
|
471
|
+
description: 'Remove tracking pixels',
|
|
472
|
+
type: 'regex',
|
|
473
|
+
pattern: '<img[^>]*tracking[^>]*>',
|
|
474
|
+
replacement: '',
|
|
475
|
+
flags: 'gi',
|
|
476
|
+
priority: 20
|
|
477
|
+
}
|
|
478
|
+
]
|
|
368
479
|
};
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
#### Ignoring Default Rules
|
|
369
483
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
484
|
+
```typescript
|
|
485
|
+
const guidoConfig = {
|
|
486
|
+
translationsPath: 'window.trans.en',
|
|
487
|
+
features: {
|
|
488
|
+
dynamicContent: true,
|
|
489
|
+
saveAsTemplate: true,
|
|
490
|
+
versionHistory: true,
|
|
491
|
+
testMessage: true
|
|
492
|
+
},
|
|
493
|
+
ignoreDefaultHtmlCompilerRules: true, // Skip all default rules
|
|
494
|
+
htmlCompilerRules: [
|
|
495
|
+
// Only your custom rules will be applied
|
|
496
|
+
{
|
|
497
|
+
id: 'custom-transformation',
|
|
498
|
+
type: 'replace',
|
|
499
|
+
search: 'old-text',
|
|
500
|
+
replacement: 'new-text',
|
|
501
|
+
priority: 1
|
|
502
|
+
}
|
|
503
|
+
]
|
|
373
504
|
};
|
|
374
|
-
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### Rule Execution Order
|
|
508
|
+
|
|
509
|
+
Rules are executed in priority order (lower numbers first). Rules with the same priority are executed in array order.
|
|
510
|
+
|
|
511
|
+
- **Priority 1-99**: Reserved for critical transformations
|
|
512
|
+
- **Priority 100-999**: Standard transformations
|
|
513
|
+
- **Priority 1000+**: Additional custom rules (automatically assigned)
|
|
514
|
+
|
|
515
|
+
### Default Rules
|
|
516
|
+
|
|
517
|
+
Guido includes several default rules for common email HTML optimizations:
|
|
518
|
+
|
|
519
|
+
- **URL encoding fixes**: Fixes malformed URL encoding in dynamic content
|
|
520
|
+
- **Template tag restoration**: Restores `{{}}` template tags that got URL encoded
|
|
521
|
+
- **HTML entity decoding**: Converts `<` and `>` back to `<` and `>`
|
|
522
|
+
- **Cleanup rules**: Removes unwanted iframe and style elements
|
|
523
|
+
- **MSO conditions**: Manages Outlook-specific conditional comments
|
|
524
|
+
- **Domain replacement**: Updates old image domains to current ones
|
|
525
|
+
|
|
526
|
+
You can view all default rules in: `src/config/compiler/htmlCompilerRules.ts`
|
|
527
|
+
|
|
528
|
+
### CompilerRule Interface
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
type CompilerRuleType = 'replace' | 'regex' | 'remove' | 'custom';
|
|
532
|
+
|
|
533
|
+
interface BaseCompilerRule {
|
|
534
|
+
id: string;
|
|
535
|
+
description?: string;
|
|
536
|
+
priority: number;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
interface ReplaceRule extends BaseCompilerRule {
|
|
540
|
+
type: 'replace';
|
|
541
|
+
search: string;
|
|
542
|
+
replacement: string;
|
|
543
|
+
replaceAll?: boolean; // Default: true
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
interface RegexRule extends BaseCompilerRule {
|
|
547
|
+
type: 'regex';
|
|
548
|
+
pattern: string;
|
|
549
|
+
replacement: string;
|
|
550
|
+
flags?: string; // Default: 'g'
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
interface RemoveRule extends BaseCompilerRule {
|
|
554
|
+
type: 'remove';
|
|
555
|
+
targets: (string | RegExp)[]; // Array of strings or RegExp objects
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
interface CustomRule extends BaseCompilerRule {
|
|
559
|
+
type: 'custom';
|
|
560
|
+
processor: (html: string) => string;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
type CompilerRule = ReplaceRule | RegexRule | RemoveRule | CustomRule;
|
|
375
564
|
```
|
|
376
565
|
|
|
377
566
|
---
|
|
378
567
|
|
|
379
|
-
## Development
|
|
568
|
+
## 🔧 Development
|
|
569
|
+
|
|
570
|
+
### Prerequisites
|
|
571
|
+
|
|
572
|
+
- 🧄 `Bun` (strongly recommended)
|
|
573
|
+
or
|
|
574
|
+
- NodeJS 18+ & `npm`
|
|
575
|
+
|
|
576
|
+
### Setup
|
|
380
577
|
|
|
381
578
|
```bash
|
|
382
|
-
# Install
|
|
579
|
+
# Install dependencies
|
|
383
580
|
bun install
|
|
384
581
|
|
|
385
|
-
# Start
|
|
582
|
+
# Start development server
|
|
386
583
|
bun start
|
|
387
584
|
|
|
388
|
-
# Build
|
|
585
|
+
# Build for production
|
|
389
586
|
bun run build
|
|
390
587
|
|
|
391
|
-
#
|
|
588
|
+
# Type checking
|
|
589
|
+
bun run type-check
|
|
590
|
+
|
|
591
|
+
# Linting
|
|
392
592
|
bun run lint
|
|
393
593
|
```
|
|
394
594
|
|
|
395
595
|
### Environment Variables
|
|
396
596
|
|
|
597
|
+
Create a `.env` file with the following variables: (You can get env variables from your senior)
|
|
598
|
+
|
|
397
599
|
```env
|
|
398
600
|
VITE_STRIPO_PLUGIN_ID=your_plugin_id
|
|
399
601
|
VITE_STRIPO_SECRET_KEY=your_secret_key
|
|
400
602
|
VITE_STRIPO_ROLE=your_role
|
|
603
|
+
|
|
604
|
+
# Playwright Test Configuration (Optional - for local debugging only)
|
|
605
|
+
HEADED=false # Set to 'true' to run tests with visible browser
|
|
401
606
|
```
|
|
402
607
|
|
|
403
|
-
|
|
608
|
+
### Project Structure
|
|
609
|
+
|
|
610
|
+
```
|
|
611
|
+
src/
|
|
612
|
+
├── components/ # Vue components
|
|
613
|
+
├── composables/ # Vue composables & business logic
|
|
614
|
+
├── services/ # API layer
|
|
615
|
+
├── stores/ # State management
|
|
616
|
+
├── @types/ # TypeScript definitions
|
|
617
|
+
├── static/ # Static assets & templates
|
|
618
|
+
├── utils/ # Utility functions
|
|
619
|
+
├── enums/ # Constants & enums
|
|
620
|
+
├── mock/ # Mock data for development
|
|
621
|
+
├── plugins/ # Vue plugins
|
|
622
|
+
└── library.ts # Main export
|
|
623
|
+
```
|
|
404
624
|
|
|
405
|
-
##
|
|
625
|
+
## 🔌 Provide/Inject Utilities
|
|
406
626
|
|
|
407
|
-
|
|
408
|
-
|
|
627
|
+
Guido includes type-safe utilities for Vue's provide/inject system to facilitate dependency injection between components.
|
|
628
|
+
|
|
629
|
+
### useProvideInject
|
|
630
|
+
|
|
631
|
+
The `useProvideInject` composable provides two helper functions for type-safe dependency injection:
|
|
632
|
+
|
|
633
|
+
#### Basic Usage
|
|
634
|
+
|
|
635
|
+
```typescript
|
|
636
|
+
// Parent component
|
|
637
|
+
import { provideValue } from '@useinsider/guido';
|
|
638
|
+
import { InjectionKey } from 'vue';
|
|
639
|
+
|
|
640
|
+
// Define a typed injection key
|
|
641
|
+
const MyServiceKey: InjectionKey<MyService> = Symbol('MyService');
|
|
642
|
+
|
|
643
|
+
// Provide the value
|
|
644
|
+
const myService = new MyService();
|
|
645
|
+
provideValue(MyServiceKey, myService);
|
|
646
|
+
|
|
647
|
+
// Child component
|
|
648
|
+
import { useInjectedValue } from '@useinsider/guido';
|
|
649
|
+
|
|
650
|
+
// Inject the value with type safety
|
|
651
|
+
const myService = useInjectedValue(MyServiceKey);
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
#### With Default Value
|
|
655
|
+
|
|
656
|
+
```typescript
|
|
657
|
+
// Inject with a fallback value
|
|
658
|
+
const myService = useInjectedValue(MyServiceKey, new DefaultService());
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
#### Error Handling
|
|
662
|
+
|
|
663
|
+
The `useInjectedValue` function will throw a descriptive error if no provider is found and no default value is provided:
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
// This will throw an error if no provider exists
|
|
667
|
+
try {
|
|
668
|
+
const myService = useInjectedValue(MyServiceKey);
|
|
669
|
+
} catch (error) {
|
|
670
|
+
console.error('No provider found for MyService');
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### API Reference
|
|
675
|
+
|
|
676
|
+
#### `provideValue`
|
|
677
|
+
|
|
678
|
+
```typescript
|
|
679
|
+
provideValue<T>(key: InjectionKey<T>, value: T): void
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
Provides a value using Vue's provide system with type safety.
|
|
683
|
+
|
|
684
|
+
| Parameter | Type | Description |
|
|
685
|
+
|-----------|------|-------------|
|
|
686
|
+
| `key` | `InjectionKey<T>` | The typed injection key |
|
|
687
|
+
| `value` | `T` | The value to provide |
|
|
688
|
+
|
|
689
|
+
#### `useInjectedValue`
|
|
690
|
+
|
|
691
|
+
```typescript
|
|
692
|
+
useInjectedValue<T>(key: InjectionKey<T>, defaultValue?: T): T
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
Injects a value using Vue's inject system with type safety and error handling.
|
|
696
|
+
|
|
697
|
+
| Parameter | Type | Required | Description |
|
|
698
|
+
|-----------|------|----------|-------------|
|
|
699
|
+
| `key` | `InjectionKey<T>` | ✅ | The typed injection key |
|
|
700
|
+
| `defaultValue` | `T` | ⚪ | Optional fallback value |
|
|
701
|
+
|
|
702
|
+
**Returns:** `T` - The injected value
|
|
703
|
+
|
|
704
|
+
**Throws:** `Error` - When no provider is found and no default value is provided
|
|
705
|
+
|
|
706
|
+
## 🌐 i18n
|
|
707
|
+
Before running the project, it sends to request to inone.useinsider.com/translations and writes the JSON file into - [trans.json](src/mock/responses/trans.json).
|
|
708
|
+
It allows to use production or local translations on your code. 🚀
|
|
709
|
+
Example usage:
|
|
710
|
+
```js
|
|
711
|
+
import { useTranslations } from '@@/Composables/useTranslations';
|
|
712
|
+
|
|
713
|
+
const trans = useTranslations();
|
|
714
|
+
|
|
715
|
+
// use everywhere like this:
|
|
716
|
+
trans('foo.bar')
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
## 📦 Local Building (Recommended)
|
|
720
|
+
|
|
721
|
+
Run this commands if you want to test the package on your local before sending to NPM.
|
|
722
|
+
```sh
|
|
409
723
|
bun run build
|
|
724
|
+
```
|
|
410
725
|
|
|
411
|
-
|
|
726
|
+
Since bun does not have packaging yet, use npm here: 🥲
|
|
727
|
+
```sh
|
|
412
728
|
npm pack
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
It'll crate like `useinsider-guido-1.0.0.tgz` file.
|
|
413
732
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
733
|
+
Move this file to your project path like: `email-fe` via:
|
|
734
|
+
```sh
|
|
735
|
+
cp useinsider-guido-1.0.0.tgz ../email-fe
|
|
417
736
|
```
|
|
418
737
|
|
|
419
|
-
|
|
738
|
+
Install the file to your project:
|
|
739
|
+
```sh
|
|
740
|
+
npm i ./useinsider-guido-1.0.0.tgz
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
Then you just need to rebuild to your project or restart the Container. 🎉
|
|
744
|
+
|
|
745
|
+
For Future, we can create a shell script for it. Feel free to help 🙃
|
|
746
|
+
|
|
747
|
+
## 📦 Build Output
|
|
748
|
+
|
|
749
|
+
The library builds to multiple formats:
|
|
420
750
|
|
|
421
|
-
|
|
751
|
+
- **ES Module**: `dist/library.js` (recommended)
|
|
752
|
+
- **CSS**: `dist/guido.css` (custom styles)
|
|
753
|
+
|
|
754
|
+
### Package Exports
|
|
755
|
+
|
|
756
|
+
```json
|
|
757
|
+
{
|
|
758
|
+
"exports": {
|
|
759
|
+
".": {
|
|
760
|
+
"import": "./dist/library.js",
|
|
761
|
+
"types": "./dist/components/Guido.vue.d.ts",
|
|
762
|
+
"require": "./dist/components/Guido.vue.js"
|
|
763
|
+
},
|
|
764
|
+
"./style": "./dist/guido.css"
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
## 🤝 Contributing
|
|
770
|
+
- PR Titles should be structured like `TASK-ID | 🔥 | Some Clear Task Descriptions`
|
|
771
|
+
- PR Labels should be filled.
|
|
772
|
+
- PR Assignee required.
|
|
773
|
+
- Tests should be covered.
|
|
774
|
+
- All required checks should be passed before sending review request.
|
|
775
|
+
|
|
776
|
+
## 📄 License
|
|
422
777
|
|
|
423
778
|
ISC License
|
|
779
|
+
|
|
780
|
+
---
|
|
781
|
+
|
|
782
|
+
## 🔗 Related
|
|
783
|
+
|
|
784
|
+
- [Stripo Email Editor](https://stripo.email/) - The underlying email editor
|
|
785
|
+
- [@useinsider/design-system-vue](https://github.com/useinsider/design-system-vue) - Insider's Vue design system
|
|
786
|
+
|
|
787
|
+
## 🎯 TODO:
|
|
788
|
+
- CSS part should be optimized with variables & `sass-loader`.
|
|
789
|
+
- Master Version Generator should be fixed.
|
|
790
|
+
- Playwright integrationBoilerplate/control.ts
|
|
791
|
+
- Commitlint & Precommit Hooks integration
|
|
792
|
+
- Get Pre-built display conditions from API
|