@pelatform/ui 1.5.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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -0
  3. package/css/components/apexcharts.css +101 -0
  4. package/css/components/book.css +19 -0
  5. package/css/components/extra.css +12 -0
  6. package/css/components/image-input.css +51 -0
  7. package/css/components/leaflet.css +25 -0
  8. package/css/components/patterns.css +34 -0
  9. package/css/components/rating.css +89 -0
  10. package/css/components/scrollable.css +118 -0
  11. package/css/components/theme-transition.css +51 -0
  12. package/css/theme.css +237 -0
  13. package/dist/animation.cjs +1936 -0
  14. package/dist/animation.d.cts +379 -0
  15. package/dist/animation.d.ts +379 -0
  16. package/dist/animation.js +1936 -0
  17. package/dist/aria.cjs +139 -0
  18. package/dist/aria.d.cts +31 -0
  19. package/dist/aria.d.ts +31 -0
  20. package/dist/aria.js +139 -0
  21. package/dist/badge-BtI4BMea.d.cts +33 -0
  22. package/dist/badge-BtI4BMea.d.ts +33 -0
  23. package/dist/base.cjs +5559 -0
  24. package/dist/base.d.cts +651 -0
  25. package/dist/base.d.ts +651 -0
  26. package/dist/base.js +5559 -0
  27. package/dist/chunk-3N75YA6Q.cjs +60 -0
  28. package/dist/chunk-CD2BCCQU.js +180 -0
  29. package/dist/chunk-CJXIPSTG.cjs +10 -0
  30. package/dist/chunk-CYFW37N5.js +1355 -0
  31. package/dist/chunk-EZW5GNS4.js +6 -0
  32. package/dist/chunk-HW52LCWN.js +22 -0
  33. package/dist/chunk-I46SELBA.cjs +22 -0
  34. package/dist/chunk-J4JGE3U5.cjs +180 -0
  35. package/dist/chunk-KNS6QRVB.cjs +28 -0
  36. package/dist/chunk-OMPNDLGS.js +576 -0
  37. package/dist/chunk-RQHJBTEU.js +10 -0
  38. package/dist/chunk-S3QFGYE6.js +28 -0
  39. package/dist/chunk-SK6SSJHC.js +9 -0
  40. package/dist/chunk-T74DBLYY.js +60 -0
  41. package/dist/chunk-UP53DCYH.cjs +6 -0
  42. package/dist/chunk-VECBSKBC.cjs +576 -0
  43. package/dist/chunk-VSLPH2IR.cjs +1355 -0
  44. package/dist/chunk-ZDR3OZ7Z.cjs +9 -0
  45. package/dist/colors-CUDWvz1g.d.cts +42 -0
  46. package/dist/colors-CUDWvz1g.d.ts +42 -0
  47. package/dist/components-BgbIL9EW.d.cts +42 -0
  48. package/dist/components-BgbIL9EW.d.ts +42 -0
  49. package/dist/components.cjs +2276 -0
  50. package/dist/components.d.cts +2762 -0
  51. package/dist/components.d.ts +2762 -0
  52. package/dist/components.js +2276 -0
  53. package/dist/default.cjs +9081 -0
  54. package/dist/default.d.cts +1322 -0
  55. package/dist/default.d.ts +1322 -0
  56. package/dist/default.js +9081 -0
  57. package/dist/hooks.cjs +666 -0
  58. package/dist/hooks.d.cts +1176 -0
  59. package/dist/hooks.d.ts +1176 -0
  60. package/dist/hooks.js +666 -0
  61. package/dist/index.cjs +234 -0
  62. package/dist/index.d.cts +298 -0
  63. package/dist/index.d.ts +298 -0
  64. package/dist/index.js +234 -0
  65. package/dist/input-AwYIskrX.d.cts +22 -0
  66. package/dist/input-AwYIskrX.d.ts +22 -0
  67. package/dist/menu-GmSRfRGB.d.cts +43 -0
  68. package/dist/menu-GmSRfRGB.d.ts +43 -0
  69. package/dist/metafile-cjs.json +1 -0
  70. package/dist/metafile-esm.json +1 -0
  71. package/dist/re-export/cva.cjs +6 -0
  72. package/dist/re-export/cva.d.cts +9 -0
  73. package/dist/re-export/cva.d.ts +9 -0
  74. package/dist/re-export/cva.js +6 -0
  75. package/dist/re-export/motion.cjs +2 -0
  76. package/dist/re-export/motion.d.cts +1 -0
  77. package/dist/re-export/motion.d.ts +1 -0
  78. package/dist/re-export/motion.js +2 -0
  79. package/dist/re-export/next-themes.cjs +2 -0
  80. package/dist/re-export/next-themes.d.cts +1 -0
  81. package/dist/re-export/next-themes.d.ts +1 -0
  82. package/dist/re-export/next-themes.js +2 -0
  83. package/dist/re-export/react-day-picker.cjs +2 -0
  84. package/dist/re-export/react-day-picker.d.cts +1 -0
  85. package/dist/re-export/react-day-picker.d.ts +1 -0
  86. package/dist/re-export/react-day-picker.js +2 -0
  87. package/dist/re-export/react-hook-form.cjs +2 -0
  88. package/dist/re-export/react-hook-form.d.cts +1 -0
  89. package/dist/re-export/react-hook-form.d.ts +1 -0
  90. package/dist/re-export/react-hook-form.js +2 -0
  91. package/dist/re-export/sonner.cjs +2 -0
  92. package/dist/re-export/sonner.d.cts +1 -0
  93. package/dist/re-export/sonner.d.ts +1 -0
  94. package/dist/re-export/sonner.js +2 -0
  95. package/dist/re-export/tanstack-query.cjs +2 -0
  96. package/dist/re-export/tanstack-query.d.cts +1 -0
  97. package/dist/re-export/tanstack-query.d.ts +1 -0
  98. package/dist/re-export/tanstack-query.js +2 -0
  99. package/dist/re-export/tanstack-table.cjs +2 -0
  100. package/dist/re-export/tanstack-table.d.cts +1 -0
  101. package/dist/re-export/tanstack-table.d.ts +1 -0
  102. package/dist/re-export/tanstack-table.js +2 -0
  103. package/dist/re-export/zod.cjs +2 -0
  104. package/dist/re-export/zod.d.cts +1 -0
  105. package/dist/re-export/zod.d.ts +1 -0
  106. package/dist/re-export/zod.js +2 -0
  107. package/package.json +171 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,234 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunkKNS6QRVBcjs = require('./chunk-KNS6QRVB.cjs');
4
+
5
+
6
+ var _chunkCJXIPSTGcjs = require('./chunk-CJXIPSTG.cjs');
7
+
8
+
9
+
10
+
11
+ var _chunkI46SELBAcjs = require('./chunk-I46SELBA.cjs');
12
+
13
+
14
+ var _chunkUP53DCYHcjs = require('./chunk-UP53DCYH.cjs');
15
+
16
+ // src/lib/ohimg.ts
17
+ var isValidHex = (color) => {
18
+ const hexPattern = /^#[0-9A-Fa-f]{6}$/;
19
+ return hexPattern.test(color);
20
+ };
21
+ var hexToRgba = (color, opacity) => {
22
+ const defaultColor = "#000000";
23
+ let normalizedColor = _optionalChain([color, 'optionalAccess', _ => _.startsWith, 'call', _2 => _2("#")]) ? color : `#${color}`;
24
+ if (!isValidHex(normalizedColor)) {
25
+ console.warn(`Invalid hex color: ${color}, using default black`);
26
+ normalizedColor = defaultColor;
27
+ }
28
+ const r = parseInt(normalizedColor.slice(1, 3), 16);
29
+ const g = parseInt(normalizedColor.slice(3, 5), 16);
30
+ const b = parseInt(normalizedColor.slice(5, 7), 16);
31
+ const safeOpacity = Math.max(0, Math.min(1, _nullishCoalesce(opacity, () => ( 1))));
32
+ return `rgba(${r}, ${g}, ${b}, ${safeOpacity})`;
33
+ };
34
+ var getMask = ({ direction = "circle at center", visibleRadius = 30, fadeWidth = 20 }) => {
35
+ const outerRadius = visibleRadius + fadeWidth;
36
+ return {
37
+ maskImage: `radial-gradient(${direction}, black ${visibleRadius}%, transparent ${outerRadius}%)`,
38
+ WebkitMaskImage: `radial-gradient(${direction}, black ${visibleRadius}%, transparent ${outerRadius}%)`
39
+ };
40
+ };
41
+ var getDotPattern = ({
42
+ color = "#000000",
43
+ opacity = 0.5,
44
+ size = 25,
45
+ backgroundSize = 20
46
+ }) => {
47
+ const dotColor = hexToRgba(color, opacity);
48
+ return {
49
+ backgroundImage: `radial-gradient(${dotColor} ${size}%, transparent ${size + 1}%), radial-gradient(${dotColor} ${size - 0.5}%, transparent ${size + 0.5}%)`,
50
+ backgroundSize: `${backgroundSize}px ${backgroundSize}px, ${backgroundSize}px ${backgroundSize}px`,
51
+ backgroundPosition: `0 0, ${backgroundSize / 2}px ${backgroundSize / 2}px`
52
+ };
53
+ };
54
+ var getGridPattern = ({
55
+ color = "#000000",
56
+ opacity = 0.5,
57
+ size = 20,
58
+ lineThickness = 1
59
+ }) => {
60
+ const colorWithOpacity = hexToRgba(color, opacity);
61
+ return {
62
+ backgroundImage: `
63
+ linear-gradient(to right, ${colorWithOpacity} ${lineThickness}px, transparent ${lineThickness}px),
64
+ linear-gradient(to bottom, ${colorWithOpacity} ${lineThickness}px, transparent ${lineThickness}px)
65
+ `,
66
+ backgroundSize: `${size}px ${size}px`
67
+ };
68
+ };
69
+ var getPatternStyle = (props) => {
70
+ switch (props.type) {
71
+ case "dots":
72
+ return {
73
+ ...getDotPattern({
74
+ color: props.color,
75
+ opacity: props.opacity,
76
+ size: props.size,
77
+ backgroundSize: props.backgroundSize
78
+ }),
79
+ ...props.mask && props.mask.enabled === true && getMask({
80
+ direction: props.mask.direction,
81
+ visibleRadius: props.mask.visibleRadius,
82
+ fadeWidth: props.mask.fadeWidth
83
+ })
84
+ };
85
+ case "grid":
86
+ return {
87
+ ...getGridPattern({
88
+ color: props.color,
89
+ opacity: props.opacity,
90
+ size: props.size,
91
+ lineThickness: props.lineThickness
92
+ }),
93
+ ...props.mask && props.mask.enabled === true && getMask({
94
+ direction: props.mask.direction,
95
+ visibleRadius: props.mask.visibleRadius,
96
+ fadeWidth: props.mask.fadeWidth
97
+ })
98
+ };
99
+ default:
100
+ return {};
101
+ }
102
+ };
103
+ var getGradientStyle = (props) => {
104
+ if (!props.direction || props.direction === "none") {
105
+ return {};
106
+ }
107
+ const baseGradient = {
108
+ background: `linear-gradient(${props.direction || "to bottom"}, ${props.startColor || "#000000"}, ${props.endColor || "#000000"})`,
109
+ opacity: _nullishCoalesce(props.opacity, () => ( 0.7))
110
+ };
111
+ return {
112
+ ...baseGradient,
113
+ ...props.mask && props.mask.enabled === true && getMask({
114
+ direction: props.mask.direction,
115
+ visibleRadius: props.mask.visibleRadius,
116
+ fadeWidth: props.mask.fadeWidth
117
+ })
118
+ };
119
+ };
120
+ function calculateMaxWidth(paddingX) {
121
+ const baseWidth = 1200;
122
+ if (!paddingX) {
123
+ return baseWidth;
124
+ }
125
+ const paddingValue = parseInt(paddingX.replace("px", ""), 10);
126
+ if (Number.isNaN(paddingValue)) {
127
+ return baseWidth;
128
+ }
129
+ const adjustedWidth = baseWidth - 2 * paddingValue;
130
+ const finalWidth = Math.min(adjustedWidth, baseWidth);
131
+ return finalWidth;
132
+ }
133
+ function getPositionClasses(element, maxWidth) {
134
+ return _chunkCJXIPSTGcjs.cn.call(void 0, element.customClasses && element.customClasses, `max-w-[${maxWidth}px]`);
135
+ }
136
+
137
+ // src/utils/flag-url.ts
138
+ function getFlagUrl(flag) {
139
+ const baseUrl = "https://assets.pelatform.com/media/flags";
140
+ const flagCode = flag.toLowerCase();
141
+ return `${baseUrl}/${flagCode}.svg`;
142
+ }
143
+
144
+ // src/utils/ip.ts
145
+ async function getIPAddress() {
146
+ if (typeof window === "undefined") {
147
+ return "unknown";
148
+ }
149
+ try {
150
+ const services = [
151
+ "https://api.ipify.org?format=json",
152
+ "https://ipapi.co/json/",
153
+ "https://api.ip.sb/jsonip"
154
+ ];
155
+ for (const service of services) {
156
+ try {
157
+ const response = await fetch(service, {
158
+ method: "GET",
159
+ headers: {
160
+ Accept: "application/json"
161
+ }
162
+ });
163
+ if (response.ok) {
164
+ const data = await response.json();
165
+ const ip = data.ip || data.query || data.ipAddress;
166
+ if (ip && typeof ip === "string") {
167
+ return ip;
168
+ }
169
+ }
170
+ } catch (serviceError) {
171
+ console.warn(`IP service ${service} failed:`, serviceError);
172
+ }
173
+ }
174
+ return "unknown";
175
+ } catch (error) {
176
+ console.error("Failed to get client IP:", error);
177
+ return "unknown";
178
+ }
179
+ }
180
+
181
+ // src/utils/parse.ts
182
+ function normalizePath(input) {
183
+ if (!input) return "/";
184
+ let p = input.trim();
185
+ if (!p.startsWith("/")) p = `/${p}`;
186
+ p = p.replace(/\/{2,}/g, "/");
187
+ if (p.length > 1 && p.endsWith("/")) p = p.slice(0, -1);
188
+ return p;
189
+ }
190
+ var parse = (
191
+ // biome-ignore lint/suspicious/noExplicitAny: disable
192
+ (req) => {
193
+ let domain = req.headers.get("host");
194
+ domain = domain.replace(/^www\./, "").toLowerCase();
195
+ const path = req.nextUrl.pathname;
196
+ const searchParams = req.nextUrl.searchParams.toString();
197
+ const searchParamsObj = Object.fromEntries(req.nextUrl.searchParams);
198
+ const searchParamsString = searchParams.length > 0 ? `?${searchParams}` : "";
199
+ const fullPath = `${path}${searchParamsString}`;
200
+ const pathSegments = path.split("/").filter(Boolean);
201
+ const key = pathSegments.length > 0 ? decodeURIComponent(pathSegments[0]) : "";
202
+ const fullKey = path.length > 1 ? decodeURIComponent(path.slice(1)) : "";
203
+ return {
204
+ domain,
205
+ path,
206
+ fullPath,
207
+ key,
208
+ fullKey,
209
+ searchParamsObj,
210
+ searchParamsString
211
+ };
212
+ }
213
+ );
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+ exports.DEFAULT_THEME_MODE = _chunkI46SELBAcjs.DEFAULT_THEME_MODE; exports.META_THEME_COLORS = _chunkI46SELBAcjs.META_THEME_COLORS; exports.THEME_MODES = _chunkI46SELBAcjs.THEME_MODES; exports.calculateMaxWidth = calculateMaxWidth; exports.cn = _chunkCJXIPSTGcjs.cn; exports.cva = _chunkUP53DCYHcjs.cva; exports.getDotPattern = getDotPattern; exports.getFlagUrl = getFlagUrl; exports.getGradientStyle = getGradientStyle; exports.getGridPattern = getGridPattern; exports.getIPAddress = getIPAddress; exports.getMask = getMask; exports.getPatternStyle = getPatternStyle; exports.getPositionClasses = getPositionClasses; exports.googleTrackEvent = _chunkKNS6QRVBcjs.googleTrackEvent; exports.hexToRgba = hexToRgba; exports.isValidHex = isValidHex; exports.normalizePath = normalizePath; exports.parse = parse;
@@ -0,0 +1,298 @@
1
+ export { D as DEFAULT_THEME_MODE, M as META_THEME_COLORS, T as THEME_MODES, a as ThemeMode } from './colors-CUDWvz1g.cjs';
2
+ import { ClassValue } from 'clsx';
3
+ export { cva } from 'class-variance-authority';
4
+ export { B as BaseProps, I as Image, L as Link } from './components-BgbIL9EW.cjs';
5
+ export { a as MenuConfig, M as MenuItem } from './menu-GmSRfRGB.cjs';
6
+ import 'react';
7
+
8
+ /**
9
+ * Interface for event tracking parameters
10
+ * Defines the structure for tracking events in Google Analytics
11
+ */
12
+ interface EventProps {
13
+ /** Event name to be tracked (required, non-empty string) */
14
+ name: string;
15
+ /** Optional properties/attributes for the event */
16
+ properties?: Record<string, string | number | boolean>;
17
+ }
18
+ /**
19
+ * Global declaration for Google Analytics gtag function
20
+ * This extends the Window interface to include the gtag function
21
+ * that's injected by the Google Analytics script
22
+ */
23
+ declare global {
24
+ interface Window {
25
+ gtag?: (command: 'event' | 'config' | 'set', targetId: string, config?: Record<string, string | number | boolean | object | null | undefined>) => void;
26
+ }
27
+ }
28
+ /**
29
+ * Tracks an event in Google Analytics with proper error handling and validation.
30
+ *
31
+ * @param params - Event parameters
32
+ * @param params.name - Event name (required, non-empty string)
33
+ * @param params.properties - Optional event properties
34
+ */
35
+ declare const googleTrackEvent: ({ name, properties }: EventProps) => void;
36
+
37
+ type PatternType = 'none' | 'grid' | 'dots';
38
+ type GradientDirection = 'none' | 'to right' | 'to left' | 'to bottom' | 'to top' | 'to bottom right' | 'to bottom left' | 'to top right' | 'to top left';
39
+ type MaskDirection = 'none' | 'circle at center' | 'circle at center top' | 'circle at top right' | 'circle at center right' | 'circle at bottom right' | 'circle at center bottom' | 'circle at bottom left' | 'circle at center left' | 'circle at top left';
40
+ type PositionOption = 'start' | 'center' | 'end';
41
+ type AlignmentOption = 'left' | 'center' | 'right';
42
+ interface BackgroundImageLayer {
43
+ imageSrc?: string;
44
+ }
45
+ interface MaskLayer {
46
+ enabled?: boolean;
47
+ direction?: MaskDirection;
48
+ visibleRadius?: number;
49
+ fadeWidth?: number;
50
+ }
51
+ interface PatternLayer {
52
+ type?: PatternType;
53
+ color?: string;
54
+ opacity?: number;
55
+ size?: number;
56
+ backgroundSize?: number;
57
+ lineThickness?: number;
58
+ mask?: MaskLayer;
59
+ }
60
+ interface GradientLayer {
61
+ startColor?: string;
62
+ endColor?: string;
63
+ opacity?: number;
64
+ direction?: GradientDirection;
65
+ mask?: MaskLayer;
66
+ }
67
+ interface PositionedElement {
68
+ customClasses?: string;
69
+ textColor?: string;
70
+ bgColor?: string;
71
+ fontSize?: string;
72
+ fontWeight?: string;
73
+ width?: string;
74
+ height?: string;
75
+ hPosition?: PositionOption;
76
+ vPosition?: PositionOption;
77
+ alignment?: AlignmentOption;
78
+ autoMargin?: boolean;
79
+ }
80
+ interface ContentLayout {
81
+ layoutContainer?: string;
82
+ logoContainer?: string;
83
+ logo?: string;
84
+ tagContainer?: string;
85
+ contentContainer?: string;
86
+ tag?: string;
87
+ title?: string;
88
+ description?: string;
89
+ website?: string;
90
+ }
91
+ interface OhImgBaseTemplateProps {
92
+ content: {
93
+ title: string;
94
+ description?: string;
95
+ tags?: string[];
96
+ website?: string;
97
+ logoSrc?: string;
98
+ };
99
+ background?: BackgroundImageLayer;
100
+ pattern?: PatternLayer;
101
+ gradient?: GradientLayer;
102
+ layout?: ContentLayout;
103
+ }
104
+
105
+ /**
106
+ * Converts hex color to rgba format with specified opacity
107
+ */
108
+ declare const isValidHex: (color: string) => boolean;
109
+ declare const hexToRgba: (color: string, opacity: number) => string;
110
+ declare const getMask: ({ direction, visibleRadius, fadeWidth }: {
111
+ direction?: string | undefined;
112
+ visibleRadius?: number | undefined;
113
+ fadeWidth?: number | undefined;
114
+ }) => {
115
+ maskImage: string;
116
+ WebkitMaskImage: string;
117
+ };
118
+ declare const getDotPattern: ({ color, opacity, size, backgroundSize, }: {
119
+ color?: string | undefined;
120
+ opacity?: number | undefined;
121
+ size?: number | undefined;
122
+ backgroundSize?: number | undefined;
123
+ }) => {
124
+ backgroundImage: string;
125
+ backgroundSize: string;
126
+ backgroundPosition: string;
127
+ };
128
+ declare const getGridPattern: ({ color, opacity, size, lineThickness, }: {
129
+ color?: string;
130
+ opacity?: number;
131
+ size?: number;
132
+ lineThickness?: number;
133
+ }) => {
134
+ backgroundImage: string;
135
+ backgroundSize: string;
136
+ };
137
+ declare const getPatternStyle: (props: PatternLayer) => {};
138
+ declare const getGradientStyle: (props: GradientLayer) => {};
139
+ declare function calculateMaxWidth(paddingX: string | undefined): number;
140
+ declare function getPositionClasses(element: PositionedElement, maxWidth: number): string;
141
+
142
+ /**
143
+ * Utility functions for CSS class name management
144
+ * Provides optimized class name merging with Tailwind CSS conflict resolution
145
+ * Essential for component styling and conditional class application
146
+ */
147
+
148
+ /**
149
+ * Merges Tailwind class names, resolving any conflicts.
150
+ * This utility combines clsx for conditional classes with tailwind-merge
151
+ * to properly handle Tailwind CSS class conflicts.
152
+ *
153
+ * @param inputs - An array of class names, objects, or arrays to merge
154
+ * @returns A string of merged and optimized class names
155
+ */
156
+ declare function cn(...inputs: ClassValue[]): string;
157
+
158
+ /**
159
+ * Build a CDN URL for a country flag SVG.
160
+ *
161
+ * The function lowercases the given ISO country code and returns a
162
+ * fully-qualified URL pointing to the SVG flag hosted on the Pelatform
163
+ * assets CDN.
164
+ *
165
+ * @param flag - ISO 3166-1 alpha-2 country code (e.g., "US", "ID", "GB")
166
+ * @returns A URL string to the SVG flag on the CDN
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * import { getFlagUrl } from "@pelatform/ui/utils/flag-url";
171
+ *
172
+ * const urlUs = getFlagUrl("US");
173
+ * // "https://assets.pelatform.com/media/flags/us.svg"
174
+ *
175
+ * const urlId = getFlagUrl("id");
176
+ * // "https://assets.pelatform.com/media/flags/id.svg"
177
+ *
178
+ * // Can be used directly in an <img /> or <Image /> component
179
+ * // <img src={getFlagUrl("GB")} alt="United Kingdom flag" />
180
+ * ```
181
+ */
182
+ declare function getFlagUrl(flag: string): string;
183
+
184
+ /**
185
+ * Get the client's public IP address using external services.
186
+ *
187
+ * This utility is intended for client-side usage only (it checks for `window`).
188
+ * It attempts multiple providers for resiliency and normalizes the response
189
+ * to a simple string. If all providers fail or the environment is not a
190
+ * browser, it resolves to `'unknown'`.
191
+ *
192
+ * Providers queried (in order):
193
+ * - `https://api.ipify.org?format=json`
194
+ * - `https://ipapi.co/json/`
195
+ * - `https://api.ip.sb/jsonip`
196
+ *
197
+ * @returns Promise that resolves to an IP address string or `'unknown'` if not available
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * import { getIPAddress } from "@pelatform/ui/utils/ip";
202
+ *
203
+ * const ip = await getIPAddress();
204
+ * // e.g., "203.0.113.42" or "unknown"
205
+ *
206
+ * // Example in a React component
207
+ * // useEffect(() => {
208
+ * // getIPAddress().then(setIp);
209
+ * // }, []);
210
+ * ```
211
+ */
212
+ declare function getIPAddress(): Promise<string>;
213
+
214
+ /**
215
+ * Normalize a pathname string.
216
+ *
217
+ * - Ensures it always starts with '/'
218
+ * - Collapses multiple slashes (e.g., `'//a///b'` becomes `'/a/b'`)
219
+ * - Removes trailing slash except for root path (e.g., `'/login/'` becomes `'/login'`)
220
+ *
221
+ * @param input - Any path-like string
222
+ * @returns A normalized path beginning with '/'
223
+ *
224
+ * @example
225
+ * ```ts
226
+ * import { normalizePath } from "@pelatform/ui/utils/parse";
227
+ *
228
+ * normalizePath("dashboard"); // "/dashboard"
229
+ * normalizePath("//a///b"); // "/a/b"
230
+ * normalizePath("/login/"); // "/login"
231
+ * normalizePath(""); // "/"
232
+ * ```
233
+ */
234
+ declare function normalizePath(input: string): string;
235
+ /**
236
+ * Interface for parsed request data
237
+ */
238
+ interface ParsedRequest {
239
+ /** Normalized domain name (lowercase, without www) */
240
+ domain: string;
241
+ /** URL pathname (e.g., '/dashboard/users') */
242
+ path: string;
243
+ /** Full path including query parameters (e.g., '/dashboard/users?page=1') */
244
+ fullPath: string;
245
+ /** First path segment (e.g., 'dashboard' from '/dashboard/users') */
246
+ key: string;
247
+ /** Full path without leading slash (e.g., 'dashboard/users') */
248
+ fullKey: string;
249
+ /** Query parameters as object */
250
+ searchParamsObj: Record<string, string>;
251
+ /** Query parameters as string (e.g., '?page=1&limit=10') */
252
+ searchParamsString: string;
253
+ }
254
+ /**
255
+ * Parse and normalize a Next.js `NextRequest`.
256
+ *
257
+ * Extracts domain, normalized path, first segment key, full path, and
258
+ * query parameters (both as object and as string). Handles international
259
+ * characters via `decodeURIComponent` and normalizes the host by removing
260
+ * a leading `www.`.
261
+ *
262
+ * @param req - The incoming Next.js `NextRequest`
263
+ * @returns Parsed request data with normalized components
264
+ *
265
+ * @example
266
+ * ```ts
267
+ * import type { NextRequest } from "next/server";
268
+ * import { parse } from "@pelatform/ui/utils/parse";
269
+ *
270
+ * export function middleware(req: NextRequest) {
271
+ * const { domain, path, fullPath, key } = parse(req);
272
+ *
273
+ * console.log(domain); // e.g., "api.pelatform.com"
274
+ * console.log(path); // e.g., "/v1/users"
275
+ * console.log(fullPath); // e.g., "/v1/users?page=1"
276
+ * console.log(key); // e.g., "v1"
277
+ * }
278
+ * ```
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * // Handling international URLs
283
+ * const { key, fullKey } = parse(req);
284
+ * console.log(key); // Decoded first path segment
285
+ * console.log(fullKey); // Decoded full path
286
+ * ```
287
+ *
288
+ * @example
289
+ * ```ts
290
+ * // Working with query parameters
291
+ * const { searchParamsObj, searchParamsString } = parse(req);
292
+ * // searchParamsObj -> { page: "1", limit: "10" }
293
+ * // searchParamsString -> "?page=1&limit=10"
294
+ * ```
295
+ */
296
+ declare const parse: (req: any) => ParsedRequest;
297
+
298
+ export { type AlignmentOption, type BackgroundImageLayer, type ContentLayout, type GradientDirection, type GradientLayer, type MaskDirection, type MaskLayer, type OhImgBaseTemplateProps, type ParsedRequest, type PatternLayer, type PatternType, type PositionOption, type PositionedElement, calculateMaxWidth, cn, getDotPattern, getFlagUrl, getGradientStyle, getGridPattern, getIPAddress, getMask, getPatternStyle, getPositionClasses, googleTrackEvent, hexToRgba, isValidHex, normalizePath, parse };