@samline/forms 2.7.0 → 2.7.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/README.md CHANGED
@@ -42,10 +42,10 @@ Requires Node 20+ when bundling. Runtime target is ES2020.
42
42
  Use the browser build when you do not have a bundler and need to run the package directly in HTML, Shopify, WordPress, or any traditional template.
43
43
 
44
44
  ```html
45
- <script src="https://unpkg.com/@samline/forms@2.7.0/dist/browser/global.global.js"></script>
45
+ <script src="https://unpkg.com/@samline/forms@2.7.2/dist/browser/global.global.js"></script>
46
46
  ```
47
47
 
48
- > Pin the version in production. Replace `2.7.0` with the version you ship.
48
+ > Pin the version in production. Replace `2.7.2` with the version you ship.
49
49
 
50
50
  The browser bundle exposes a single global: `window.Forms`.
51
51
 
@@ -55,7 +55,7 @@ The browser bundle exposes a single global: `window.Forms`.
55
55
  <button type="submit">Send</button>
56
56
  </form>
57
57
 
58
- <script src="https://unpkg.com/@samline/forms@2.7.0/dist/browser/global.global.js"></script>
58
+ <script src="https://unpkg.com/@samline/forms@2.7.2/dist/browser/global.global.js"></script>
59
59
  <script>
60
60
  const contactForm = window.Forms.newForm({ id: 'contact-form' })
61
61
 
@@ -4168,6 +4168,12 @@ var Forms = (() => {
4168
4168
  if (lowercase) chars += "a-z";
4169
4169
  if (numbers) chars += "0-9";
4170
4170
  if (special) chars += `!@#$%^&*()_+\\-=\\[\\]{}|;:'",.<>?/`;
4171
+ const requirements = [
4172
+ uppercase ? "(?=.*[A-Z])" : "",
4173
+ lowercase ? "(?=.*[a-z])" : "",
4174
+ numbers ? "(?=.*[0-9])" : "",
4175
+ special ? `(?=.*[!@#$%^&*()_+\\-=\\[\\]{}|;:'",.<>?/])` : ""
4176
+ ].join("");
4171
4177
  const ruleParts = [];
4172
4178
  if (uppercase) ruleParts.push("uppercase letter");
4173
4179
  if (lowercase) ruleParts.push("lowercase letter");
@@ -4175,7 +4181,7 @@ var Forms = (() => {
4175
4181
  if (special) ruleParts.push("special character");
4176
4182
  const rulesText = ruleParts.length > 2 ? ruleParts.slice(0, -1).join(", ") + " and " + ruleParts.slice(-1) : ruleParts.join(" and ");
4177
4183
  return {
4178
- pattern: new RegExp(`^[${chars}]{${min},${max}}$`),
4184
+ pattern: new RegExp(`^${requirements}[${chars}]{${min},${max}}$`),
4179
4185
  errorMessage: `Password must be ${min}-${max} characters with at least one ${rulesText}.`
4180
4186
  };
4181
4187
  }
@@ -4304,7 +4310,7 @@ var Forms = (() => {
4304
4310
  looksLikeRawDate = (value, options) => {
4305
4311
  if (!value) return false;
4306
4312
  const delimiter = options.delimiter ?? "/";
4307
- if (value.includes(delimiter)) return false;
4313
+ if (delimiter.length > 0 && value.includes(delimiter)) return false;
4308
4314
  const rawPattern = options.dateRawPattern ?? DEFAULT_DATE_RAW_PATTERN;
4309
4315
  const expectedLength = getRawPatternLength(rawPattern);
4310
4316
  const digits2 = value.replace(/\D/g, "");
@@ -4313,7 +4319,7 @@ var Forms = (() => {
4313
4319
  looksLikeRawTime = (value, options) => {
4314
4320
  if (!value) return false;
4315
4321
  const delimiter = options.delimiter ?? ":";
4316
- if (value.includes(delimiter)) return false;
4322
+ if (delimiter.length > 0 && value.includes(delimiter)) return false;
4317
4323
  const rawPattern = options.timeRawPattern ?? options.timePattern ?? DEFAULT_TIME_RAW_PATTERN;
4318
4324
  const expectedLength = getTimePatternLength(rawPattern);
4319
4325
  const digits2 = value.replace(/\D/g, "");
@@ -4358,16 +4364,19 @@ var Forms = (() => {
4358
4364
  );
4359
4365
  };
4360
4366
  stripPrefixAndSuffix = (value, options = {}) => {
4361
- if (!value || !options.prefix) return value;
4362
- const { prefix } = options;
4367
+ if (!value) return value;
4368
+ const { prefix, suffix } = options;
4363
4369
  const tailPrefix = options.tailPrefix ?? false;
4364
- if (tailPrefix && value.endsWith(prefix)) {
4365
- return value.slice(0, -prefix.length);
4370
+ let result = value;
4371
+ if (suffix && result.endsWith(suffix)) {
4372
+ result = result.slice(0, -suffix.length);
4366
4373
  }
4367
- if (!tailPrefix && value.startsWith(prefix)) {
4368
- return value.slice(prefix.length);
4374
+ if (prefix && tailPrefix && result.endsWith(prefix)) {
4375
+ result = result.slice(0, -prefix.length);
4376
+ } else if (prefix && !tailPrefix && result.startsWith(prefix)) {
4377
+ result = result.slice(prefix.length);
4369
4378
  }
4370
- return value;
4379
+ return result;
4371
4380
  };
4372
4381
  getRawValue = (value, formatType, options = {}) => {
4373
4382
  if (!value) return "";
@@ -5025,6 +5034,10 @@ var Forms = (() => {
5025
5034
  ...formatOptions ?? {},
5026
5035
  interpretInputAs: "auto"
5027
5036
  });
5037
+ var buildDisplayInterpretedOptions = (formatOptions) => ({
5038
+ ...formatOptions ?? {},
5039
+ interpretInputAs: "display"
5040
+ });
5028
5041
  var shouldForceAutoInterpretation = (formatOptions) => formatOptions?.interpretInputAs === void 0;
5029
5042
  var buildHandler = (visible, mirror, formatFn, formatType, formatOptions) => {
5030
5043
  const handler = (event) => {
@@ -5034,7 +5047,7 @@ var Forms = (() => {
5034
5047
  if (!isVisible && !isMirror) return;
5035
5048
  const rawInput = isMirror ? mirror.value : visible.value;
5036
5049
  const inputType = readInputType(event);
5037
- const sourceOptions = isMirror && shouldForceAutoInterpretation(formatOptions) ? buildAutoInterpretedOptions(formatOptions) : formatOptions;
5050
+ const sourceOptions = shouldForceAutoInterpretation(formatOptions) ? isMirror ? buildAutoInterpretedOptions(formatOptions) : buildDisplayInterpretedOptions(formatOptions) : formatOptions;
5038
5051
  const { formatted, raw } = formatFn(rawInput, formatType, sourceOptions);
5039
5052
  if (!formatted && !raw) {
5040
5053
  visible.value = "";
@@ -5116,7 +5129,8 @@ var Forms = (() => {
5116
5129
  if (entry.handler !== UNBOUND) {
5117
5130
  const current = entry.visible.value;
5118
5131
  if (current !== "") {
5119
- const { formatted, raw } = formatter.format(current, formatType, formatOptions);
5132
+ const rebindOptions = shouldForceAutoInterpretation(formatOptions) ? buildDisplayInterpretedOptions(formatOptions) : formatOptions;
5133
+ const { formatted, raw } = formatter.format(current, formatType, rebindOptions);
5120
5134
  applyFormattedValue(entry.visible, entry.mirror, formatted, raw);
5121
5135
  }
5122
5136
  continue;