@mario_hahn/jumpy-ui 0.15.0 → 0.15.1

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.
@@ -16658,18 +16658,18 @@ function createCardTokens(theme) {
16658
16658
  if (presetCard?.inactive && presetCard?.active) {
16659
16659
  return {
16660
16660
  inactive: {
16661
- default: normalizeTokenState(presetCard.inactive.default),
16662
- hover: normalizeTokenState(presetCard.inactive.hover),
16663
- pressed: normalizeTokenState(presetCard.inactive.pressed),
16664
- focus: normalizeTokenState(presetCard.inactive.focus),
16665
- disabled: normalizeTokenState(presetCard.inactive.disabled)
16661
+ default: resolveGeneratedState(presetCard.inactive.default, "card-inactive-default", theme),
16662
+ hover: resolveGeneratedState(presetCard.inactive.hover, "card-inactive-hover", theme),
16663
+ pressed: resolveGeneratedState(presetCard.inactive.pressed, "card-inactive-pressed", theme),
16664
+ focus: resolveGeneratedState(presetCard.inactive.focus, "card-inactive-focus", theme),
16665
+ disabled: resolveGeneratedState(presetCard.inactive.disabled, "card-inactive-disabled", theme)
16666
16666
  },
16667
16667
  active: {
16668
- default: normalizeTokenState(presetCard.active.default),
16669
- hover: normalizeTokenState(presetCard.active.hover),
16670
- pressed: normalizeTokenState(presetCard.active.pressed),
16671
- focus: normalizeTokenState(presetCard.active.focus),
16672
- disabled: normalizeTokenState(presetCard.active.disabled)
16668
+ default: resolveGeneratedState(presetCard.active.default, "card-active-default", theme),
16669
+ hover: resolveGeneratedState(presetCard.active.hover, "card-active-hover", theme),
16670
+ pressed: resolveGeneratedState(presetCard.active.pressed, "card-active-pressed", theme),
16671
+ focus: resolveGeneratedState(presetCard.active.focus, "card-active-focus", theme),
16672
+ disabled: resolveGeneratedState(presetCard.active.disabled, "card-active-disabled", theme)
16673
16673
  }
16674
16674
  };
16675
16675
  }
@@ -16697,18 +16697,18 @@ function createListItemTokens(theme) {
16697
16697
  if (presetInactiveRegular && presetActiveRegular) {
16698
16698
  return {
16699
16699
  inactive: {
16700
- default: normalizeTokenState(presetInactiveRegular.default),
16701
- hover: normalizeTokenState(presetInactiveRegular.hover),
16702
- pressed: normalizeTokenState(presetInactiveRegular.pressed),
16703
- focus: normalizeTokenState(presetInactiveRegular.focus),
16704
- disabled: normalizeTokenState(presetInactiveRegular.disabled)
16700
+ default: resolveGeneratedState(presetInactiveRegular.default, "interactive-inactive-regular-default", theme),
16701
+ hover: resolveGeneratedState(presetInactiveRegular.hover, "interactive-inactive-regular-hover", theme),
16702
+ pressed: resolveGeneratedState(presetInactiveRegular.pressed, "interactive-inactive-regular-pressed", theme),
16703
+ focus: resolveGeneratedState(presetInactiveRegular.focus, "interactive-inactive-regular-focus", theme),
16704
+ disabled: resolveGeneratedState(presetInactiveRegular.disabled, "interactive-inactive-regular-disabled", theme)
16705
16705
  },
16706
16706
  active: {
16707
- default: normalizeTokenState(presetActiveRegular.default),
16708
- hover: normalizeTokenState(presetActiveRegular.hover),
16709
- pressed: normalizeTokenState(presetActiveRegular.pressed),
16710
- focus: normalizeTokenState(presetActiveRegular.focus),
16711
- disabled: normalizeTokenState(presetActiveRegular.disabled)
16707
+ default: resolveGeneratedState(presetActiveRegular.default, "interactive-active-regular-default", theme),
16708
+ hover: resolveGeneratedState(presetActiveRegular.hover, "interactive-active-regular-hover", theme),
16709
+ pressed: resolveGeneratedState(presetActiveRegular.pressed, "interactive-active-regular-pressed", theme),
16710
+ focus: resolveGeneratedState(presetActiveRegular.focus, "interactive-active-regular-focus", theme),
16711
+ disabled: resolveGeneratedState(presetActiveRegular.disabled, "interactive-active-regular-disabled", theme)
16712
16712
  }
16713
16713
  };
16714
16714
  }
@@ -16729,25 +16729,41 @@ function createListItemTokens(theme) {
16729
16729
  }
16730
16730
  };
16731
16731
  }
16732
+ function resolveGeneratedState(state, prefix, theme) {
16733
+ const normalized = normalizeTokenState(state);
16734
+ if (!normalized) return normalized;
16735
+ const sources = { ...color_sources_default.base, ...color_sources_default.presets?.[theme.__tokenPresetName || "default-light"] };
16736
+ const slots = { surface: "surface", border: "border", text: "text", subtext: "subtext", icon: "icon", handle: "handle", focusRing: "focus-ring", hoverRing: "hover-ring" };
16737
+ const resolved = { ...normalized };
16738
+ for (const [slot, cssSlot] of Object.entries(slots)) {
16739
+ const source = sources[`jumpy-${prefix}-${cssSlot}`];
16740
+ if (source && theme.color?.[source] !== void 0) resolved[slot] = theme.color[source];
16741
+ }
16742
+ return resolved;
16743
+ }
16744
+ function resolveSelectorState(state, group, name, theme) {
16745
+ return resolveGeneratedState(state, `selectors-${group}-${name}`, theme);
16746
+ }
16732
16747
  function createSelectorTokens(theme) {
16733
16748
  const presetSelectors = getWebPresetTokenRoot(theme.__tokenPresetName || "default-light")?.selectors;
16734
16749
  if (presetSelectors?.inactive && presetSelectors?.active) {
16750
+ const state = (group, name, key = name) => resolveSelectorState(presetSelectors[group][key], group, name, theme);
16735
16751
  return {
16736
16752
  inactive: {
16737
- default: normalizeTokenState(presetSelectors.inactive.default),
16738
- disabled: normalizeTokenState(presetSelectors.inactive.disabled),
16739
- focus: normalizeTokenState(presetSelectors.inactive.focus),
16740
- hover: normalizeTokenState(presetSelectors.inactive.hover),
16741
- pressed: normalizeTokenState(presetSelectors.inactive.pressed),
16742
- readOnly: normalizeTokenState(presetSelectors.inactive.read?.only)
16753
+ default: state("inactive", "default"),
16754
+ disabled: state("inactive", "disabled"),
16755
+ focus: state("inactive", "focus"),
16756
+ hover: state("inactive", "hover"),
16757
+ pressed: state("inactive", "pressed"),
16758
+ readOnly: resolveSelectorState(presetSelectors.inactive.read?.only, "inactive", "read-only", theme)
16743
16759
  },
16744
16760
  active: {
16745
- default: normalizeTokenState(presetSelectors.active.default),
16746
- disabled: normalizeTokenState(presetSelectors.active.disabled),
16747
- focus: normalizeTokenState(presetSelectors.active.focus),
16748
- hover: normalizeTokenState(presetSelectors.active.hover),
16749
- pressed: normalizeTokenState(presetSelectors.active.pressed),
16750
- readOnly: normalizeTokenState(presetSelectors.active.read?.only)
16761
+ default: state("active", "default"),
16762
+ disabled: state("active", "disabled"),
16763
+ focus: state("active", "focus"),
16764
+ hover: state("active", "hover"),
16765
+ pressed: state("active", "pressed"),
16766
+ readOnly: resolveSelectorState(presetSelectors.active.read?.only, "active", "read-only", theme)
16751
16767
  }
16752
16768
  };
16753
16769
  }
@@ -18,7 +18,7 @@ import {
18
18
  textStyleValue,
19
19
  themeToCSSVariables,
20
20
  useJumpyTheme
21
- } from "./chunk-YAOAIT3N.js";
21
+ } from "./chunk-5YSWJIM2.js";
22
22
  import {
23
23
  cn
24
24
  } from "./chunk-3DBKYKP2.js";
@@ -2876,17 +2876,45 @@ function formatTimeValue(value, format = "HH:mm") {
2876
2876
  const hours12 = hours24 % 12 || 12;
2877
2877
  return format.includes("aa") ? format.replace("hh", String(hours12).padStart(2, "0")).replace("mm", minutes).replace("aa", period) : format.replace("HH", String(hours24).padStart(2, "0")).replace("mm", minutes);
2878
2878
  }
2879
- function parseDateValue(text, format = "MM/dd/yyyy") {
2879
+ var MASK_TOKENS = { yyyy: { max: 4 }, MM: { max: 2, padAbove: "1" }, dd: { max: 2, padAbove: "3" }, HH: { max: 2, padAbove: "2" }, mm: { max: 2, padAbove: "5" } };
2880
+ function maskDigitsToFormat(text, format) {
2881
+ const digits = text.replace(/\D/g, "");
2882
+ const typedSeparator = /\D$/.test(text);
2883
+ const parts = format.split(/(yyyy|MM|dd|HH|mm)/).filter(Boolean);
2884
+ let out = "";
2885
+ let index = 0;
2886
+ for (let i = 0; i < parts.length; i += 1) {
2887
+ const rule = MASK_TOKENS[parts[i]];
2888
+ if (!rule) continue;
2889
+ if (index >= digits.length) break;
2890
+ let chunk;
2891
+ if (rule.padAbove && digits[index] > rule.padAbove) {
2892
+ chunk = `0${digits[index]}`;
2893
+ index += 1;
2894
+ } else {
2895
+ chunk = digits.slice(index, index + rule.max);
2896
+ index += chunk.length;
2897
+ if (rule.padAbove && chunk.length === 1 && typedSeparator && index === digits.length) chunk = `0${chunk}`;
2898
+ }
2899
+ out += chunk;
2900
+ if (chunk.length < rule.max) break;
2901
+ const next = parts.findIndex((part, position) => position > i && MASK_TOKENS[part]);
2902
+ if (next !== -1 && (index < digits.length || typedSeparator)) out += parts.slice(i + 1, next).join("");
2903
+ }
2904
+ return out;
2905
+ }
2906
+ function parseDateValue(text, format = "MM/dd/yyyy", { shortYear = false } = {}) {
2880
2907
  const value = text.trim();
2881
2908
  if (!value) return null;
2882
2909
  const activeFormat = Array.isArray(format) ? format[0] : format;
2883
2910
  const escaped = activeFormat.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2884
- const pattern = escaped.replace("dd", "(?<dd>\\d{1,2})").replace("MM", "(?<MM>\\d{1,2})").replace("yyyy", "(?<yyyy>\\d{4})");
2911
+ const pattern = escaped.replace("dd", "(?<dd>\\d{1,2})").replace("MM", "(?<MM>\\d{1,2})").replace("yyyy", shortYear ? "(?<yyyy>\\d{4}|\\d{2})" : "(?<yyyy>\\d{4})");
2885
2912
  const match = value.match(new RegExp(`^${pattern}$`));
2886
2913
  if (!match?.groups) return null;
2887
2914
  const day = Number(match.groups.dd);
2888
2915
  const month = Number(match.groups.MM) - 1;
2889
- const year = Number(match.groups.yyyy);
2916
+ let year = Number(match.groups.yyyy);
2917
+ if (match.groups.yyyy.length === 2) year += year <= (/* @__PURE__ */ new Date()).getFullYear() % 100 + 10 ? 2e3 : 1900;
2890
2918
  const date = new Date(year, month, day);
2891
2919
  return date.getFullYear() === year && date.getMonth() === month && date.getDate() === day ? date : null;
2892
2920
  }
@@ -3004,12 +3032,14 @@ function JumpDatePicker({ label = "Date", hint, value, defaultValue = null, onCh
3004
3032
  readOnly,
3005
3033
  disabled,
3006
3034
  "data-has-value": selectedTime !== null,
3035
+ "data-jumpy-floating": isOpen,
3007
3036
  value: draft,
3008
3037
  placeholder: props.placeholder || (Array.isArray(format) ? format[0] : format),
3009
3038
  autoComplete: "off",
3010
3039
  inputMode: "numeric",
3011
3040
  onChange: (event) => {
3012
- const text = event.target.value;
3041
+ const typed = event.target.value;
3042
+ const text = typed.length > draft.length && event.target.selectionStart === typed.length ? maskDigitsToFormat(typed, resolvedFormat) || typed : typed;
3013
3043
  setDraft(text);
3014
3044
  const parsedDate = parseDateValue(text, format);
3015
3045
  typedValue.current = void 0;
@@ -3023,7 +3053,15 @@ function JumpDatePicker({ label = "Date", hint, value, defaultValue = null, onCh
3023
3053
  },
3024
3054
  onBlur: (event) => {
3025
3055
  typedValue.current = void 0;
3026
- setDraft(inputValue);
3056
+ const shortDate = parseDateValue(draft, format) ? null : parseDateValue(draft, format, { shortYear: true });
3057
+ if (shortDate && shortDate.getTime() !== selectedTime && !dateIsUnavailable(shortDate, { minDate, maxDate, disabledDates, isDateDisabled })) {
3058
+ const next = coerceDateOutput(shortDate, value ?? defaultValue);
3059
+ setDraft(formatDateValue(shortDate, resolvedFormat));
3060
+ if (!isControlled) setInternalValue(next);
3061
+ onChange?.(next);
3062
+ } else {
3063
+ setDraft(inputValue);
3064
+ }
3027
3065
  props.onBlur?.(event);
3028
3066
  },
3029
3067
  onClick: (event) => {
@@ -3138,12 +3176,14 @@ function JumpTimePicker({ label = "Time", hint, value, defaultValue = null, onCh
3138
3176
  readOnly,
3139
3177
  disabled,
3140
3178
  "data-has-value": selectedTime !== null,
3179
+ "data-jumpy-floating": isOpen,
3141
3180
  value: draft,
3142
3181
  placeholder: props.placeholder || resolvedFormat,
3143
3182
  autoComplete: "off",
3144
3183
  inputMode: resolvedFormat.includes("aa") ? "text" : "numeric",
3145
3184
  onChange: (event) => {
3146
- const text = event.target.value;
3185
+ const typed = event.target.value;
3186
+ const text = !resolvedFormat.includes("aa") && typed.length > draft.length && event.target.selectionStart === typed.length ? maskDigitsToFormat(typed, resolvedFormat) || typed : typed;
3147
3187
  setDraft(text);
3148
3188
  const parsedDate = parseTimeValue(text, resolvedFormat);
3149
3189
  typedValue.current = void 0;
@@ -3890,7 +3930,8 @@ function JumpBaseInput({ label, hint, children, className = "", error = false, h
3890
3930
  const disabled = Boolean(child.props.disabled);
3891
3931
  const isDropdownTrigger = child.props["data-jumpy-dropdown-trigger"] === true || child.props["data-jumpy-dropdown-trigger"] === "true";
3892
3932
  const readOnly = Boolean(child.props.readOnly) && !isDropdownTrigger;
3893
- const floating = focused && !readOnly || hasValue || Boolean(props.slots?.content);
3933
+ const keepFloating = child.props["data-jumpy-floating"] === true || child.props["data-jumpy-floating"] === "true";
3934
+ const floating = focused && !readOnly || hasValue || childHasValue || keepFloating || Boolean(props.slots?.content);
3894
3935
  const isTextarea = child.type === JumpTextarea || child.props["data-jumpy-token-editor"] && child.props.multiline;
3895
3936
  const isDropdown = isDropdownTrigger || child.props["data-jumpy-component"] === "dropdown";
3896
3937
  const status = error ? "alarm" : props.status || "regular";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  JumpField,
3
3
  JumpyFieldContext
4
- } from "./chunk-K4DXYTVW.js";
4
+ } from "./chunk-UT6U2IMA.js";
5
5
  import {
6
6
  JumpySpacing,
7
7
  spacingValue,
8
8
  useJumpyTheme
9
- } from "./chunk-YAOAIT3N.js";
9
+ } from "./chunk-5YSWJIM2.js";
10
10
 
11
11
  // editor.js
12
12
  import { useContext, useRef as useRef2, useState as useState2 } from "react";
@@ -74,7 +74,7 @@ import {
74
74
  getSortOrder,
75
75
  isRowFullySelected,
76
76
  useJumpSnackbar
77
- } from "./chunk-K4DXYTVW.js";
77
+ } from "./chunk-UT6U2IMA.js";
78
78
  import {
79
79
  JumpyAnimation,
80
80
  JumpyAnimationDelay,
@@ -105,7 +105,7 @@ import {
105
105
  textStyleValue,
106
106
  themeToCSSVariables,
107
107
  useJumpyTheme
108
- } from "./chunk-YAOAIT3N.js";
108
+ } from "./chunk-5YSWJIM2.js";
109
109
  import "./chunk-3DBKYKP2.js";
110
110
  import {
111
111
  jumpyThemeInventory
package/dist/editor.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import {
3
3
  JumpTokenInput
4
- } from "./chunk-NK6N6UY5.js";
5
- import "./chunk-K4DXYTVW.js";
6
- import "./chunk-YAOAIT3N.js";
4
+ } from "./chunk-ZFRDQCPV.js";
5
+ import "./chunk-UT6U2IMA.js";
6
+ import "./chunk-5YSWJIM2.js";
7
7
  import "./chunk-3DBKYKP2.js";
8
8
  import "./chunk-XDTVYUWG.js";
9
9
  export {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  JumpTokenInput
4
- } from "./chunk-NK6N6UY5.js";
4
+ } from "./chunk-ZFRDQCPV.js";
5
5
  import {
6
6
  BrandMark,
7
7
  JumpAppShell,
@@ -77,7 +77,7 @@ import {
77
77
  getSortOrder,
78
78
  isRowFullySelected,
79
79
  useJumpSnackbar
80
- } from "./chunk-K4DXYTVW.js";
80
+ } from "./chunk-UT6U2IMA.js";
81
81
  import {
82
82
  JumpyAnimation,
83
83
  JumpyAnimationDelay,
@@ -108,7 +108,7 @@ import {
108
108
  textStyleValue,
109
109
  themeToCSSVariables,
110
110
  useJumpyTheme
111
- } from "./chunk-YAOAIT3N.js";
111
+ } from "./chunk-5YSWJIM2.js";
112
112
  import "./chunk-3DBKYKP2.js";
113
113
  import {
114
114
  jumpyThemeInventory
package/dist/theme.js CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  textStyleValue,
31
31
  themeToCSSVariables,
32
32
  useJumpyTheme
33
- } from "./chunk-YAOAIT3N.js";
33
+ } from "./chunk-5YSWJIM2.js";
34
34
  export {
35
35
  JumpyAnimation,
36
36
  JumpyAnimationDelay,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mario_hahn/jumpy-ui",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": ["**/*.css"],