@synerise/ds-utils 1.5.1 → 1.5.2

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.5.2](https://github.com/synerise/synerise-design/compare/@synerise/ds-utils@1.5.1...@synerise/ds-utils@1.5.2) (2026-01-07)
7
+
8
+ **Note:** Version bump only for package @synerise/ds-utils
9
+
6
10
  ## [1.5.1](https://github.com/synerise/synerise-design/compare/@synerise/ds-utils@1.5.0...@synerise/ds-utils@1.5.1) (2025-12-15)
7
11
 
8
12
  **Note:** Version bump only for package @synerise/ds-utils
package/dist/index.d.ts CHANGED
@@ -23,5 +23,6 @@ export * from './omitKeys/omitKeys';
23
23
  export * from './useTraceUpdate';
24
24
  export * from './getPopupContainer';
25
25
  export * from './useLatestRef';
26
+ export * from './useDelimiterEscape/useDelimiterEscape';
26
27
  export declare const NOOP: () => void;
27
28
  export type { DataAttributes, ExactlyOne, LiteralStringUnion, WithHTMLAttributes, DeepPartial, RequiredProps, ObjectStringKeys, } from './types/types';
package/dist/index.js CHANGED
@@ -23,4 +23,5 @@ export * from './omitKeys/omitKeys';
23
23
  export * from './useTraceUpdate';
24
24
  export * from './getPopupContainer';
25
25
  export * from './useLatestRef';
26
+ export * from './useDelimiterEscape/useDelimiterEscape';
26
27
  export var NOOP = function NOOP() {};
@@ -0,0 +1,6 @@
1
+ export declare const validTestCases: string[];
2
+ export declare const invalidTestCases: string[];
3
+ export declare const splitWithCommaEscapeTestCases: {
4
+ input: string;
5
+ expected: string[];
6
+ }[];
@@ -0,0 +1,11 @@
1
+ export interface DelimiterEscapeConfig {
2
+ delimiter?: string;
3
+ openTag?: string;
4
+ closeTag?: string;
5
+ }
6
+ export interface DelimiterEscapeUtils {
7
+ joinWithEscape: (items: string[]) => string;
8
+ splitWithEscape: (input: string) => string[];
9
+ isValidEscapedString: (input: string) => boolean;
10
+ }
11
+ export declare const useDelimiterEscape: (config?: DelimiterEscapeConfig) => DelimiterEscapeUtils;
@@ -0,0 +1,136 @@
1
+ import { useMemo } from 'react';
2
+ export var useDelimiterEscape = function useDelimiterEscape(config) {
3
+ if (config === void 0) {
4
+ config = {};
5
+ }
6
+ var _config = config,
7
+ _config$delimiter = _config.delimiter,
8
+ delimiter = _config$delimiter === void 0 ? ',' : _config$delimiter,
9
+ _config$openTag = _config.openTag,
10
+ openTag = _config$openTag === void 0 ? '```' : _config$openTag,
11
+ _config$closeTag = _config.closeTag,
12
+ closeTag = _config$closeTag === void 0 ? '```' : _config$closeTag;
13
+ return useMemo(function () {
14
+ var joinWithEscape = function joinWithEscape(items) {
15
+ return items.map(function (item) {
16
+ return item.includes(delimiter) ? "" + openTag + item + closeTag : item;
17
+ }).join(delimiter);
18
+ };
19
+ var splitWithEscape = function splitWithEscape(input) {
20
+ var result = [];
21
+ var i = 0;
22
+ var openTagLen = openTag.length;
23
+ var closeTagLen = closeTag.length;
24
+ while (i < input.length) {
25
+ var current = '';
26
+
27
+ // Check if we're at the start of a potential opening sequence
28
+ if (input.substring(i, i + openTagLen) === openTag) {
29
+ var validOpening = i === 0 || input[i - 1] === delimiter;
30
+ if (validOpening) {
31
+ // This is a valid opening - consume the opening tag
32
+ i += openTagLen;
33
+ current = '';
34
+
35
+ // Find the closing tag (must be followed by delimiter or at end)
36
+ while (i < input.length) {
37
+ if (input.substring(i, i + closeTagLen) === closeTag) {
38
+ // Check if this is a valid closing
39
+ var validClosing = i + closeTagLen === input.length || input[i + closeTagLen] === delimiter;
40
+ if (validClosing) {
41
+ // Found closing tag
42
+ i += closeTagLen;
43
+ break;
44
+ } else {
45
+ // Not a valid closing - treat as content
46
+ current += input[i];
47
+ i++;
48
+ }
49
+ } else {
50
+ current += input[i];
51
+ i++;
52
+ }
53
+ }
54
+ // Push the item without the wrapper tags
55
+ result.push(current);
56
+ } else {
57
+ // Not a valid opening - treat as regular item
58
+ while (i < input.length && input[i] !== delimiter) {
59
+ current += input[i];
60
+ i++;
61
+ }
62
+ if (current) {
63
+ result.push(current);
64
+ }
65
+ }
66
+ } else {
67
+ // Regular item - consume until delimiter
68
+ while (i < input.length && input[i] !== delimiter) {
69
+ current += input[i];
70
+ i++;
71
+ }
72
+ if (current) {
73
+ result.push(current);
74
+ }
75
+ }
76
+
77
+ // Skip the delimiter
78
+ if (i < input.length && input[i] === delimiter) {
79
+ i++;
80
+ }
81
+ }
82
+ return result;
83
+ };
84
+ var isValidEscapedString = function isValidEscapedString(input) {
85
+ var inEscapeBlock = false;
86
+ var i = 0;
87
+ var openTagLen = openTag.length;
88
+ var closeTagLen = closeTag.length;
89
+ var delimiterLen = delimiter.length;
90
+ while (i < input.length) {
91
+ if (!inEscapeBlock) {
92
+ // Not in escape block - look for opening tag
93
+ if (input.substring(i, i + openTagLen) === openTag) {
94
+ // Check if this is a valid opening position
95
+ var validOpening = i === 0 || input.substring(i - delimiterLen, i) === delimiter;
96
+ if (validOpening) {
97
+ // Valid opening position - enter escape block
98
+ inEscapeBlock = true;
99
+ i += openTagLen;
100
+ } else {
101
+ // Not a valid opening position - treat as regular content
102
+ i++;
103
+ }
104
+ } else {
105
+ i++;
106
+ }
107
+ } else {
108
+ // In escape block - look for closing tag
109
+ if (input.substring(i, i + closeTagLen) === closeTag) {
110
+ // Check if this is a valid closing
111
+ // Valid closing: at end of string or followed by delimiter
112
+ var validClosing = i + closeTagLen === input.length || input.substring(i + closeTagLen, i + closeTagLen + delimiterLen) === delimiter;
113
+ if (validClosing) {
114
+ // This is a closing tag
115
+ inEscapeBlock = false;
116
+ i += closeTagLen;
117
+ } else {
118
+ // Not a valid closing - treat as regular content
119
+ i++;
120
+ }
121
+ } else {
122
+ i++;
123
+ }
124
+ }
125
+ }
126
+
127
+ // Invalid if we're still inside an escape block (unclosed opening tag)
128
+ return !inEscapeBlock;
129
+ };
130
+ return {
131
+ joinWithEscape: joinWithEscape,
132
+ splitWithEscape: splitWithEscape,
133
+ isValidEscapedString: isValidEscapedString
134
+ };
135
+ }, [delimiter, openTag, closeTag]);
136
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synerise/ds-utils",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "Utils UI Component for the Synerise Design System",
5
5
  "license": "ISC",
6
6
  "repository": "synerise/synerise-design",
@@ -41,5 +41,5 @@
41
41
  "react": ">=16.9.0 <= 18.3.1",
42
42
  "styled-components": "^5.3.3"
43
43
  },
44
- "gitHead": "b1279d5354132a2bf0b6f0cfa343db4c6c928f72"
44
+ "gitHead": "f38e4b2dca1d43c39af0b189c93808de62c11e9b"
45
45
  }