@dava96/osrs-icons 1.0.15 → 1.0.17

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.
Files changed (47) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +170 -5
  3. package/dist/cjs/animateCursor.d.ts +72 -0
  4. package/dist/cjs/animateCursor.d.ts.map +1 -0
  5. package/dist/cjs/animateCursor.js +94 -0
  6. package/dist/cjs/applyCursors.d.ts +64 -0
  7. package/dist/cjs/applyCursors.d.ts.map +1 -0
  8. package/dist/cjs/applyCursors.js +82 -0
  9. package/dist/cjs/flip.d.ts +55 -0
  10. package/dist/cjs/flip.d.ts.map +1 -0
  11. package/dist/cjs/flip.js +117 -0
  12. package/dist/cjs/generated/icons.d.ts +1 -0
  13. package/dist/cjs/generated/icons.d.ts.map +1 -0
  14. package/dist/cjs/generated/meta.d.ts +15 -0
  15. package/dist/cjs/generated/meta.d.ts.map +1 -0
  16. package/dist/cjs/generated/meta.js +14 -0
  17. package/dist/cjs/index.d.ts +16 -0
  18. package/dist/cjs/index.d.ts.map +1 -0
  19. package/dist/cjs/index.js +20 -1
  20. package/dist/cjs/packs.d.ts +142 -0
  21. package/dist/cjs/packs.d.ts.map +1 -0
  22. package/dist/cjs/packs.js +192 -0
  23. package/dist/esm/animateCursor.d.ts +72 -0
  24. package/dist/esm/animateCursor.d.ts.map +1 -0
  25. package/dist/esm/animateCursor.js +91 -0
  26. package/dist/esm/applyCursors.d.ts +64 -0
  27. package/dist/esm/applyCursors.d.ts.map +1 -0
  28. package/dist/esm/applyCursors.js +79 -0
  29. package/dist/esm/flip.d.ts +55 -0
  30. package/dist/esm/flip.d.ts.map +1 -0
  31. package/dist/esm/flip.js +114 -0
  32. package/dist/esm/generated/icons.d.ts +1 -0
  33. package/dist/esm/generated/icons.d.ts.map +1 -0
  34. package/dist/esm/generated/meta.d.ts +15 -0
  35. package/dist/esm/generated/meta.d.ts.map +1 -0
  36. package/dist/esm/generated/meta.js +14 -0
  37. package/dist/esm/index.d.ts +16 -0
  38. package/dist/esm/index.d.ts.map +1 -0
  39. package/dist/esm/index.js +18 -1
  40. package/dist/esm/packs.d.ts +142 -0
  41. package/dist/esm/packs.d.ts.map +1 -0
  42. package/dist/esm/packs.js +189 -0
  43. package/package.json +2 -2
  44. package/dist/cjs/index_test.d.ts +0 -1
  45. package/dist/cjs/index_test.js +0 -110
  46. package/dist/esm/index_test.d.ts +0 -1
  47. package/dist/esm/index_test.js +0 -105
package/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Attribution — NonCommercial — ShareAlike 3.0 Unported
2
+ (CC BY-NC-SA 3.0)
3
+
4
+ Full licence text: https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
5
+
6
+ You are free to:
7
+
8
+ Share — copy and redistribute the material in any medium or format.
9
+ Adapt — remix, transform, and build upon the material.
10
+
11
+ Under the following terms:
12
+
13
+ Attribution — You must give appropriate credit, provide a link to
14
+ the licence, and indicate if changes were made.
15
+
16
+ NonCommercial — You may not use the material for commercial purposes.
17
+
18
+ ShareAlike — If you remix, transform, or build upon the material, you
19
+ must distribute your contributions under the same licence.
20
+
21
+ ---
22
+
23
+ This project is not affiliated with Jagex Ltd.
24
+ OSRS icons are sourced from the Old School RuneScape Wiki and are the
25
+ property of Jagex / the Wiki contributors.
package/README.md CHANGED
@@ -8,12 +8,47 @@ Designed for easy integration with modern web apps, with full tree-shaking suppo
8
8
  [![license](https://img.shields.io/npm/l/@dava96/osrs-icons)](./LICENSE)
9
9
  [![GitHub stars](https://img.shields.io/github/stars/Dava96/osrs-icons)](https://github.com/Dava96/osrs-icons)
10
10
 
11
+ 📖 **[Browse icons & build packs →](https://dava96.github.io/osrs-icons/)**
12
+
13
+ ## Table of Contents
14
+
15
+ - [Installation](#installation)
16
+ - [Quick Start](#quick-start)
17
+ - [Usage](#usage)
18
+ - [CSS Cursor](#css-cursor-tree-shaking-supported)
19
+ - [As an Image](#as-an-image)
20
+ - [Icon Discovery](#icon-discovery)
21
+ - [CDN (No Build Step)](#cdn-usage-no-build-step)
22
+ - [Cursor Packs](#cursor-packs)
23
+ - [Utilities](#utilities)
24
+ - [flipCursor](#flip-cursor)
25
+ - [applyCursors](#apply-cursors)
26
+ - [errorCursor](#error-cursor-)
27
+ - [API Reference](#api-reference)
28
+ - [Browser Compatibility](#browser-compatibility)
29
+ - [How It Works](#how-it-works)
30
+ - [Contributing](#contributing)
31
+ - [License](#license)
32
+
11
33
  ## Installation
12
34
 
13
35
  ```bash
14
36
  npm install @dava96/osrs-icons
15
37
  ```
16
38
 
39
+ ## Quick Start
40
+
41
+ ```tsx
42
+ import { abyssalWhip } from '@dava96/osrs-icons';
43
+
44
+ // As a cursor
45
+ <div style={{ cursor: abyssalWhip }}>Hover me!</div>;
46
+
47
+ // As an image
48
+ import { toDataUrl } from '@dava96/osrs-icons';
49
+ <img src={toDataUrl(abyssalWhip)} alt="Abyssal Whip" />;
50
+ ```
51
+
17
52
  ## Usage
18
53
 
19
54
  ### CSS Cursor (Tree-Shaking Supported)
@@ -38,7 +73,7 @@ Use the `toDataUrl` helper to extract the raw data URL for use outside of CSS:
38
73
  import { abyssalWhip, dragonScimitar, toDataUrl } from '@dava96/osrs-icons';
39
74
 
40
75
  // Single icon
41
- <img src={toDataUrl(abyssalWhip)} alt="Abyssal Whip" />
76
+ <img src={toDataUrl(abyssalWhip)} alt="Abyssal Whip" />;
42
77
 
43
78
  // Multiple icons at once
44
79
  const urls = toDataUrl({
@@ -57,10 +92,12 @@ Browse all available icons programmatically with `iconNames`, or restrict values
57
92
  import { iconNames, type IconName } from '@dava96/osrs-icons';
58
93
 
59
94
  // Search / autocomplete
60
- const results = iconNames.filter(name => name.includes('dragon'));
95
+ const results = iconNames.filter((name) => name.includes('dragon'));
61
96
 
62
97
  // Type-safe icon references
63
- function setCustomCursor(name: IconName) { /* ... */ }
98
+ function setCustomCursor(name: IconName) {
99
+ /* ... */
100
+ }
64
101
  ```
65
102
 
66
103
  ### CDN Usage (No Build Step)
@@ -70,11 +107,129 @@ You can use the package directly in the browser via ESM.sh:
70
107
  ```html
71
108
  <script type="module">
72
109
  import { AbyssalWhip } from 'https://esm.sh/@dava96/osrs-icons';
73
-
110
+
74
111
  document.body.style.cursor = AbyssalWhip;
75
112
  </script>
76
113
  ```
77
114
 
115
+ ## Cursor Packs
116
+
117
+ Pre-built thematic icon groups — each pack groups related icons by their in-game state:
118
+
119
+ ```ts
120
+ import { runePack, bucketPack, coinsPack } from '@dava96/osrs-icons';
121
+
122
+ // Rune pack — all 10 F2P runes
123
+ element.style.cursor = runePack.air;
124
+
125
+ // Bucket fill progression — great for loading states
126
+ const stages = bucketPack.stages; // [empty, 1/5, 2/5, 3/5, 4/5, full]
127
+ const index = Math.min(Math.floor((progress / 100) * stages.length), stages.length - 1);
128
+ element.style.cursor = stages[index];
129
+ ```
130
+
131
+ **Available packs:**
132
+
133
+ | Pack | Keys |
134
+ | ------------ | ----------------------------------------------------------------------------------------------- |
135
+ | `coinsPack` | `_1` to `_10000` + `stages[]` |
136
+ | `bucketPack` | `empty` to `full` + `stages[]` |
137
+ | `runePack` | `air`, `fire`, `water`, `earth`, `chaos`, `mind`, `death`, `law`, `nature`, `body` + `stages[]` |
138
+
139
+ ## Utilities
140
+
141
+ ### Flip Cursor
142
+
143
+ Many OSRS icons face right, but cursors typically point left. Flip one icon, an array, or an entire pack:
144
+
145
+ ```ts
146
+ import { abyssalWhip, runePack, flipCursor } from '@dava96/osrs-icons';
147
+
148
+ // Single icon
149
+ const leftFacing = await flipCursor(abyssalWhip);
150
+
151
+ // Array of icons
152
+ const [flippedAir, flippedFire] = await flipCursor([runePack.air, runePack.fire]);
153
+
154
+ // Entire pack — flips all values and stages in one call
155
+ const flippedRunes = await flipCursor(runePack);
156
+ ```
157
+
158
+ Results are cached internally — flipping the same icon twice returns instantly. Browser-only (uses Canvas API); returns the original value in Node.js/SSR.
159
+
160
+ ### Apply Cursors
161
+
162
+ Map OSRS icons to standard CSS cursor states with a one-liner:
163
+
164
+ ```ts
165
+ import { abyssalWhip, dragonScimitar, bucketPack, applyCursors } from '@dava96/osrs-icons';
166
+
167
+ const cleanup = applyCursors({
168
+ default: abyssalWhip,
169
+ pointer: dragonScimitar,
170
+ wait: bucketPack.full,
171
+ });
172
+
173
+ // Later, revert to browser defaults
174
+ cleanup();
175
+ ```
176
+
177
+ You can also scope cursors to a specific element:
178
+
179
+ ```ts
180
+ applyCursors({ default: abyssalWhip }, document.getElementById('game-area')!);
181
+ ```
182
+
183
+ ### Error Cursor 🐟
184
+
185
+ Use the iconic red herring as your error cursor:
186
+
187
+ ```ts
188
+ import { errorCursor } from '@dava96/osrs-icons';
189
+
190
+ // Also available via herringPack.error
191
+ element.style.cursor = errorCursor;
192
+ ```
193
+
194
+ ## API Reference
195
+
196
+ ### Types
197
+
198
+ | Type | Description |
199
+ | --------------- | ------------------------------------------------------------------------------------------ |
200
+ | `IconName` | Union of all valid icon name strings (for type-safe references) |
201
+ | `CursorMapping` | `Partial<Record<CursorState, string>>` — maps CSS cursor states to icon values |
202
+ | `CursorState` | `'default' \| 'pointer' \| 'wait' \| 'text' \| 'move' \| ...` — standard CSS cursor states |
203
+
204
+ ### Functions
205
+
206
+ | Function | Signature | Description |
207
+ | -------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
208
+ | `toDataUrl` | `(cursor: string) → string` | Extracts the raw `data:image/png;base64,...` URL from a CSS cursor value |
209
+ | `toDataUrl` | `(cursors: Record<K, string>) → Record<K, string>` | Batch version — extracts URLs from multiple cursor values |
210
+ | `flipCursor` | `(cursor: string) → Promise<string>` | Horizontally flips a cursor icon at runtime via Canvas API. Cached. Browser-only. |
211
+ | `applyCursors` | `(mapping: CursorMapping, target?: HTMLElement) → () => void` | Injects a `<style>` tag mapping cursor states to OSRS icons. Returns a cleanup function. |
212
+
213
+ ### Constants
214
+
215
+ | Export | Type | Description |
216
+ | ------------- | ------------------------ | ---------------------------------------------------------- |
217
+ | `iconNames` | `readonly string[]` | Array of all available icon name strings |
218
+ | `errorCursor` | `string` | Semantic alias for `redHerring` |
219
+ | `*Pack` | `Record<string, string>` | Pre-built cursor packs (see [Cursor Packs](#cursor-packs)) |
220
+
221
+ ## Browser Compatibility
222
+
223
+ | Feature | Browser | Node.js / SSR |
224
+ | -------------- | ---------------------- | ------------------------- |
225
+ | Icon imports | ✅ All | ✅ All |
226
+ | `toDataUrl` | ✅ All | ✅ All |
227
+ | `applyCursors` | ✅ All modern | ⚠️ Returns no-op cleanup |
228
+ | `flipCursor` | ✅ Canvas API required | ⚠️ Returns original value |
229
+ | Cursor packs | ✅ All | ✅ All |
230
+
231
+ All features are SSR-safe — browser-only features degrade gracefully in Node.js environments by returning safe fallback values.
232
+
78
233
  ## How It Works
79
234
 
80
235
  The build script fetches every inventory sprite (~17,400 icons) from the
@@ -83,9 +238,19 @@ compresses them as palette PNGs, and generates a TypeScript file of named export
83
238
 
84
239
  Each icon is a small ~32×32 pixel sprite, base64-encoded inline — no external assets to host.
85
240
 
241
+ ### Package Output
242
+
243
+ | Format | Path | Use |
244
+ | ------ | --------------------- | ------------------------------------ |
245
+ | ESM | `dist/esm/index.js` | `import` (bundlers, modern browsers) |
246
+ | CJS | `dist/cjs/index.js` | `require()` (Node.js, legacy) |
247
+ | Types | `dist/cjs/index.d.ts` | TypeScript definitions |
248
+
249
+ The package has `"sideEffects": false` for optimal tree-shaking in Webpack, Rollup, Vite, and esbuild.
250
+
86
251
  ## Contributing
87
252
 
88
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for details on updating icons and publishing new versions.
253
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for details on local development, updating icons, and publishing new versions.
89
254
 
90
255
  ## License
91
256
 
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Options for {@link animateCursor}.
3
+ */
4
+ export interface AnimateCursorOptions {
5
+ /**
6
+ * Total duration of one full animation cycle in milliseconds.
7
+ * Each frame occupies `duration / frames.length` of the cycle.
8
+ *
9
+ * @default 1000
10
+ */
11
+ duration?: number;
12
+ /**
13
+ * Element to scope the animated cursor to.
14
+ * When omitted the cursor animates on the entire page (`*`).
15
+ */
16
+ target?: HTMLElement;
17
+ /**
18
+ * How many times the cycle should repeat.
19
+ * Use `Infinity` (the default) for a continuous loop.
20
+ *
21
+ * @default Infinity
22
+ */
23
+ iterations?: number;
24
+ }
25
+ /**
26
+ * Animates a cursor by cycling through an ordered array of OSRS icon
27
+ * strings using a pure‑CSS `@keyframes` rule.
28
+ *
29
+ * Each frame is assigned an equal slice of the total `duration` and
30
+ * transitions are **discrete** (`step-end`), producing a clean
31
+ * frame‑by‑frame sprite animation — no JavaScript timers required.
32
+ *
33
+ * **Browser‑only** — in non‑browser environments (Node / SSR) this
34
+ * is a no‑op that returns an empty cleanup function.
35
+ *
36
+ * @param frames - An ordered array of CSS cursor strings (≥ 2).
37
+ * @param options - Optional configuration for duration, target, and iterations.
38
+ * @returns A cleanup function that removes the injected styles and
39
+ * stops the animation.
40
+ *
41
+ * @throws {Error} If fewer than 2 frames are provided.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * import {
46
+ * coins1, coins2, coins3, coins4, coins5,
47
+ * animateCursor,
48
+ * } from '@dava96/osrs-icons';
49
+ *
50
+ * // Animate a growing coin stack on the whole page
51
+ * const stop = animateCursor(
52
+ * [coins1, coins2, coins3, coins4, coins5],
53
+ * { duration: 1200 },
54
+ * );
55
+ *
56
+ * // Later, stop the animation and clean up
57
+ * stop();
58
+ * ```
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * import { lobsterRaw, lobsterCooked, lobsterBurnt, animateCursor } from '@dava96/osrs-icons';
63
+ *
64
+ * // Scope to a specific element, play 3 times
65
+ * const stop = animateCursor(
66
+ * [lobsterRaw, lobsterCooked, lobsterBurnt],
67
+ * { duration: 900, target: document.getElementById('cooking')!, iterations: 3 },
68
+ * );
69
+ * ```
70
+ */
71
+ export declare function animateCursor(frames: string[], options?: AnimateCursorOptions): () => void;
72
+ //# sourceMappingURL=animateCursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animateCursor.d.ts","sourceRoot":"","sources":["../../src/animateCursor.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,IAAI,CAiD9F"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.animateCursor = animateCursor;
4
+ /**
5
+ * Animates a cursor by cycling through an ordered array of OSRS icon
6
+ * strings using a pure‑CSS `@keyframes` rule.
7
+ *
8
+ * Each frame is assigned an equal slice of the total `duration` and
9
+ * transitions are **discrete** (`step-end`), producing a clean
10
+ * frame‑by‑frame sprite animation — no JavaScript timers required.
11
+ *
12
+ * **Browser‑only** — in non‑browser environments (Node / SSR) this
13
+ * is a no‑op that returns an empty cleanup function.
14
+ *
15
+ * @param frames - An ordered array of CSS cursor strings (≥ 2).
16
+ * @param options - Optional configuration for duration, target, and iterations.
17
+ * @returns A cleanup function that removes the injected styles and
18
+ * stops the animation.
19
+ *
20
+ * @throws {Error} If fewer than 2 frames are provided.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import {
25
+ * coins1, coins2, coins3, coins4, coins5,
26
+ * animateCursor,
27
+ * } from '@dava96/osrs-icons';
28
+ *
29
+ * // Animate a growing coin stack on the whole page
30
+ * const stop = animateCursor(
31
+ * [coins1, coins2, coins3, coins4, coins5],
32
+ * { duration: 1200 },
33
+ * );
34
+ *
35
+ * // Later, stop the animation and clean up
36
+ * stop();
37
+ * ```
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { lobsterRaw, lobsterCooked, lobsterBurnt, animateCursor } from '@dava96/osrs-icons';
42
+ *
43
+ * // Scope to a specific element, play 3 times
44
+ * const stop = animateCursor(
45
+ * [lobsterRaw, lobsterCooked, lobsterBurnt],
46
+ * { duration: 900, target: document.getElementById('cooking')!, iterations: 3 },
47
+ * );
48
+ * ```
49
+ */
50
+ function animateCursor(frames, options = {}) {
51
+ if (frames.length < 2) {
52
+ throw new Error(`animateCursor requires at least 2 frames, received ${frames.length}.`);
53
+ }
54
+ if (typeof document === 'undefined') {
55
+ return () => { };
56
+ }
57
+ const { duration = 1000, target, iterations = Infinity } = options;
58
+ const animationName = generateAnimationName();
59
+ const scopeId = `${animationName}-scope`;
60
+ const selector = target ? `[data-osrs-anim-id="${scopeId}"]` : '*';
61
+ if (target) {
62
+ target.setAttribute('data-osrs-anim-id', scopeId);
63
+ }
64
+ const keyframeSteps = frames
65
+ .map((cursorValue, index) => {
66
+ const percentage = ((index / frames.length) * 100).toFixed(2);
67
+ return ` ${percentage}% { cursor: ${cursorValue}; }`;
68
+ })
69
+ .join('\n');
70
+ const iterationCount = iterations === Infinity ? 'infinite' : String(iterations);
71
+ const css = [
72
+ `@keyframes ${animationName} {`,
73
+ keyframeSteps,
74
+ '}',
75
+ `${selector} {`,
76
+ ` animation: ${animationName} ${duration}ms step-end ${iterationCount};`,
77
+ '}',
78
+ ].join('\n');
79
+ const styleElement = document.createElement('style');
80
+ styleElement.textContent = css;
81
+ styleElement.setAttribute('data-osrs-animate', 'true');
82
+ document.head.appendChild(styleElement);
83
+ return () => {
84
+ styleElement.remove();
85
+ if (target) {
86
+ target.removeAttribute('data-osrs-anim-id');
87
+ }
88
+ };
89
+ }
90
+ /** Generates a short unique ID for animation scoping. */
91
+ let animCounter = 0;
92
+ function generateAnimationName() {
93
+ return `osrs-anim-${++animCounter}-${Date.now().toString(36)}`;
94
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Standard CSS cursor states that can be mapped to OSRS icons.
3
+ *
4
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
5
+ */
6
+ export type CursorState = 'default' | 'pointer' | 'wait' | 'text' | 'move' | 'crosshair' | 'grab' | 'grabbing' | 'not-allowed' | 'help' | 'progress' | 'cell' | 'copy' | 'alias' | 'no-drop' | 'col-resize' | 'row-resize' | 'n-resize' | 'e-resize' | 's-resize' | 'w-resize' | 'zoom-in' | 'zoom-out';
7
+ /**
8
+ * A mapping of CSS cursor states to OSRS icon cursor strings.
9
+ *
10
+ * Only include the states you want to override — unlisted states
11
+ * keep their default browser cursor.
12
+ */
13
+ export type CursorMapping = Partial<Record<CursorState, string>>;
14
+ /**
15
+ * Applies OSRS cursor icons to CSS cursor states on a target element
16
+ * or globally across the entire page.
17
+ *
18
+ * Injects a `<style>` tag with CSS rules that map each specified cursor
19
+ * state to the given OSRS icon. Returns a cleanup function that removes
20
+ * the injected styles and restores the previous cursors.
21
+ *
22
+ * **Browser-only** — in non-browser environments this is a no-op that
23
+ * returns an empty cleanup function.
24
+ *
25
+ * @param mapping - An object mapping CSS cursor states to OSRS cursor strings.
26
+ * @param target - Optional element to scope the cursors to. Defaults to the
27
+ * entire document (global).
28
+ * @returns A cleanup function that reverts all applied cursors.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * import { abyssalWhip, dragonScimitar, applyCursors } from '@dava96/osrs-icons';
33
+ *
34
+ * // Apply globally
35
+ * const remove = applyCursors({
36
+ * default: abyssalWhip,
37
+ * pointer: dragonScimitar,
38
+ * });
39
+ *
40
+ * // Later, revert to browser defaults
41
+ * remove();
42
+ * ```
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * import { bucketPack, applyCursors } from '@dava96/osrs-icons';
47
+ *
48
+ * // Scope to a specific element
49
+ * const cleanup = applyCursors(
50
+ * { wait: bucketPack.full },
51
+ * document.getElementById('loading-area')!,
52
+ * );
53
+ * ```
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * import { herringPack, applyCursors } from '@dava96/osrs-icons';
58
+ *
59
+ * // Use the red herring for error states!
60
+ * applyCursors({ not-allowed: herringPack.error });
61
+ * ```
62
+ */
63
+ export declare function applyCursors(mapping: CursorMapping, target?: HTMLElement): () => void;
64
+ //# sourceMappingURL=applyCursors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyCursors.d.ts","sourceRoot":"","sources":["../../src/applyCursors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,SAAS,GACT,MAAM,GACN,MAAM,GACN,MAAM,GACN,WAAW,GACX,MAAM,GACN,UAAU,GACV,aAAa,GACb,MAAM,GACN,UAAU,GACV,MAAM,GACN,MAAM,GACN,OAAO,GACP,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,UAAU,GACV,UAAU,GACV,UAAU,GACV,SAAS,GACT,UAAU,CAAC;AAEf;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,IAAI,CA6BrF"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyCursors = applyCursors;
4
+ /**
5
+ * Applies OSRS cursor icons to CSS cursor states on a target element
6
+ * or globally across the entire page.
7
+ *
8
+ * Injects a `<style>` tag with CSS rules that map each specified cursor
9
+ * state to the given OSRS icon. Returns a cleanup function that removes
10
+ * the injected styles and restores the previous cursors.
11
+ *
12
+ * **Browser-only** — in non-browser environments this is a no-op that
13
+ * returns an empty cleanup function.
14
+ *
15
+ * @param mapping - An object mapping CSS cursor states to OSRS cursor strings.
16
+ * @param target - Optional element to scope the cursors to. Defaults to the
17
+ * entire document (global).
18
+ * @returns A cleanup function that reverts all applied cursors.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { abyssalWhip, dragonScimitar, applyCursors } from '@dava96/osrs-icons';
23
+ *
24
+ * // Apply globally
25
+ * const remove = applyCursors({
26
+ * default: abyssalWhip,
27
+ * pointer: dragonScimitar,
28
+ * });
29
+ *
30
+ * // Later, revert to browser defaults
31
+ * remove();
32
+ * ```
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * import { bucketPack, applyCursors } from '@dava96/osrs-icons';
37
+ *
38
+ * // Scope to a specific element
39
+ * const cleanup = applyCursors(
40
+ * { wait: bucketPack.full },
41
+ * document.getElementById('loading-area')!,
42
+ * );
43
+ * ```
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * import { herringPack, applyCursors } from '@dava96/osrs-icons';
48
+ *
49
+ * // Use the red herring for error states!
50
+ * applyCursors({ not-allowed: herringPack.error });
51
+ * ```
52
+ */
53
+ function applyCursors(mapping, target) {
54
+ if (typeof document === 'undefined') {
55
+ return () => { };
56
+ }
57
+ const styleElement = document.createElement('style');
58
+ const selector = target ? `[data-osrs-cursor-id="${generateId()}"]` : '*';
59
+ if (target) {
60
+ target.setAttribute('data-osrs-cursor-id', selector.slice(22, -2));
61
+ }
62
+ const rules = Object.entries(mapping)
63
+ .map(([state, cursorValue]) => {
64
+ const fallback = state === 'default' ? 'auto' : state;
65
+ return `${selector} { cursor: ${cursorValue.replace(', auto', `, ${fallback}`)}; }`;
66
+ })
67
+ .join('\n');
68
+ styleElement.textContent = rules;
69
+ styleElement.setAttribute('data-osrs-cursors', 'true');
70
+ document.head.appendChild(styleElement);
71
+ return () => {
72
+ styleElement.remove();
73
+ if (target) {
74
+ target.removeAttribute('data-osrs-cursor-id');
75
+ }
76
+ };
77
+ }
78
+ /** Generates a short unique ID for scoping cursor styles to elements. */
79
+ let idCounter = 0;
80
+ function generateId() {
81
+ return `osrs-${++idCounter}-${Date.now().toString(36)}`;
82
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Horizontally flips CSS cursor icons so they point in the opposite direction.
3
+ *
4
+ * Many OSRS inventory icons face right, but cursor conventions typically
5
+ * expect left-facing images. This helper mirrors the embedded base64 PNG
6
+ * using the Canvas API and returns new, ready-to-use CSS cursor strings.
7
+ *
8
+ * Results are cached internally — flipping the same icon twice returns
9
+ * the cached value instantly.
10
+ *
11
+ * **Browser-only** — requires the Canvas API. In non-browser environments
12
+ * (Node.js, SSR) the original cursor strings are returned unchanged.
13
+ *
14
+ * Supports three input shapes:
15
+ * - **Single string** → returns a single flipped string.
16
+ * - **Array of strings** → returns an array of flipped strings (same order).
17
+ * - **Record of strings** → returns a record with the same keys, values flipped.
18
+ * Perfect for flipping an entire pack in one call.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { abyssalWhip, flipCursor } from '@dava96/osrs-icons';
23
+ *
24
+ * // Single icon
25
+ * const flipped = await flipCursor(abyssalWhip);
26
+ * document.body.style.cursor = flipped;
27
+ * ```
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * import { coinsPack, flipCursor } from '@dava96/osrs-icons';
32
+ *
33
+ * // Flip an entire pack
34
+ * const flippedPack = await flipCursor(coinsPack);
35
+ * // flippedPack._1, flippedPack._2, ... are all flipped
36
+ * // flippedPack.stages is a flipped array
37
+ * ```
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { airRune, fireRune, flipCursor } from '@dava96/osrs-icons';
42
+ *
43
+ * // Flip an array of cursors
44
+ * const [flippedAir, flippedFire] = await flipCursor([airRune, fireRune]);
45
+ * ```
46
+ */
47
+ /** Flip a single CSS cursor string. */
48
+ export declare function flipCursor(cursorValue: string): Promise<string>;
49
+ /** Flip an array of CSS cursor strings, preserving order. */
50
+ export declare function flipCursor(cursorValues: readonly string[]): Promise<string[]>;
51
+ /** Flip every string value in a record (e.g. a pack object), preserving keys. */
52
+ export declare function flipCursor<T extends Record<string, unknown>>(pack: T): Promise<{
53
+ [K in keyof T]: T[K] extends string ? string : T[K] extends readonly string[] ? string[] : T[K];
54
+ }>;
55
+ //# sourceMappingURL=flip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flip.d.ts","sourceRoot":"","sources":["../../src/flip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAUH,uCAAuC;AACvC,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAEvE,6DAA6D;AAC7D,wBAAsB,UAAU,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAErF,iFAAiF;AACjF,wBAAsB,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,IAAI,EAAE,CAAC,GACN,OAAO,CAAC;KACR,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;CAChG,CAAC,CAAC"}