@fw-components/formula-editor 2.0.7-formula-editor.35 → 2.0.7-formula-editor.36

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.
@@ -21,13 +21,13 @@ let FormulaEditor = class FormulaEditor extends LitElement {
21
21
  */
22
22
  this.content = "";
23
23
  this.placeholder = "Type your formula...";
24
+ this.recommendationLabels = new Map();
24
25
  this.variables = new Map();
25
26
  this.minSuggestionLen = 2;
26
27
  this.errorString = "";
27
28
  this.formulaRegex = /'[^']*'|[A-Za-z0-9_#@]+|[-+(),*^/\s]/g;
28
- }
29
- firstUpdated(_changedProperties) {
30
- this.editor.focus();
29
+ this.allowedNumbers = true;
30
+ this.allowedOperators = new Set(["^", "+", "-", "*", "/"]);
31
31
  }
32
32
  updated(_changedProperties) {
33
33
  if (_changedProperties.has("content")) {
@@ -37,7 +37,7 @@ let FormulaEditor = class FormulaEditor extends LitElement {
37
37
  this._adjustTextAreaHeight();
38
38
  }
39
39
  if (_changedProperties.has("variables")) {
40
- this._parser = new Parser(this.variables, this.formulaRegex, this.minSuggestionLen);
40
+ this._parser = new Parser(this.variables, this.formulaRegex, this.allowedNumbers, this.allowedOperators, this.minSuggestionLen);
41
41
  this.recommendations = Array.from(this.variables.keys());
42
42
  }
43
43
  }
@@ -151,6 +151,7 @@ let FormulaEditor = class FormulaEditor extends LitElement {
151
151
  .recommendations=${this.recommendations}
152
152
  .currentSelection=${this._selectedRecommendation}
153
153
  .onRecommendationClick=${this.onRecommendationClick.bind(this)}
154
+ .recommendationLabels=${this.recommendationLabels}
154
155
  ></suggestion-menu>`
155
156
  : ''}
156
157
  `;
@@ -177,6 +178,9 @@ __decorate([
177
178
  __decorate([
178
179
  property()
179
180
  ], FormulaEditor.prototype, "placeholder", void 0);
181
+ __decorate([
182
+ property()
183
+ ], FormulaEditor.prototype, "recommendationLabels", void 0);
180
184
  __decorate([
181
185
  property()
182
186
  ], FormulaEditor.prototype, "label", void 0);
@@ -192,6 +196,12 @@ __decorate([
192
196
  __decorate([
193
197
  property()
194
198
  ], FormulaEditor.prototype, "formulaRegex", void 0);
199
+ __decorate([
200
+ property()
201
+ ], FormulaEditor.prototype, "allowedNumbers", void 0);
202
+ __decorate([
203
+ property()
204
+ ], FormulaEditor.prototype, "allowedOperators", void 0);
195
205
  __decorate([
196
206
  query("#wysiwyg-editor")
197
207
  ], FormulaEditor.prototype, "editor", void 0);
@@ -11,6 +11,7 @@ let SuggestionMenu = class SuggestionMenu extends LitElement {
11
11
  constructor() {
12
12
  super(...arguments);
13
13
  this.recommendations = [];
14
+ this.recommendationLabels = new Map();
14
15
  this.onRecommendationClick = () => { };
15
16
  this._selectedRecommendationIndex = -1;
16
17
  }
@@ -49,7 +50,7 @@ let SuggestionMenu = class SuggestionMenu extends LitElement {
49
50
  ${this.recommendations.map((recommendation, index) => html `<li
50
51
  class="${this._selectedRecommendationIndex === index ? "selected" : ""}"
51
52
  @click=${(e) => this.handleRecommendationSelect(index)}
52
- >${recommendation}</li>`)}
53
+ >${this.recommendationLabels.get(recommendation) ?? recommendation}</li>`)}
53
54
  </ul>
54
55
  `;
55
56
  }
@@ -57,6 +58,9 @@ let SuggestionMenu = class SuggestionMenu extends LitElement {
57
58
  __decorate([
58
59
  property()
59
60
  ], SuggestionMenu.prototype, "recommendations", void 0);
61
+ __decorate([
62
+ property()
63
+ ], SuggestionMenu.prototype, "recommendationLabels", void 0);
60
64
  __decorate([
61
65
  property()
62
66
  ], SuggestionMenu.prototype, "onRecommendationClick", void 0);
@@ -1,5 +1,7 @@
1
1
  export function getFormulaTokens(formulaString, formulaRegex) {
2
2
  if (!formulaString?.length)
3
3
  return [];
4
+ if (!Boolean(formulaRegex))
5
+ return formulaString.split(/(\s+)/) || [];
4
6
  return formulaString.match(formulaRegex) || [];
5
7
  }
@@ -3,13 +3,20 @@ import { Recommender } from "./recommendor.js";
3
3
  import { Stack } from "./stack.js";
4
4
  import { Queue } from "./queue.js";
5
5
  import { Expectation } from "../types";
6
- import { mathematicalOperators, operatorPrecedence, unaryOperators } from "./constants.js";
6
+ import { operatorPrecedence, unaryOperators } from "./constants.js";
7
7
  import { getFormulaTokens } from "./get-formula-tokens.js";
8
8
  export class Parser {
9
- constructor(variables, formulaRegex, minSuggestionLen) {
9
+ constructor(variables, formulaRegex, allowedNumbers, allowedOperators, minSuggestionLen) {
10
10
  this.variables = variables;
11
11
  this.formulaRegex = formulaRegex;
12
12
  this._recommender = new Recommender(Array.from(this.variables.keys()), minSuggestionLen);
13
+ this.allowedNumbers = allowedNumbers;
14
+ this.allowedOperators = allowedOperators;
15
+ }
16
+ isNumber(value) {
17
+ if (!this.allowedNumbers || value.trim() === "")
18
+ return false;
19
+ return !Number.isNaN(Number(value));
13
20
  }
14
21
  parseInput(formula, prevCurPos = null, recommendation = null) {
15
22
  const tokens = getFormulaTokens(formula, this.formulaRegex);
@@ -30,8 +37,8 @@ export class Parser {
30
37
  return parseOutput;
31
38
  }
32
39
  tokens?.forEach((token) => {
33
- let isNumber = token.trim() !== "" && (this.variables.has(token) || !Number.isNaN(Number(token)));
34
- const isOperator = mathematicalOperators.has(token);
40
+ let isNumber = this.variables.has(token) || this.isNumber(token);
41
+ const isOperator = this.allowedOperators.has(token);
35
42
  const isSpace = token.trim() === "";
36
43
  const isBracket = token === "(" || token === ")";
37
44
  if (isSpace) {
@@ -48,7 +55,7 @@ export class Parser {
48
55
  if (currentPosition <= prevCurPos && currentPosition + token.length >= prevCurPos) {
49
56
  if (recommendation) {
50
57
  isNumber = true;
51
- if (mathematicalOperators.has(token)) {
58
+ if (this.allowedOperators.has(token)) {
52
59
  const updatedTokenString = `${token} ${recommendation}`;
53
60
  parseOutput.formattedString += updatedTokenString;
54
61
  currentPosition += updatedTokenString.length;
@@ -69,7 +76,7 @@ export class Parser {
69
76
  * skip error check if there is one already
70
77
  */
71
78
  if (expectation != Expectation.UNDEFINED) {
72
- if (mathematicalOperators.has(previousToken) && isOperator) {
79
+ if (this.allowedOperators.has(previousToken) && isOperator) {
73
80
  parseOutput.errorString = `Multiple operators at position ${currentPosition}`;
74
81
  expectation = Expectation.UNDEFINED;
75
82
  }
@@ -82,7 +89,7 @@ export class Parser {
82
89
  * No error for Unary `+` and `-` as they might represent a positive or negative number respectively
83
90
  */
84
91
  else if (expectation === Expectation.VARIABLE && !isNumber && !isSpace && token != "("
85
- && !((unaryOperators.includes(token)) && (!parsedString.trim() || previousToken === "(" || mathematicalOperators.has(previousToken)))) {
92
+ && !((unaryOperators.includes(token)) && (!parsedString.trim() || previousToken === "(" || this.allowedOperators.has(previousToken)))) {
86
93
  parseOutput.errorString = `Expected variable/number at position ${currentPosition}`;
87
94
  expectation = Expectation.UNDEFINED;
88
95
  }
@@ -140,10 +147,10 @@ export class Parser {
140
147
  parseOutput.formattedString += recommendation;
141
148
  previousToken = recommendation;
142
149
  }
143
- if (mathematicalOperators.has(previousToken) || !previousToken.trim().length) {
150
+ if (this.allowedOperators.has(previousToken) || !previousToken.trim().length) {
144
151
  parseOutput.recommendations = !parseOutput.errorString?.length ? Array.from(this.variables.keys()) : [];
145
152
  }
146
- if (mathematicalOperators.has(previousToken)) {
153
+ if (this.allowedOperators.has(previousToken)) {
147
154
  parseOutput.errorString = `Unexpected ending with mathematical operator at position: ${currentPosition}`;
148
155
  }
149
156
  if (!parentheses.isEmpty()) {
@@ -161,7 +168,7 @@ export class Parser {
161
168
  let currentTokens = "";
162
169
  // Check if variables include unary operators `-` and `+`.
163
170
  for (const token of tokens) {
164
- if ((unaryOperators.includes(token)) && (!currentTokens.trim() || previousToken === "(" || mathematicalOperators.has(previousToken))) {
171
+ if ((unaryOperators.includes(token)) && (!currentTokens.trim() || previousToken === "(" || this.allowedOperators.has(previousToken))) {
165
172
  carriedToken = token;
166
173
  }
167
174
  else if (carriedToken) {
@@ -189,8 +196,8 @@ export class Parser {
189
196
  }
190
197
  operatorStack.pop();
191
198
  }
192
- else if (mathematicalOperators.has(token)) {
193
- while (mathematicalOperators.has(operatorStack.top()) && operatorPrecedence[token] <= operatorPrecedence[operatorStack.top()]) {
199
+ else if (this.allowedOperators.has(token)) {
200
+ while (this.allowedOperators.has(operatorStack.top()) && operatorPrecedence[token] <= operatorPrecedence[operatorStack.top()]) {
194
201
  outputQueue.enqueue(operatorStack.pop());
195
202
  }
196
203
  operatorStack.push(token);
@@ -267,7 +274,7 @@ export class Parser {
267
274
  const calcStack = new Stack();
268
275
  while (!formulaRPN.isEmpty()) {
269
276
  const frontItem = formulaRPN.dequeue();
270
- if (!mathematicalOperators.has(frontItem)) {
277
+ if (!this.allowedOperators.has(frontItem)) {
271
278
  const [sign, variableKey] = /^[+-]/.test(frontItem) ? [frontItem[0], frontItem.slice(1)] : ["", frontItem];
272
279
  const operandValue = Number.parseFloat(this.variables.get(variableKey)?.toString() ?? variableKey);
273
280
  const number = Number.parseFloat(sign + "1") * operandValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fw-components/formula-editor",
3
- "version": "2.0.7-formula-editor.35",
3
+ "version": "2.0.7-formula-editor.36",
4
4
  "description": "A WYSIWYG type formula editor",
5
5
  "main": "dist/formula-editor/src/formula-editor.js",
6
6
  "exports": {
@@ -31,5 +31,5 @@
31
31
  "@types/big.js": "^6.1.6",
32
32
  "es-dev-server": "^2.1.0"
33
33
  },
34
- "gitHead": "ef64463d26814b5eb6389aa3a1f9ce12f26c46a6"
34
+ "gitHead": "78fd3b78f8f72ac4ab0b4b7ec57848b2a78cccad"
35
35
  }