@xivdyetools/svg 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.
Files changed (50) hide show
  1. package/README.md +136 -0
  2. package/dist/accessibility-comparison.d.ts +66 -0
  3. package/dist/accessibility-comparison.d.ts.map +1 -0
  4. package/dist/accessibility-comparison.js +201 -0
  5. package/dist/accessibility-comparison.js.map +1 -0
  6. package/dist/base.d.ts +115 -0
  7. package/dist/base.d.ts.map +1 -0
  8. package/dist/base.js +201 -0
  9. package/dist/base.js.map +1 -0
  10. package/dist/budget-comparison.d.ts +121 -0
  11. package/dist/budget-comparison.d.ts.map +1 -0
  12. package/dist/budget-comparison.js +331 -0
  13. package/dist/budget-comparison.js.map +1 -0
  14. package/dist/comparison-grid.d.ts +61 -0
  15. package/dist/comparison-grid.d.ts.map +1 -0
  16. package/dist/comparison-grid.js +366 -0
  17. package/dist/comparison-grid.js.map +1 -0
  18. package/dist/contrast-matrix.d.ts +78 -0
  19. package/dist/contrast-matrix.d.ts.map +1 -0
  20. package/dist/contrast-matrix.js +303 -0
  21. package/dist/contrast-matrix.js.map +1 -0
  22. package/dist/dye-info-card.d.ts +34 -0
  23. package/dist/dye-info-card.d.ts.map +1 -0
  24. package/dist/dye-info-card.js +218 -0
  25. package/dist/dye-info-card.js.map +1 -0
  26. package/dist/gradient.d.ts +49 -0
  27. package/dist/gradient.d.ts.map +1 -0
  28. package/dist/gradient.js +131 -0
  29. package/dist/gradient.js.map +1 -0
  30. package/dist/harmony-wheel.d.ts +38 -0
  31. package/dist/harmony-wheel.d.ts.map +1 -0
  32. package/dist/harmony-wheel.js +158 -0
  33. package/dist/harmony-wheel.js.map +1 -0
  34. package/dist/index.d.ts +31 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +32 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/palette-grid.d.ts +105 -0
  39. package/dist/palette-grid.d.ts.map +1 -0
  40. package/dist/palette-grid.js +277 -0
  41. package/dist/palette-grid.js.map +1 -0
  42. package/dist/preset-swatch.d.ts +76 -0
  43. package/dist/preset-swatch.d.ts.map +1 -0
  44. package/dist/preset-swatch.js +226 -0
  45. package/dist/preset-swatch.js.map +1 -0
  46. package/dist/random-dyes-grid.d.ts +45 -0
  47. package/dist/random-dyes-grid.d.ts.map +1 -0
  48. package/dist/random-dyes-grid.js +143 -0
  49. package/dist/random-dyes-grid.js.map +1 -0
  50. package/package.json +56 -0
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Random Dyes Grid SVG Generator (V4)
3
+ *
4
+ * Generates a visual infographic grid for the /dye random command.
5
+ * Shows 5 randomly selected dyes in an attractive card layout.
6
+ *
7
+ * Layout:
8
+ * +--------------------------------------------------+
9
+ * | 🎲 Random Dyes |
10
+ * +--------------------------------------------------+
11
+ * | [Swatch 1] [Swatch 2] [Swatch 3] |
12
+ * | Name Name Name |
13
+ * | Category Category Category |
14
+ * +--------------------------------------------------+
15
+ * | [Swatch 4] [Swatch 5] |
16
+ * | Name Name |
17
+ * | Category Category |
18
+ * +--------------------------------------------------+
19
+ *
20
+ * @module services/svg/random-dyes-grid
21
+ */
22
+ import { createSvgDocument, rect, text, THEME, FONTS, escapeXml, getContrastTextColor, } from './base.js';
23
+ // ============================================================================
24
+ // Constants
25
+ // ============================================================================
26
+ const DEFAULT_WIDTH = 600;
27
+ const PADDING = 20;
28
+ const TITLE_HEIGHT = 50;
29
+ const CARD_WIDTH = 170;
30
+ const CARD_HEIGHT = 140;
31
+ const CARD_GAP = 20;
32
+ // ============================================================================
33
+ // SVG Generation
34
+ // ============================================================================
35
+ /**
36
+ * Generate a visual grid of random dyes
37
+ */
38
+ export function generateRandomDyesGrid(options) {
39
+ const { dyes, title = '🎲 Random Dyes', width = DEFAULT_WIDTH, uniqueCategories = false, } = options;
40
+ // Calculate layout
41
+ const cardsPerRow = 3;
42
+ const rows = Math.ceil(dyes.length / cardsPerRow);
43
+ const gridHeight = rows * (CARD_HEIGHT + CARD_GAP) - CARD_GAP;
44
+ const height = TITLE_HEIGHT + gridHeight + PADDING * 2;
45
+ const elements = [];
46
+ // Background
47
+ elements.push(rect(0, 0, width, height, THEME.background, { rx: 16, ry: 16 }));
48
+ // Title
49
+ elements.push(text(width / 2, PADDING + 24, title, {
50
+ fill: THEME.text,
51
+ fontSize: 22,
52
+ fontFamily: FONTS.headerCjk,
53
+ fontWeight: 600,
54
+ textAnchor: 'middle',
55
+ }));
56
+ // Subtitle based on mode
57
+ const subtitle = uniqueCategories
58
+ ? 'One from each category'
59
+ : `${dyes.length} randomly selected dyes`;
60
+ elements.push(text(width / 2, PADDING + 42, subtitle, {
61
+ fill: THEME.textMuted,
62
+ fontSize: 12,
63
+ fontFamily: FONTS.primary,
64
+ textAnchor: 'middle',
65
+ }));
66
+ // Calculate starting position for cards (centered)
67
+ const totalGridWidth = Math.min(dyes.length, cardsPerRow) * (CARD_WIDTH + CARD_GAP) - CARD_GAP;
68
+ const startX = (width - totalGridWidth) / 2;
69
+ const startY = TITLE_HEIGHT + PADDING;
70
+ // Draw dye cards
71
+ dyes.forEach((dyeInfo, index) => {
72
+ const row = Math.floor(index / cardsPerRow);
73
+ const col = index % cardsPerRow;
74
+ // Center the last row if it has fewer cards
75
+ const cardsInThisRow = Math.min(cardsPerRow, dyes.length - row * cardsPerRow);
76
+ const rowWidth = cardsInThisRow * (CARD_WIDTH + CARD_GAP) - CARD_GAP;
77
+ const rowStartX = (width - rowWidth) / 2;
78
+ const cardX = rowStartX + col * (CARD_WIDTH + CARD_GAP);
79
+ const cardY = startY + row * (CARD_HEIGHT + CARD_GAP);
80
+ elements.push(generateDyeCard(dyeInfo, cardX, cardY));
81
+ });
82
+ // Footer
83
+ elements.push(text(width / 2, height - 8, 'XIV Dye Tools • Run again for new results', {
84
+ fill: THEME.textDim,
85
+ fontSize: 10,
86
+ fontFamily: FONTS.primary,
87
+ textAnchor: 'middle',
88
+ }));
89
+ return createSvgDocument(width, height, elements.join('\n'));
90
+ }
91
+ /**
92
+ * Generate a single dye card
93
+ */
94
+ function generateDyeCard(dyeInfo, x, y) {
95
+ const { dye, localizedName, localizedCategory } = dyeInfo;
96
+ const elements = [];
97
+ const swatchHeight = 80;
98
+ const infoHeight = CARD_HEIGHT - swatchHeight;
99
+ // Card background
100
+ elements.push(rect(x, y, CARD_WIDTH, CARD_HEIGHT, THEME.backgroundLight, {
101
+ rx: 12,
102
+ ry: 12,
103
+ }));
104
+ // Color swatch (top portion)
105
+ elements.push(rect(x, y, CARD_WIDTH, swatchHeight, dye.hex, {
106
+ rx: 12,
107
+ ry: 12,
108
+ }));
109
+ // Flatten bottom corners of swatch
110
+ elements.push(rect(x, y + swatchHeight - 12, CARD_WIDTH, 12, dye.hex));
111
+ // Hex value on swatch
112
+ const textColor = getContrastTextColor(dye.hex);
113
+ elements.push(text(x + CARD_WIDTH / 2, y + swatchHeight / 2 + 4, dye.hex.toUpperCase(), {
114
+ fill: textColor,
115
+ fontSize: 14,
116
+ fontFamily: FONTS.mono,
117
+ fontWeight: 600,
118
+ textAnchor: 'middle',
119
+ }));
120
+ // Info section
121
+ const infoY = y + swatchHeight + 12;
122
+ // Dye name (truncate if too long)
123
+ const maxNameLength = 18;
124
+ const displayName = localizedName.length > maxNameLength
125
+ ? localizedName.substring(0, maxNameLength - 1) + '…'
126
+ : localizedName;
127
+ elements.push(text(x + CARD_WIDTH / 2, infoY, escapeXml(displayName), {
128
+ fill: THEME.text,
129
+ fontSize: 13,
130
+ fontFamily: FONTS.primaryCjk,
131
+ fontWeight: 600,
132
+ textAnchor: 'middle',
133
+ }));
134
+ // Category
135
+ elements.push(text(x + CARD_WIDTH / 2, infoY + 18, localizedCategory, {
136
+ fill: THEME.textMuted,
137
+ fontSize: 11,
138
+ fontFamily: FONTS.primaryCjk,
139
+ textAnchor: 'middle',
140
+ }));
141
+ return elements.join('\n');
142
+ }
143
+ //# sourceMappingURL=random-dyes-grid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random-dyes-grid.js","sourceRoot":"","sources":["../src/random-dyes-grid.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@xivdyetools/svg",
3
+ "version": "1.0.0",
4
+ "description": "Platform-agnostic SVG card generators for the XIV Dye Tools ecosystem (pure functions: data in → SVG string out)",
5
+ "author": "XIV Dye Tools",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "sideEffects": false,
21
+ "dependencies": {
22
+ "@xivdyetools/color-blending": "1.0.0",
23
+ "@xivdyetools/core": "1.17.0",
24
+ "@xivdyetools/types": "1.8.0"
25
+ },
26
+ "devDependencies": {
27
+ "@vitest/coverage-v8": "^4.0.18",
28
+ "vitest": "^4.0.18",
29
+ "@xivdyetools/test-utils": "1.1.1"
30
+ },
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "keywords": [
35
+ "xivdyetools",
36
+ "svg",
37
+ "card",
38
+ "generator",
39
+ "ffxiv",
40
+ "typescript"
41
+ ],
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/FlashGalatine/xivdyetools.git",
45
+ "directory": "packages/svg"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc -p tsconfig.build.json",
49
+ "type-check": "tsc --noEmit",
50
+ "clean": "rimraf dist coverage",
51
+ "lint": "eslint src",
52
+ "test": "vitest run",
53
+ "test:watch": "vitest",
54
+ "test:coverage": "vitest run --coverage"
55
+ }
56
+ }