|
1 | 1 | # service-injector |
2 | 2 |
|
3 | | -Lightweight JavaScript library for SaaS providers to allow its services installation on clients' sites. |
4 | | - |
5 | | -## Use Case |
6 | | - |
7 | | -* You provide SaaS in the Internet. |
8 | | -* You want to allow your users to install a snippet on their sites as floating tab on the side with the ability to display and use your SaaS. |
| 3 | +Lightweight JavaScript library for SaaS providers to embed services on client websites as a floating tab/window. |
9 | 4 |
|
10 | 5 | ## Features |
11 | 6 |
|
12 | | -- **Zero Dependencies** — Pure vanilla JavaScript with no jQuery, React, or other libraries required. Works on any website regardless of tech stack. |
13 | | - |
14 | | -- **Multiple Installation Options** — Use as npm package with ES modules, CommonJS, or as a simple script tag for vanilla JS websites. |
15 | | - |
16 | | -- **Drop-in Configuration** — Configure behavior via query string parameters, data attributes, or programmatic API. No coding required for basic usage. |
17 | | - |
18 | | -- **Mobile-Aware** — Automatically detects mobile devices and opens SaaS in a new browser window instead of an iframe for optimal UX. |
19 | | - |
20 | | -- **Interactive Window** — Draggable header and resizable corner with full touch event support. Both features can be toggled via configuration. |
21 | | - |
22 | | -- **Dockable Window** — When enabled, drag the window to any screen edge to dock it. The page content is pushed aside to make room. Undock by double-clicking the header or dragging away. Disabled on mobile and small screens (<768px). |
23 | | - |
24 | | -- **Fully Customizable** — Override tab template, window template, and styles without modifying source code. |
25 | | - |
26 | | -- **TypeScript Support** — Full TypeScript definitions included for excellent IDE support. |
| 7 | +- **Zero Dependencies** — Pure vanilla JavaScript, works on any website |
| 8 | +- **Multiple Installation Options** — npm package, CDN script tag, or self-hosted |
| 9 | +- **Drop-in Configuration** — Query strings, data attributes, or programmatic API |
| 10 | +- **Mobile-Aware** — Auto-detects mobile and opens in new tab for better UX |
| 11 | +- **Interactive Window** — Draggable, resizable with touch support |
| 12 | +- **Dockable** — Snap to screen edges like browser DevTools |
| 13 | +- **Fully Customizable** — Templates, styles, and themes |
| 14 | +- **TypeScript Support** — Full type definitions included |
27 | 15 |
|
28 | 16 | ## Installation |
29 | 17 |
|
30 | | -### npm (Recommended for modern projects) |
| 18 | +### npm |
31 | 19 |
|
32 | 20 | ```bash |
33 | 21 | npm install service-injector |
34 | 22 | ``` |
35 | 23 |
|
36 | | -### CDN (For vanilla JS websites) |
37 | | - |
38 | | -```html |
39 | | -<!-- unpkg --> |
40 | | -<script src="https://unpkg.com/service-injector/dist/index.iife.js"></script> |
41 | | - |
42 | | -<!-- jsDelivr --> |
43 | | -<script src="https://cdn.jsdelivr.net/npm/service-injector/dist/index.iife.js"></script> |
44 | | -``` |
45 | | - |
46 | | -## Usage |
47 | | - |
48 | | -### Vanilla JavaScript (Script Tag) — Zero Config |
49 | | - |
50 | | -The simplest way to use service-injector. Just add the script tag and it auto-installs: |
51 | | - |
52 | | -```html |
53 | | -<!-- Basic usage - auto-installs with defaults --> |
54 | | -<script id="service-injector" src="https://unpkg.com/service-injector/dist/index.iife.js"></script> |
55 | | -``` |
56 | | - |
57 | | -**With query string configuration:** |
58 | | - |
59 | | -```html |
60 | | -<script id="service-injector" |
61 | | - src="https://unpkg.com/service-injector/dist/index.iife.js?p=right&o=100px&url=https://my-saas.com"> |
62 | | -</script> |
63 | | -``` |
64 | | - |
65 | | -**With data attributes:** |
66 | | - |
67 | | -```html |
68 | | -<script id="service-injector" |
69 | | - src="https://unpkg.com/service-injector/dist/index.iife.js" |
70 | | - data-position="left" |
71 | | - data-offset="50%" |
72 | | - data-url="https://my-saas.com"> |
73 | | -</script> |
74 | | -``` |
75 | | - |
76 | | -### ES Modules (Modern JavaScript) |
77 | | - |
78 | 24 | ```javascript |
79 | 25 | import { ServiceInjector } from 'service-injector'; |
80 | 26 |
|
81 | 27 | const injector = new ServiceInjector({ |
82 | 28 | saasUrl: 'https://my-saas.com', |
83 | 29 | position: 'right', |
84 | | - offset: '100px', |
85 | | - windowWidth: '500px', |
86 | | - windowHeight: '600px', |
87 | | - draggable: true, |
88 | | - resizable: true, |
89 | | - prefix: 'my-widget' // Custom prefix for element IDs |
90 | | -}); |
91 | | - |
92 | | -injector.install(); |
93 | | - |
94 | | -// Later, to control programmatically: |
95 | | -injector.toggle(); // Toggle window open/closed |
96 | | -injector.expand(); // Open window |
97 | | -injector.collapse(); // Close window |
98 | | -injector.destroy(); // Clean up completely |
99 | | -``` |
100 | | - |
101 | | -### CommonJS (Node.js) |
102 | | - |
103 | | -```javascript |
104 | | -const { ServiceInjector } = require('service-injector'); |
105 | | - |
106 | | -const injector = new ServiceInjector({ |
107 | | - saasUrl: 'https://my-saas.com', |
108 | | - position: 'bottom' |
| 30 | + draggable: true |
109 | 31 | }); |
110 | 32 |
|
111 | 33 | injector.install(); |
112 | 34 | ``` |
113 | 35 |
|
114 | | -### With Global Config (Backwards Compatible) |
| 36 | +### CDN |
115 | 37 |
|
116 | 38 | ```html |
117 | | -<script> |
118 | | - window.serviceInjectorConfig = { |
119 | | - tabTemplate: "<a onclick='return siToggleWindow();'>Support</a>", |
120 | | - styles: "#si-tab { background: #4a90d9; color: white; }" |
121 | | - }; |
| 39 | +<script id="service-injector" |
| 40 | + src="https://unpkg.com/service-injector/dist/index.iife.js?url=https://my-saas.com"> |
122 | 41 | </script> |
123 | | -<script id="service-injector" src="https://unpkg.com/service-injector/dist/index.iife.js"></script> |
124 | 42 | ``` |
125 | 43 |
|
126 | | -## Configuration Options |
127 | | - |
128 | | -### Programmatic API Options |
129 | | - |
130 | | -| Option | Type | Default | Description | |
131 | | -|--------|------|---------|-------------| |
132 | | -| `url` | `string` | `null` | Custom URL to load in the iframe | |
133 | | -| `position` | `string` | `'bottom'` | Tab position: `'left'`, `'right'`, `'top'`, `'bottom'` | |
134 | | -| `offset` | `string` | `'80%'` | Tab offset from edge (e.g., `'80%'`, `'100px'`) | |
135 | | -| `animation` | `number` | `300` | Animation duration in milliseconds | |
136 | | -| `windowWidth` | `string` | `'440px'` | Window width | |
137 | | -| `windowHeight` | `string` | `'550px'` | Window height | |
138 | | -| `windowTop` | `string` | `'100px'` | Window top position | |
139 | | -| `windowBottom` | `string` | `null` | Window bottom position | |
140 | | -| `windowLeft` | `string` | `null` | Window left position | |
141 | | -| `windowCenter` | `number` | `0` | Window center offset (0 = centered) | |
142 | | -| `windowRight` | `string` | `null` | Window right position | |
143 | | -| `draggable` | `boolean` | `true` | Enable window dragging | |
144 | | -| `resizable` | `boolean` | `true` | Enable window resizing | |
145 | | -| `hideTab` | `boolean` | `false` | Hide tab when window is open | |
146 | | -| `dockable` | `boolean \| string[]` | `false` | Enable window docking to viewport edges. `true` = all sides, or array like `['left', 'right']` | |
147 | | -| `prefix` | `string` | `'si'` | Element ID prefix | |
148 | | -| `saasUrl` | `string` | `'https://orienteer.org'` | Default SaaS URL | |
149 | | -| `tabTemplate` | `string` | (default) | Custom tab HTML template | |
150 | | -| `windowTemplate` | `string` | (default) | Custom window HTML template | |
151 | | -| `styles` | `string` | `''` | Additional CSS styles | |
152 | | - |
153 | | -### Query String / Data Attribute Parameters |
154 | | - |
155 | | -For script tag usage, use short parameter names: |
156 | | - |
157 | | -| Parameter | Long Name | Default | Description | |
158 | | -|-----------|-----------|---------|-------------| |
159 | | -| `url` | `url` | `null` | Custom URL to load in the iframe | |
160 | | -| `p` | `position` | `'bottom'` | Tab position: left, right, top, bottom | |
161 | | -| `o` | `offset` | `'80%'` | Tab offset from edge (% or px) | |
162 | | -| `a` | `animation` | `300` | Animation duration in milliseconds | |
163 | | -| `ww` | `window-width` | `'440px'` | Window width | |
164 | | -| `wh` | `window-height` | `'550px'` | Window height | |
165 | | -| `wt` | `window-top` | `'100px'` | Window top position | |
166 | | -| `wb` | `window-bottom` | `null` | Window bottom position | |
167 | | -| `wl` | `window-left` | `null` | Window left position | |
168 | | -| `wc` | `window-center` | `0` | Window center offset | |
169 | | -| `wr` | `window-right` | `null` | Window right position | |
170 | | -| `d` | `draggable` | `true` | Enable window dragging | |
171 | | -| `r` | `resizable` | `true` | Enable window resizing | |
172 | | -| `ht` | `hide-tab` | `false` | Hide tab when window is open | |
173 | | -| `dk` | `dockable` | `false` | Enable window docking to viewport edges | |
174 | | - |
175 | | -## Customizing Templates |
176 | | - |
177 | | -### Using Global Configuration |
| 44 | +Or use jsDelivr: |
178 | 45 |
|
179 | 46 | ```html |
180 | | -<script> |
181 | | - window.serviceInjectorConfig = { |
182 | | - tabTemplate: "<a onclick='return siToggleWindow();' href='#'>Open Panel</a>", |
183 | | - windowTemplate: "...", // Custom window HTML |
184 | | - styles: "#si-tab { background: #4a90d9; color: white; border-radius: 8px; }" |
185 | | - }; |
| 47 | +<script id="service-injector" |
| 48 | + src="https://cdn.jsdelivr.net/npm/service-injector/dist/index.iife.js"> |
186 | 49 | </script> |
187 | | -<script id="service-injector" src="https://unpkg.com/service-injector/dist/index.iife.js"></script> |
188 | 50 | ``` |
189 | 51 |
|
190 | | -### Using DOM Elements |
| 52 | +## Quick Start |
| 53 | + |
| 54 | +The simplest setup - just add the script tag: |
191 | 55 |
|
192 | 56 | ```html |
193 | | -<!-- Custom tab template --> |
194 | | -<script type="text/template" id="si-tab-template"> |
195 | | - <a onclick='return siToggleWindow();' href='#'>Open Panel</a> |
| 57 | +<script id="service-injector" |
| 58 | + src="https://unpkg.com/service-injector/dist/index.iife.js" |
| 59 | + data-url="https://my-saas.com" |
| 60 | + data-position="right"> |
196 | 61 | </script> |
197 | | - |
198 | | -<!-- Custom styles (appended to defaults) --> |
199 | | -<style id="si-custom-styles"> |
200 | | - #si-tab { background: #4a90d9; color: white; border-radius: 8px; } |
201 | | - #si-header { background: #357abd; color: white; } |
202 | | -</style> |
203 | | - |
204 | | -<script id="service-injector" src="https://unpkg.com/service-injector/dist/index.iife.js"></script> |
205 | 62 | ``` |
206 | 63 |
|
207 | | -### Template Placeholders |
| 64 | +A floating tab appears. Click it to open your service in a popup window. |
208 | 65 |
|
209 | | -Templates support these placeholders: |
210 | | -- `%prefix%` - Element ID prefix (default: "si") |
211 | | -- `%url%` - The configured URL |
| 66 | +## Documentation |
212 | 67 |
|
213 | | -### Customizable Elements |
| 68 | +For detailed documentation, see the **[docs/](./docs/)** folder: |
214 | 69 |
|
215 | | -| Element ID | Description | |
216 | | -|------------|-------------| |
217 | | -| `#si-tab` | The floating tab button | |
218 | | -| `#si-window` | The popup window container | |
219 | | -| `#si-header` | Window header (draggable area) | |
220 | | -| `#si-body` | Window body (contains iframe) | |
221 | | -| `#si-iframe` | The iframe element | |
222 | | -| `#si-footer` | Window footer | |
223 | | -| `#si-resizer` | Resize handle | |
| 70 | +| Document | Description | |
| 71 | +|----------|-------------| |
| 72 | +| [Overview](./docs/README.md) | Introduction and navigation | |
| 73 | +| [Installation](./docs/installation.md) | npm, CDN, script tag, self-hosting | |
| 74 | +| [Configuration](./docs/configuration.md) | All options for position, size, behavior | |
| 75 | +| [Customization](./docs/customization.md) | Templates, styles, themes | |
| 76 | +| [Docking](./docs/docking.md) | Snap windows to screen edges | |
| 77 | +| [API Reference](./docs/api.md) | Methods, global functions, TypeScript | |
| 78 | +| [Mobile Behavior](./docs/mobile.md) | How mobile devices are handled | |
224 | 79 |
|
225 | | -## Programmatic Control |
| 80 | +## Demo |
226 | 81 |
|
227 | | -### Global Functions (Script Tag Usage) |
228 | | - |
229 | | -When using the script tag, global functions are automatically exposed: |
230 | | - |
231 | | -```javascript |
232 | | -// Toggle window open/closed |
233 | | -siToggleWindow(); |
234 | | - |
235 | | -// Dock window to a specific side |
236 | | -siDock('right'); // 'left', 'right', 'top', 'bottom' |
237 | | - |
238 | | -// Undock window |
239 | | -siUndock(); |
240 | | - |
241 | | -// Completely remove the injector |
242 | | -siDestroy(); |
243 | | -``` |
244 | | - |
245 | | -With a custom prefix (e.g., `prefix: 'my'`): |
246 | | -```javascript |
247 | | -myToggleWindow(); |
248 | | -myDock('left'); |
249 | | -myUndock(); |
250 | | -myDestroy(); |
251 | | -``` |
252 | | - |
253 | | -### ServiceInjector Instance Methods |
254 | | - |
255 | | -```javascript |
256 | | -const injector = new ServiceInjector(options); |
257 | | - |
258 | | -injector.install(); // Mount to DOM |
259 | | -injector.toggle(); // Toggle window |
260 | | -injector.expand(); // Open window |
261 | | -injector.collapse(); // Close window |
262 | | -injector.dock('right'); // Dock to edge ('left', 'right', 'top', 'bottom') |
263 | | -injector.undock(); // Undock from edge |
264 | | -injector.isDocked(); // Get dock side or null if floating |
265 | | -injector.destroy(); // Full cleanup |
266 | | -injector.isOpen(); // Check if window is open |
267 | | -injector.isMobile(); // Check if mobile device |
268 | | -injector.getConfig(); // Get current configuration |
269 | | -injector.getPrefix(); // Get the prefix |
270 | | -``` |
271 | | - |
272 | | -## TypeScript Support |
273 | | - |
274 | | -Full TypeScript definitions are included: |
275 | | - |
276 | | -```typescript |
277 | | -import { ServiceInjector, ServiceInjectorOptions, ServiceInjectorConfig } from 'service-injector'; |
278 | | - |
279 | | -const options: ServiceInjectorOptions = { |
280 | | - saasUrl: 'https://my-saas.com', |
281 | | - position: 'right', |
282 | | - draggable: true |
283 | | -}; |
284 | | - |
285 | | -const injector = new ServiceInjector(options); |
286 | | -injector.install(); |
287 | | -``` |
288 | | - |
289 | | -## Browser Support |
290 | | - |
291 | | -- Chrome, Firefox, Safari, Edge (modern versions) |
292 | | -- IE11 (with appropriate polyfills) |
293 | | -- Mobile browsers (iOS Safari, Android Chrome) |
| 82 | +Try it live: **[https://orienteerbap.github.io/service-injector/](https://orienteerbap.github.io/service-injector/)** |
294 | 83 |
|
295 | 84 | ## License |
296 | 85 |
|
297 | 86 | Apache-2.0 |
298 | 87 |
|
299 | | -## Future Ideas |
300 | | - |
301 | | -Some potential features for future versions: |
302 | | - |
303 | | -- **Dock Preview** — Show a visual preview/highlight of the dock zone while dragging near an edge, before the user releases |
304 | | -- **Dock Snap Animation** — Animated transition when snapping to dock zone |
305 | | -- **Persist State** — Remember dock state, window position, and size across page loads (localStorage) |
306 | | -- **Multiple Instances** — Better support for running multiple independent injectors on the same page |
307 | | - |
308 | 88 | ## Links |
309 | 89 |
|
310 | 90 | - [GitHub Repository](https://github.com/OrienteerBAP/service-injector) |
311 | 91 | - [npm Package](https://www.npmjs.com/package/service-injector) |
312 | | -- [Demo](https://orienteerbap.github.io/service-injector/demo/) |
| 92 | +- [Demo](https://orienteerbap.github.io/service-injector/) |
0 commit comments