@bccampus/ui-components 0.1.0 → 0.2.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 (65) hide show
  1. package/dist/banner.d.ts +16 -0
  2. package/dist/banner.js +42 -0
  3. package/dist/button.d.ts +5 -4
  4. package/dist/button.js +20 -14
  5. package/dist/caption.js +9 -8
  6. package/dist/card.d.ts +15 -9
  7. package/dist/card.js +62 -84
  8. package/dist/createLucideIcon-CzehbSja.js +94 -0
  9. package/dist/horizontal-list.d.ts +9 -2
  10. package/dist/horizontal-list.js +47 -115
  11. package/dist/icon-generator.d.ts +2 -1
  12. package/dist/icon-generator.js +180 -147
  13. package/dist/index-CQhYMnjT.js +34 -0
  14. package/dist/index-DlfV3JTY.js +70 -0
  15. package/dist/input.d.ts +7 -0
  16. package/dist/input.js +18 -0
  17. package/dist/masked-image-generator.d.ts +1 -0
  18. package/dist/overlay.d.ts +13 -0
  19. package/dist/overlay.js +27 -0
  20. package/dist/page-header.d.ts +5 -0
  21. package/dist/page-header.js +943 -0
  22. package/dist/page-section.d.ts +14 -0
  23. package/dist/page-section.js +31 -0
  24. package/dist/page.d.ts +7 -0
  25. package/dist/page.js +8 -0
  26. package/dist/search-input.d.ts +7 -0
  27. package/dist/search-input.js +23 -0
  28. package/dist/tag.d.ts +2 -2
  29. package/dist/tag.js +10 -9
  30. package/dist/ui-components.d.ts +84 -29
  31. package/dist/ui-components.js +42 -27
  32. package/package.json +44 -15
  33. package/src/assets/images/image_06.jpg +0 -0
  34. package/src/components/ui/banner.tsx +48 -0
  35. package/src/components/ui/button.tsx +52 -47
  36. package/src/components/ui/card.tsx +131 -147
  37. package/src/components/ui/horizontal-list.tsx +75 -50
  38. package/src/components/ui/icon-generator/generate-tiles.tsx +243 -243
  39. package/src/components/ui/icon-generator/icon-generator.tsx +84 -51
  40. package/src/components/ui/icon-generator/masked-image-generator.tsx +38 -38
  41. package/src/components/ui/icon-generator/types.ts +53 -52
  42. package/src/components/ui/index.ts +11 -4
  43. package/src/components/ui/input.tsx +17 -0
  44. package/src/components/ui/overlay.tsx +29 -0
  45. package/src/components/ui/page-header.tsx +16 -0
  46. package/src/components/ui/page-section.tsx +33 -0
  47. package/src/components/ui/page.tsx +9 -0
  48. package/src/components/ui/search-input.tsx +16 -0
  49. package/src/components/ui/tag.tsx +39 -39
  50. package/src/components/ui/typography/caption.tsx +32 -32
  51. package/src/styles/all.css +4 -4
  52. package/src/styles/colors.css +9 -10
  53. package/src/styles/index.css +7 -7
  54. package/src/styles/theme.css +56 -2
  55. package/src/styles/typography.css +480 -479
  56. package/tsconfig.app.json +37 -37
  57. package/vite.config.ts +51 -44
  58. package/dist/@bccampus-ui-components-0.1.0.tgz +0 -0
  59. package/dist/index-DcqAdr0d.js +0 -102
  60. package/dist/mockServiceWorker.js +0 -348
  61. package/public/mockServiceWorker.js +0 -348
  62. package/src/assets/images/bg_pattern_01.png +0 -0
  63. package/src/assets/images/bg_pattern_02.png +0 -0
  64. package/src/assets/images/bg_pattern_03.png +0 -0
  65. package/src/assets/images/bg_pattern_04.png +0 -0
@@ -1,243 +1,243 @@
1
- import type { JSX } from "react";
2
- import type { TileConfig } from "./types";
3
- import { cn } from "@/lib/utils";
4
- import { TileShape } from "./types";
5
-
6
- const randomSet = [
7
- TileShape.Square,
8
- TileShape.Circle,
9
- TileShape.Diamond,
10
- TileShape.Hexagon,
11
- TileShape.TriangleSE,
12
- TileShape.TriangleSW,
13
- TileShape.TriangleNW,
14
- TileShape.TriangleNE,
15
- TileShape.PieSE,
16
- TileShape.PieSW,
17
- TileShape.PieNW,
18
- TileShape.PieNE,
19
- ];
20
-
21
- type TileTemplatesConfig = TileConfig & Required<Pick<TileConfig, "scale">>;
22
-
23
- const TileTemplates: Record<
24
- TileShape,
25
- (tileX: number, tileY: number, tileSize: number, tileConfig: TileTemplatesConfig) => JSX.Element | null
26
- > = {
27
- [TileShape.Blank]: () => null,
28
-
29
- [TileShape.Rand]: (tileX, tileY, tileSize, tileConfig) =>
30
- TileTemplates[randomSet[Math.floor(Math.random() * randomSet.length)]](tileX, tileY, tileSize, tileConfig),
31
-
32
- [TileShape.Mosaic]: (tileX, tileY, tileSize, tileConfig) =>
33
- TileTemplates[Math.random() > 0.8 ? TileShape.Blank : TileShape.Square](tileX, tileY, tileSize, tileConfig),
34
- [TileShape.MosaicCircle]: (tileX, tileY, tileSize, tileConfig) =>
35
- TileTemplates[Math.random() > 0.8 ? TileShape.Blank : TileShape.Circle](tileX, tileY, tileSize, tileConfig),
36
- [TileShape.MosaicDiamond]: (tileX, tileY, tileSize, tileConfig) =>
37
- TileTemplates[Math.random() > 0.8 ? TileShape.Blank : TileShape.Diamond](tileX, tileY, tileSize, tileConfig),
38
-
39
- [TileShape.Square]: (tileX, tileY, tileSize, tileConfig) => (
40
- <rect
41
- key={`tile-${tileX}-${tileY}`}
42
- x={tileSize * tileX}
43
- y={tileSize * tileY}
44
- width={tileSize * tileConfig.scale}
45
- height={tileSize * tileConfig.scale}
46
- className={cn("fill-current stroke-none", tileConfig?.className)}
47
- />
48
- ),
49
-
50
- [TileShape.Circle]: (tileX, tileY, tileSize, tileConfig) => (
51
- <circle
52
- key={`tile-${tileX}-${tileY}`}
53
- cx={tileSize * (tileX + 0.5 * tileConfig.scale)}
54
- cy={tileSize * (tileY + 0.5 * tileConfig.scale)}
55
- r={(tileSize / 2) * tileConfig.scale}
56
- className={cn("fill-current stroke-none", tileConfig?.className)}
57
- />
58
- ),
59
-
60
- [TileShape.Diamond]: (tileX, tileY, tileSize, tileConfig) => (
61
- <path
62
- key={`tile-${tileX}-${tileY}`}
63
- d={`M ${tileSize * (tileX + 0.5 * tileConfig.scale)} ${tileSize * tileY}
64
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + 0.5 * tileConfig.scale)}
65
- L ${tileSize * (tileX + 0.5 * tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)}
66
- L ${tileSize * tileX} ${tileSize * (tileY + 0.5 * tileConfig.scale)} Z`}
67
- className={cn("fill-current stroke-none", tileConfig?.className)}
68
- />
69
- ),
70
- [TileShape.Hexagon]: (tileX, tileY, tileSize, tileConfig) => {
71
- const side = tileSize / Math.sqrt(3);
72
- const start = (tileSize - side) / 2;
73
- return (
74
- <path
75
- rotate={45}
76
- key={`tile-${tileX}-${tileY}`}
77
- d={`M ${tileSize * tileX + start * tileConfig.scale} ${tileSize * tileY}
78
- L ${tileSize * tileX + (start + side) * tileConfig.scale} ${tileSize * tileY}
79
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + 0.5 * tileConfig.scale)}
80
- L ${tileSize * tileX + (start + side) * tileConfig.scale} ${tileSize * (tileY + tileConfig.scale)}
81
- L ${tileSize * tileX + start * tileConfig.scale} ${tileSize * (tileY + tileConfig.scale)}
82
- L ${tileSize * tileX} ${tileSize * (tileY + 0.5 * tileConfig.scale)} Z`}
83
- className={cn("fill-current stroke-none", tileConfig?.className)}
84
- />
85
- );
86
- },
87
- [TileShape.RandBasic]: (tileX, tileY, tileSize, tileConfig) =>
88
- TileTemplates[(TileShape.Square + Math.floor(Math.random() * 4)) as TileShape](tileX, tileY, tileSize, tileConfig),
89
-
90
- [TileShape.TriangleSE]: (tileX, tileY, tileSize, tileConfig) => (
91
- <path
92
- key={`tile-${tileX}-${tileY}`}
93
- d={`M ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY}
94
- L ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)}
95
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)} Z`}
96
- className={cn("fill-current stroke-none", tileConfig?.className)}
97
- />
98
- ),
99
- [TileShape.TriangleSW]: (tileX, tileY, tileSize, tileConfig) => (
100
- <path
101
- key={`tile-${tileX}-${tileY}`}
102
- d={`M ${tileSize * tileX} ${tileSize * tileY}
103
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)}
104
- L ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)} Z`}
105
- className={cn("fill-current stroke-none", tileConfig?.className)}
106
- />
107
- ),
108
- [TileShape.TriangleNW]: (tileX, tileY, tileSize, tileConfig) => (
109
- <path
110
- key={`tile-${tileX}-${tileY}`}
111
- d={`M ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY}
112
- L ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)}
113
- L ${tileSize * tileX} ${tileSize * tileY} Z`}
114
- className={cn("fill-current stroke-none", tileConfig?.className)}
115
- />
116
- ),
117
- [TileShape.TriangleNE]: (tileX, tileY, tileSize, tileConfig) => (
118
- <path
119
- key={`tile-${tileX}-${tileY}`}
120
- d={`M ${tileSize * tileX} ${tileSize * tileY}
121
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)}
122
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY} Z`}
123
- className={cn("fill-current stroke-none", tileConfig?.className)}
124
- />
125
- ),
126
- [TileShape.TriangleRand]: (tileX, tileY, tileSize, tileConfig) =>
127
- TileTemplates[(TileShape.TriangleSE + Math.floor(Math.random() * 4)) as TileShape](
128
- tileX,
129
- tileY,
130
- tileSize,
131
- tileConfig
132
- ),
133
-
134
- [TileShape.CaretN]: (tileX, tileY, tileSize, tileConfig) => (
135
- <path
136
- key={`tile-${tileX}-${tileY}`}
137
- d={`M ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)}
138
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)}
139
- L ${tileSize * (tileX + 0.5 * tileConfig.scale)} ${tileSize * tileY} Z`}
140
- className={cn("fill-current stroke-none", tileConfig?.className)}
141
- />
142
- ),
143
- [TileShape.CaretE]: (tileX, tileY, tileSize, tileConfig) => (
144
- <path
145
- key={`tile-${tileX}-${tileY}`}
146
- d={`M ${tileSize * tileX} ${tileSize * tileY}
147
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + 0.5 * tileConfig.scale)}
148
- L ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)} Z`}
149
- className={cn("fill-current stroke-none", tileConfig?.className)}
150
- />
151
- ),
152
- [TileShape.CaretS]: (tileX, tileY, tileSize, tileConfig) => (
153
- <path
154
- key={`tile-${tileX}-${tileY}`}
155
- d={`M ${tileSize * tileX} ${tileSize * tileY}
156
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY}
157
- L ${tileSize * (tileX + 0.5 * tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)} Z`}
158
- className={cn("fill-current stroke-none", tileConfig?.className)}
159
- />
160
- ),
161
- [TileShape.CaretW]: (tileX, tileY, tileSize, tileConfig) => (
162
- <path
163
- key={`tile-${tileX}-${tileY}`}
164
- d={`M ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY}
165
- L ${tileSize * tileX} ${tileSize * (tileY + 0.5 * tileConfig.scale)}
166
- L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)} Z`}
167
- className={cn("fill-current stroke-none", tileConfig?.className)}
168
- />
169
- ),
170
- [TileShape.CaretRand]: (tileX, tileY, tileSize, tileConfig) =>
171
- TileTemplates[(TileShape.CaretN + Math.floor(Math.random() * 4)) as TileShape](tileX, tileY, tileSize, tileConfig),
172
-
173
- [TileShape.PieSE]: (tileX, tileY, tileSize, tileConfig) => (
174
- <path
175
- key={`tile-${tileX}-${tileY}`}
176
- d={`M ${tileSize * tileConfig.scale + tileSize * tileX} ${tileSize * tileY}
177
- A ${tileSize * tileConfig.scale} ${tileSize * tileConfig.scale}, 0, 0, 0, ${tileSize * tileX} ${
178
- tileSize * tileConfig.scale + tileSize * tileY
179
- }
180
- L ${tileSize * tileConfig.scale + tileSize * tileX} ${tileSize * tileConfig.scale + tileSize * tileY} Z`}
181
- className={cn("fill-current stroke-none", tileConfig?.className)}
182
- />
183
- ),
184
- [TileShape.PieSW]: (tileX, tileY, tileSize, tileConfig) => (
185
- <path
186
- key={`tile-${tileX}-${tileY}`}
187
- d={`M ${tileSize * tileConfig.scale + tileSize * tileX} ${tileSize * tileConfig.scale + tileSize * tileY}
188
- A ${tileSize * tileConfig.scale} ${tileSize * tileConfig.scale}, 0, 0, 0, ${tileSize * tileX} ${tileSize * tileY}
189
- L ${tileSize * tileX} ${tileSize * tileConfig.scale + tileSize * tileY} Z`}
190
- className={cn("fill-current stroke-none", tileConfig?.className)}
191
- />
192
- ),
193
- [TileShape.PieNW]: (tileX, tileY, tileSize, tileConfig) => (
194
- <path
195
- key={`tile-${tileX}-${tileY}`}
196
- d={`M ${tileSize * tileX} ${tileSize * tileConfig.scale + tileSize * tileY}
197
- A ${tileSize * tileConfig.scale} ${tileSize * tileConfig.scale}, 0, 0, 0, ${
198
- tileSize * tileConfig.scale + tileSize * tileX
199
- } ${tileSize * tileY}
200
- L ${tileSize * tileX} ${tileSize * tileY} Z`}
201
- className={cn("fill-current stroke-none", tileConfig?.className)}
202
- />
203
- ),
204
- [TileShape.PieNE]: (tileX, tileY, tileSize, tileConfig) => (
205
- <path
206
- key={`tile-${tileX}-${tileY}`}
207
- d={`M ${tileSize * tileX} ${tileSize * tileY}
208
- A ${tileSize * tileConfig.scale} ${tileSize * tileConfig.scale}, 0, 0, 0, ${
209
- tileSize * tileConfig.scale + tileSize * tileX
210
- } ${tileSize * tileConfig.scale + tileSize * tileY}
211
- L ${tileSize * tileConfig.scale + tileSize * tileX} ${tileSize * tileY} Z`}
212
- className={cn("fill-current stroke-none", tileConfig?.className)}
213
- />
214
- ),
215
- [TileShape.PieRand]: (tileX, tileY, tileSize, tileConfig) =>
216
- TileTemplates[(TileShape.PieSE + Math.floor(Math.random() * 4)) as TileShape](tileX, tileY, tileSize, tileConfig),
217
- };
218
-
219
- export const generateIconPattern = (width: number, height: number, tileConfig: TileShape | TileConfig) => {
220
- const pattern: (TileShape | TileConfig)[][] = [];
221
- for (let y = 0; y < height; y++) {
222
- pattern[y] = [];
223
- for (let x = 0; x < width; x++) {
224
- pattern[y].push(tileConfig);
225
- }
226
- }
227
-
228
- return pattern;
229
- };
230
-
231
- export const generateTiles = (pattern: (TileShape | TileConfig)[][], tileSize: number, tileClassName?: string) =>
232
- pattern
233
- .map((rows, y) =>
234
- rows.map((item, x) => {
235
- const tileConfig: TileTemplatesConfig =
236
- typeof item === "object"
237
- ? { className: cn(tileClassName, item.className), scale: item.scale ?? 1, shape: item.shape }
238
- : { className: tileClassName, scale: 1, shape: item };
239
-
240
- return TileTemplates[tileConfig.shape](x, y, tileSize, tileConfig);
241
- })
242
- )
243
- .flat();
1
+ import type { JSX } from "react";
2
+ import type { TileConfig } from "./types";
3
+ import { cn } from "@/lib/utils";
4
+ import { TileShape } from "./types";
5
+
6
+ const randomSet = [
7
+ TileShape.Square,
8
+ TileShape.Circle,
9
+ TileShape.Diamond,
10
+ TileShape.Hexagon,
11
+ TileShape.TriangleSE,
12
+ TileShape.TriangleSW,
13
+ TileShape.TriangleNW,
14
+ TileShape.TriangleNE,
15
+ TileShape.PieSE,
16
+ TileShape.PieSW,
17
+ TileShape.PieNW,
18
+ TileShape.PieNE,
19
+ ];
20
+
21
+ type TileTemplatesConfig = TileConfig & Required<Pick<TileConfig, "scale">>;
22
+
23
+ const TileTemplates: Record<
24
+ TileShape,
25
+ (tileX: number, tileY: number, tileSize: number, tileConfig: TileTemplatesConfig) => JSX.Element | null
26
+ > = {
27
+ [TileShape.Blank]: () => null,
28
+
29
+ [TileShape.Rand]: (tileX, tileY, tileSize, tileConfig) =>
30
+ TileTemplates[randomSet[Math.floor(Math.random() * randomSet.length)]](tileX, tileY, tileSize, tileConfig),
31
+
32
+ [TileShape.Mosaic]: (tileX, tileY, tileSize, tileConfig) =>
33
+ TileTemplates[Math.random() > 0.8 ? TileShape.Blank : TileShape.Square](tileX, tileY, tileSize, tileConfig),
34
+ [TileShape.MosaicCircle]: (tileX, tileY, tileSize, tileConfig) =>
35
+ TileTemplates[Math.random() > 0.8 ? TileShape.Blank : TileShape.Circle](tileX, tileY, tileSize, tileConfig),
36
+ [TileShape.MosaicDiamond]: (tileX, tileY, tileSize, tileConfig) =>
37
+ TileTemplates[Math.random() > 0.8 ? TileShape.Blank : TileShape.Diamond](tileX, tileY, tileSize, tileConfig),
38
+
39
+ [TileShape.Square]: (tileX, tileY, tileSize, tileConfig) => (
40
+ <rect
41
+ key={`tile-${tileX}-${tileY}`}
42
+ x={tileSize * tileX}
43
+ y={tileSize * tileY}
44
+ width={tileSize * tileConfig.scale}
45
+ height={tileSize * tileConfig.scale}
46
+ className={cn("fill-current stroke-none", tileConfig?.className)}
47
+ />
48
+ ),
49
+
50
+ [TileShape.Circle]: (tileX, tileY, tileSize, tileConfig) => (
51
+ <circle
52
+ key={`tile-${tileX}-${tileY}`}
53
+ cx={tileSize * (tileX + 0.5 * tileConfig.scale)}
54
+ cy={tileSize * (tileY + 0.5 * tileConfig.scale)}
55
+ r={(tileSize / 2) * tileConfig.scale}
56
+ className={cn("fill-current stroke-none", tileConfig?.className)}
57
+ />
58
+ ),
59
+
60
+ [TileShape.Diamond]: (tileX, tileY, tileSize, tileConfig) => (
61
+ <path
62
+ key={`tile-${tileX}-${tileY}`}
63
+ d={`M ${tileSize * (tileX + 0.5 * tileConfig.scale)} ${tileSize * tileY}
64
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + 0.5 * tileConfig.scale)}
65
+ L ${tileSize * (tileX + 0.5 * tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)}
66
+ L ${tileSize * tileX} ${tileSize * (tileY + 0.5 * tileConfig.scale)} Z`}
67
+ className={cn("fill-current stroke-none", tileConfig?.className)}
68
+ />
69
+ ),
70
+ [TileShape.Hexagon]: (tileX, tileY, tileSize, tileConfig) => {
71
+ const side = tileSize / Math.sqrt(3);
72
+ const start = (tileSize - side) / 2;
73
+ return (
74
+ <path
75
+ rotate={45}
76
+ key={`tile-${tileX}-${tileY}`}
77
+ d={`M ${tileSize * tileX + start * tileConfig.scale} ${tileSize * tileY}
78
+ L ${tileSize * tileX + (start + side) * tileConfig.scale} ${tileSize * tileY}
79
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + 0.5 * tileConfig.scale)}
80
+ L ${tileSize * tileX + (start + side) * tileConfig.scale} ${tileSize * (tileY + tileConfig.scale)}
81
+ L ${tileSize * tileX + start * tileConfig.scale} ${tileSize * (tileY + tileConfig.scale)}
82
+ L ${tileSize * tileX} ${tileSize * (tileY + 0.5 * tileConfig.scale)} Z`}
83
+ className={cn("fill-current stroke-none", tileConfig?.className)}
84
+ />
85
+ );
86
+ },
87
+ [TileShape.RandBasic]: (tileX, tileY, tileSize, tileConfig) =>
88
+ TileTemplates[(TileShape.Square + Math.floor(Math.random() * 4)) as TileShape](tileX, tileY, tileSize, tileConfig),
89
+
90
+ [TileShape.TriangleSE]: (tileX, tileY, tileSize, tileConfig) => (
91
+ <path
92
+ key={`tile-${tileX}-${tileY}`}
93
+ d={`M ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY}
94
+ L ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)}
95
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)} Z`}
96
+ className={cn("fill-current stroke-none", tileConfig?.className)}
97
+ />
98
+ ),
99
+ [TileShape.TriangleSW]: (tileX, tileY, tileSize, tileConfig) => (
100
+ <path
101
+ key={`tile-${tileX}-${tileY}`}
102
+ d={`M ${tileSize * tileX} ${tileSize * tileY}
103
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)}
104
+ L ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)} Z`}
105
+ className={cn("fill-current stroke-none", tileConfig?.className)}
106
+ />
107
+ ),
108
+ [TileShape.TriangleNW]: (tileX, tileY, tileSize, tileConfig) => (
109
+ <path
110
+ key={`tile-${tileX}-${tileY}`}
111
+ d={`M ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY}
112
+ L ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)}
113
+ L ${tileSize * tileX} ${tileSize * tileY} Z`}
114
+ className={cn("fill-current stroke-none", tileConfig?.className)}
115
+ />
116
+ ),
117
+ [TileShape.TriangleNE]: (tileX, tileY, tileSize, tileConfig) => (
118
+ <path
119
+ key={`tile-${tileX}-${tileY}`}
120
+ d={`M ${tileSize * tileX} ${tileSize * tileY}
121
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)}
122
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY} Z`}
123
+ className={cn("fill-current stroke-none", tileConfig?.className)}
124
+ />
125
+ ),
126
+ [TileShape.TriangleRand]: (tileX, tileY, tileSize, tileConfig) =>
127
+ TileTemplates[(TileShape.TriangleSE + Math.floor(Math.random() * 4)) as TileShape](
128
+ tileX,
129
+ tileY,
130
+ tileSize,
131
+ tileConfig
132
+ ),
133
+
134
+ [TileShape.CaretN]: (tileX, tileY, tileSize, tileConfig) => (
135
+ <path
136
+ key={`tile-${tileX}-${tileY}`}
137
+ d={`M ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)}
138
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)}
139
+ L ${tileSize * (tileX + 0.5 * tileConfig.scale)} ${tileSize * tileY} Z`}
140
+ className={cn("fill-current stroke-none", tileConfig?.className)}
141
+ />
142
+ ),
143
+ [TileShape.CaretE]: (tileX, tileY, tileSize, tileConfig) => (
144
+ <path
145
+ key={`tile-${tileX}-${tileY}`}
146
+ d={`M ${tileSize * tileX} ${tileSize * tileY}
147
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + 0.5 * tileConfig.scale)}
148
+ L ${tileSize * tileX} ${tileSize * (tileY + tileConfig.scale)} Z`}
149
+ className={cn("fill-current stroke-none", tileConfig?.className)}
150
+ />
151
+ ),
152
+ [TileShape.CaretS]: (tileX, tileY, tileSize, tileConfig) => (
153
+ <path
154
+ key={`tile-${tileX}-${tileY}`}
155
+ d={`M ${tileSize * tileX} ${tileSize * tileY}
156
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY}
157
+ L ${tileSize * (tileX + 0.5 * tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)} Z`}
158
+ className={cn("fill-current stroke-none", tileConfig?.className)}
159
+ />
160
+ ),
161
+ [TileShape.CaretW]: (tileX, tileY, tileSize, tileConfig) => (
162
+ <path
163
+ key={`tile-${tileX}-${tileY}`}
164
+ d={`M ${tileSize * (tileX + tileConfig.scale)} ${tileSize * tileY}
165
+ L ${tileSize * tileX} ${tileSize * (tileY + 0.5 * tileConfig.scale)}
166
+ L ${tileSize * (tileX + tileConfig.scale)} ${tileSize * (tileY + tileConfig.scale)} Z`}
167
+ className={cn("fill-current stroke-none", tileConfig?.className)}
168
+ />
169
+ ),
170
+ [TileShape.CaretRand]: (tileX, tileY, tileSize, tileConfig) =>
171
+ TileTemplates[(TileShape.CaretN + Math.floor(Math.random() * 4)) as TileShape](tileX, tileY, tileSize, tileConfig),
172
+
173
+ [TileShape.PieSE]: (tileX, tileY, tileSize, tileConfig) => (
174
+ <path
175
+ key={`tile-${tileX}-${tileY}`}
176
+ d={`M ${tileSize * tileConfig.scale + tileSize * tileX} ${tileSize * tileY}
177
+ A ${tileSize * tileConfig.scale} ${tileSize * tileConfig.scale}, 0, 0, 0, ${tileSize * tileX} ${
178
+ tileSize * tileConfig.scale + tileSize * tileY
179
+ }
180
+ L ${tileSize * tileConfig.scale + tileSize * tileX} ${tileSize * tileConfig.scale + tileSize * tileY} Z`}
181
+ className={cn("fill-current stroke-none", tileConfig?.className)}
182
+ />
183
+ ),
184
+ [TileShape.PieSW]: (tileX, tileY, tileSize, tileConfig) => (
185
+ <path
186
+ key={`tile-${tileX}-${tileY}`}
187
+ d={`M ${tileSize * tileConfig.scale + tileSize * tileX} ${tileSize * tileConfig.scale + tileSize * tileY}
188
+ A ${tileSize * tileConfig.scale} ${tileSize * tileConfig.scale}, 0, 0, 0, ${tileSize * tileX} ${tileSize * tileY}
189
+ L ${tileSize * tileX} ${tileSize * tileConfig.scale + tileSize * tileY} Z`}
190
+ className={cn("fill-current stroke-none", tileConfig?.className)}
191
+ />
192
+ ),
193
+ [TileShape.PieNW]: (tileX, tileY, tileSize, tileConfig) => (
194
+ <path
195
+ key={`tile-${tileX}-${tileY}`}
196
+ d={`M ${tileSize * tileX} ${tileSize * tileConfig.scale + tileSize * tileY}
197
+ A ${tileSize * tileConfig.scale} ${tileSize * tileConfig.scale}, 0, 0, 0, ${
198
+ tileSize * tileConfig.scale + tileSize * tileX
199
+ } ${tileSize * tileY}
200
+ L ${tileSize * tileX} ${tileSize * tileY} Z`}
201
+ className={cn("fill-current stroke-none", tileConfig?.className)}
202
+ />
203
+ ),
204
+ [TileShape.PieNE]: (tileX, tileY, tileSize, tileConfig) => (
205
+ <path
206
+ key={`tile-${tileX}-${tileY}`}
207
+ d={`M ${tileSize * tileX} ${tileSize * tileY}
208
+ A ${tileSize * tileConfig.scale} ${tileSize * tileConfig.scale}, 0, 0, 0, ${
209
+ tileSize * tileConfig.scale + tileSize * tileX
210
+ } ${tileSize * tileConfig.scale + tileSize * tileY}
211
+ L ${tileSize * tileConfig.scale + tileSize * tileX} ${tileSize * tileY} Z`}
212
+ className={cn("fill-current stroke-none", tileConfig?.className)}
213
+ />
214
+ ),
215
+ [TileShape.PieRand]: (tileX, tileY, tileSize, tileConfig) =>
216
+ TileTemplates[(TileShape.PieSE + Math.floor(Math.random() * 4)) as TileShape](tileX, tileY, tileSize, tileConfig),
217
+ };
218
+
219
+ export const generateIconPattern = (width: number, height: number, tileConfig: TileShape | TileConfig) => {
220
+ const pattern: (TileShape | TileConfig)[][] = [];
221
+ for (let y = 0; y < height; y++) {
222
+ pattern[y] = [];
223
+ for (let x = 0; x < width; x++) {
224
+ pattern[y].push(tileConfig);
225
+ }
226
+ }
227
+
228
+ return pattern;
229
+ };
230
+
231
+ export const generateTiles = (pattern: (TileShape | TileConfig)[][], tileSize: number, tileClassName?: string) =>
232
+ pattern
233
+ .map((rows, y) =>
234
+ rows.map((item, x) => {
235
+ const tileConfig: TileTemplatesConfig =
236
+ typeof item === "object"
237
+ ? { className: cn(tileClassName, item.className), scale: item.scale ?? 1, shape: item.shape }
238
+ : { className: tileClassName, scale: 1, shape: item };
239
+
240
+ return TileTemplates[tileConfig.shape](x, y, tileSize, tileConfig);
241
+ })
242
+ )
243
+ .flat();
@@ -1,51 +1,84 @@
1
- import { useMemo } from "react";
2
- import { TileShape, type IconGeneratorProps } from "./types";
3
- import { generateTiles } from "./generate-tiles";
4
- import { cn } from "@/lib/utils";
5
-
6
- const defaultIconPattern: TileShape[][] = [
7
- [TileShape.PieRand, TileShape.PieRand],
8
- [TileShape.PieRand, TileShape.PieRand],
9
- ];
10
-
11
- function IconGenerator({
12
- pattern = defaultIconPattern,
13
- tileSize = 64,
14
- tileClassName,
15
- tileBgClassName,
16
- renderChildren,
17
- ...props
18
- }: IconGeneratorProps) {
19
- const patternSize = useMemo(
20
- () => ({
21
- width: pattern.reduce((longestRow, row) => Math.max(longestRow, row.length), 0) * tileSize,
22
- height: pattern.length * tileSize,
23
- }),
24
- [pattern, tileSize]
25
- );
26
-
27
- const paths = useMemo(() => {
28
- const tiles = generateTiles(pattern, tileSize, tileClassName);
29
- if (tileBgClassName)
30
- tiles.unshift(
31
- <rect
32
- key="svg-mask-invert"
33
- x={0}
34
- y={0}
35
- width={patternSize.width}
36
- height={patternSize.height}
37
- className={cn("fill-black stroke-2 stroke-black", tileBgClassName)}
38
- />
39
- );
40
-
41
- return tiles;
42
- }, [pattern, patternSize, tileClassName, tileBgClassName, tileSize]);
43
-
44
- return (
45
- <svg width={patternSize.width} height={patternSize.height} viewBox={`0 0 ${patternSize.width} ${patternSize.height}`} overflow="visible" {...props}>
46
- {renderChildren ? renderChildren(paths, patternSize.width, patternSize.height) : paths}
47
- </svg>
48
- );
49
- }
50
-
51
- export { IconGenerator };
1
+ import { useMemo } from "react";
2
+ import { TileShape, type IconGeneratorProps } from "./types";
3
+ import { generateTiles } from "./generate-tiles";
4
+ import { cn } from "@/lib/utils";
5
+
6
+ const defaultIconPattern: TileShape[][] = [
7
+ [TileShape.PieRand, TileShape.PieRand],
8
+ [TileShape.PieRand, TileShape.PieRand],
9
+ ];
10
+
11
+ function IconGenerator({
12
+ pattern = defaultIconPattern,
13
+ tileSize = 64,
14
+ tileClassName,
15
+ tileBgClassName,
16
+ renderChildren,
17
+ fit = "none",
18
+ ...props
19
+ }: IconGeneratorProps) {
20
+ const patternSize = useMemo(
21
+ () => ({
22
+ width: pattern.reduce((longestRow, row) => Math.max(longestRow, row.length), 0) * tileSize,
23
+ height: pattern.length * tileSize,
24
+ }),
25
+ [pattern, tileSize]
26
+ );
27
+
28
+ const paths = useMemo(() => {
29
+ const tiles = generateTiles(pattern, tileSize, tileClassName);
30
+ if (tileBgClassName)
31
+ tiles.unshift(
32
+ <rect
33
+ key="svg-mask-invert"
34
+ x={0}
35
+ y={0}
36
+ width={patternSize.width}
37
+ height={patternSize.height}
38
+ className={cn("fill-black stroke-2 stroke-black", tileBgClassName)}
39
+ />
40
+ );
41
+
42
+ return tiles;
43
+ }, [pattern, patternSize, tileClassName, tileBgClassName, tileSize]);
44
+
45
+ const width = useMemo(() => {
46
+ switch (fit) {
47
+ case "fill":
48
+ return patternSize.width <= patternSize.height ? "100%" : undefined;
49
+ case "width":
50
+ return "100%";
51
+ case "none":
52
+ return patternSize.width;
53
+ default:
54
+ return undefined;
55
+ }
56
+ }, [fit, patternSize]);
57
+
58
+ const height = useMemo(() => {
59
+ switch (fit) {
60
+ case "fill":
61
+ return patternSize.height < patternSize.width ? "100%" : undefined;
62
+ case "height":
63
+ return "100%";
64
+ case "none":
65
+ return patternSize.height;
66
+ default:
67
+ return undefined;
68
+ }
69
+ }, [fit, patternSize]);
70
+
71
+ return (
72
+ <svg
73
+ width={width}
74
+ height={height}
75
+ viewBox={`0 0 ${patternSize.width} ${patternSize.height}`}
76
+ overflow="visible"
77
+ {...props}
78
+ >
79
+ {renderChildren ? renderChildren(paths, patternSize.width, patternSize.height) : paths}
80
+ </svg>
81
+ );
82
+ }
83
+
84
+ export { IconGenerator };