@officesdk/design 0.2.7 → 0.2.9

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.
@@ -73,6 +73,25 @@ interface ButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
73
73
  */
74
74
  declare const Button: React$1.FC<ButtonProps>;
75
75
 
76
+ /**
77
+ * Value map utilities for piecewise linear mapping (non-linear slider)
78
+ */
79
+ interface ValueMapPiece {
80
+ /** Size of the piece (value range) */
81
+ size: number;
82
+ /** Step increment, defaults to 1 */
83
+ step?: number;
84
+ /** Visual size (relative), defaults to size/step */
85
+ visualSize?: number;
86
+ }
87
+ interface ValueMap {
88
+ type: 'piecewise';
89
+ /** Starting value */
90
+ start: number;
91
+ /** Array of pieces defining the mapping */
92
+ pieces: ValueMapPiece[];
93
+ }
94
+
76
95
  type LineType$1 = 'outlined' | 'underlined' | 'borderless';
77
96
  interface NumberInputProps {
78
97
  /**
@@ -152,6 +171,11 @@ interface NumberInputProps {
152
171
  * @default false
153
172
  */
154
173
  useThousandsSeparator?: boolean;
174
+ /**
175
+ * Value map for piecewise linear mapping (non-linear stepping)
176
+ * When provided, min/max/step props are ignored
177
+ */
178
+ valueMap?: ValueMap;
155
179
  /**
156
180
  * Callback when value changes
157
181
  * @param fixedValue - The clamped value within min/max range (can be undefined if empty)
@@ -181,6 +205,16 @@ interface NumberInputProps {
181
205
  * @param parsedValue - The parsed number value (undefined if invalid)
182
206
  */
183
207
  onInputChange?: (inputValue: string, parsedValue: number | undefined) => void;
208
+ /**
209
+ * Whether to select all text when the input receives focus
210
+ * @default false
211
+ */
212
+ selectAllOnFocus?: boolean;
213
+ /**
214
+ * Whether to blur the input when Escape key is pressed
215
+ * @default true
216
+ */
217
+ blurOnEscape?: boolean;
184
218
  }
185
219
  /**
186
220
  * NumberInput Component
@@ -241,6 +275,11 @@ interface SpinButtonProps {
241
275
  * Parse the input value
242
276
  */
243
277
  parser?: (displayValue: string) => number;
278
+ /**
279
+ * Value map for piecewise linear mapping (non-linear stepping)
280
+ * When provided, min/max/step props are ignored in NumberInput and Slider
281
+ */
282
+ valueMap?: ValueMap;
244
283
  /**
245
284
  * Callback when value changes
246
285
  */
@@ -257,7 +296,7 @@ interface SpinButtonProps {
257
296
  * Additional props passed to the internal NumberInput component
258
297
  * Allows customizing unit, placeholder, lineType, showStepButtons, etc.
259
298
  */
260
- inputProps?: Partial<Omit<NumberInputProps, 'value' | 'defaultValue' | 'min' | 'max' | 'step' | 'size' | 'disabled' | 'alert' | 'precision' | 'formatter' | 'parser' | 'onChange' | 'className' | 'style'>>;
299
+ inputProps?: Partial<Omit<NumberInputProps, 'value' | 'defaultValue' | 'min' | 'max' | 'step' | 'size' | 'disabled' | 'alert' | 'precision' | 'formatter' | 'parser' | 'valueMap' | 'onChange' | 'className' | 'style'>>;
261
300
  }
262
301
  /**
263
302
  * SpinButton Component - Spin Button
@@ -425,25 +464,6 @@ interface CheckboxProps {
425
464
  */
426
465
  declare const Checkbox: React$1.FC<CheckboxProps>;
427
466
 
428
- /**
429
- * Value map utilities for piecewise linear mapping (non-linear slider)
430
- */
431
- interface ValueMapPiece {
432
- /** Size of the piece (value range) */
433
- size: number;
434
- /** Step increment, defaults to 1 */
435
- step?: number;
436
- /** Visual size (relative), defaults to size/step */
437
- visualSize?: number;
438
- }
439
- interface ValueMap {
440
- type: 'piecewise';
441
- /** Starting value */
442
- start: number;
443
- /** Array of pieces defining the mapping */
444
- pieces: ValueMapPiece[];
445
- }
446
-
447
467
  interface SliderProps {
448
468
  /**
449
469
  * Current value (0-100)
@@ -1614,28 +1614,12 @@ var init_numberLocale = __esm({
1614
1614
  };
1615
1615
  }
1616
1616
  });
1617
- var getDecimalPlaces, precisionAdd, precisionSubtract, NumberInputContainer, InputWrapper, UnitText, StyledInput, ButtonGroup, StepButton, UpArrow, DownArrow; exports.NumberInput = void 0;
1618
- var init_NumberInput = __esm({
1619
- "src/NumberInput/NumberInput.tsx"() {
1617
+
1618
+ // src/NumberInput/NumberInput.styled.ts
1619
+ var NumberInputContainer, InputWrapper, StyledInput, ButtonGroup, StepButton;
1620
+ var init_NumberInput_styled = __esm({
1621
+ "src/NumberInput/NumberInput.styled.ts"() {
1620
1622
  init_styled();
1621
- init_UIConfigProvider2();
1622
- init_numberLocale();
1623
- getDecimalPlaces = (num) => {
1624
- const str = String(num);
1625
- const decimalIndex = str.indexOf(".");
1626
- if (decimalIndex === -1) return 0;
1627
- return str.length - decimalIndex - 1;
1628
- };
1629
- precisionAdd = (a, b) => {
1630
- const precision = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
1631
- const multiplier = Math.pow(10, precision);
1632
- return Math.round(a * multiplier + b * multiplier) / multiplier;
1633
- };
1634
- precisionSubtract = (a, b) => {
1635
- const precision = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
1636
- const multiplier = Math.pow(10, precision);
1637
- return Math.round(a * multiplier - b * multiplier) / multiplier;
1638
- };
1639
1623
  NumberInputContainer = exports.styled.div`
1640
1624
  display: inline-flex;
1641
1625
  align-items: center;
@@ -1706,25 +1690,6 @@ var init_NumberInput = __esm({
1706
1690
  align-items: center;
1707
1691
  padding: 0 8px;
1708
1692
  min-width: 0;
1709
- gap: 4px;
1710
- `;
1711
- UnitText = exports.styled.span`
1712
- flex-shrink: 0;
1713
- font-family: 'PingFang SC', sans-serif;
1714
- font-weight: 400;
1715
- line-height: 20px;
1716
-
1717
- ${({ $size }) => $size === "small" ? `
1718
- font-size: 12px;
1719
- ` : `
1720
- font-size: 13px;
1721
- `}
1722
-
1723
- ${({ $disabled, theme: theme2 }) => $disabled ? `
1724
- color: ${theme2.colors.palettes.transparency["30"]};
1725
- ` : `
1726
- color: ${theme2.colors.palettes.gray["120"]};
1727
- `}
1728
1693
  `;
1729
1694
  StyledInput = exports.styled.input`
1730
1695
  width: 100%;
@@ -1842,6 +1807,31 @@ var init_NumberInput = __esm({
1842
1807
  fill: ${({ $disabled, theme: theme2 }) => $disabled ? theme2.colors.palettes.transparency["30"] : theme2.colors.palettes.gray["120"]};
1843
1808
  }
1844
1809
  `;
1810
+ }
1811
+ });
1812
+ var getDecimalPlaces, precisionAdd, precisionSubtract, UpArrow, DownArrow; exports.NumberInput = void 0;
1813
+ var init_NumberInput = __esm({
1814
+ "src/NumberInput/NumberInput.tsx"() {
1815
+ init_UIConfigProvider2();
1816
+ init_numberLocale();
1817
+ init_valueMap();
1818
+ init_NumberInput_styled();
1819
+ getDecimalPlaces = (num) => {
1820
+ const str = String(num);
1821
+ const decimalIndex = str.indexOf(".");
1822
+ if (decimalIndex === -1) return 0;
1823
+ return str.length - decimalIndex - 1;
1824
+ };
1825
+ precisionAdd = (a, b) => {
1826
+ const precision = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
1827
+ const multiplier = Math.pow(10, precision);
1828
+ return Math.round(a * multiplier + b * multiplier) / multiplier;
1829
+ };
1830
+ precisionSubtract = (a, b) => {
1831
+ const precision = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
1832
+ const multiplier = Math.pow(10, precision);
1833
+ return Math.round(a * multiplier - b * multiplier) / multiplier;
1834
+ };
1845
1835
  UpArrow = () => /* @__PURE__ */ React3__default.default.createElement("svg", { viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React3__default.default.createElement("path", { d: "M7 4.5L10.5 8.5H3.5L7 4.5Z", fill: "currentColor" }));
1846
1836
  DownArrow = () => /* @__PURE__ */ React3__default.default.createElement("svg", { viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React3__default.default.createElement("path", { d: "M7 9.5L3.5 5.5H10.5L7 9.5Z", fill: "currentColor" }));
1847
1837
  exports.NumberInput = ({
@@ -1862,12 +1852,15 @@ var init_NumberInput = __esm({
1862
1852
  showStepButtonsTrigger = "normal",
1863
1853
  lineType = "outlined",
1864
1854
  useThousandsSeparator = false,
1855
+ valueMap: valueMapProp,
1865
1856
  onChange,
1866
1857
  className,
1867
1858
  style,
1868
1859
  onFocus: onFocusProp,
1869
1860
  onBlur: onBlurProp,
1870
- onInputChange
1861
+ onInputChange,
1862
+ selectAllOnFocus = false,
1863
+ blurOnEscape = true
1871
1864
  }) => {
1872
1865
  const config = exports.useUIConfig();
1873
1866
  const locale = config?.locale ?? "en-US";
@@ -1877,20 +1870,31 @@ var init_NumberInput = __esm({
1877
1870
  const [isHovered, setIsHovered] = React3.useState(false);
1878
1871
  const inputRef = React3.useRef(null);
1879
1872
  const value = controlledValue !== void 0 ? controlledValue : internalValue;
1873
+ const extendedValueMap = React3.useMemo(() => {
1874
+ if (!valueMapProp) return void 0;
1875
+ return extendValueMap(valueMapProp);
1876
+ }, [valueMapProp]);
1877
+ const effectiveMin = extendedValueMap ? extendedValueMap.start : min;
1878
+ const effectiveMax = extendedValueMap ? extendedValueMap.end : max;
1880
1879
  const formatValue = React3.useCallback(
1881
1880
  (val) => {
1882
1881
  if (val === void 0) {
1883
1882
  return "";
1884
1883
  }
1884
+ let formatted;
1885
1885
  if (formatter) {
1886
- return formatter(val);
1886
+ formatted = formatter(val);
1887
+ } else if (useThousandsSeparator) {
1888
+ formatted = formatNumber(val, locale, precision);
1889
+ } else {
1890
+ formatted = formatNumberForEdit(val, locale, precision);
1887
1891
  }
1888
- if (useThousandsSeparator) {
1889
- return formatNumber(val, locale, precision);
1892
+ if (unit) {
1893
+ return formatted + unit;
1890
1894
  }
1891
- return formatNumberForEdit(val, locale, precision);
1895
+ return formatted;
1892
1896
  },
1893
- [formatter, precision, locale, useThousandsSeparator]
1897
+ [formatter, precision, locale, useThousandsSeparator, unit]
1894
1898
  );
1895
1899
  const formatValueForEdit = React3.useCallback(
1896
1900
  (val) => {
@@ -1933,9 +1937,9 @@ var init_NumberInput = __esm({
1933
1937
  if (val === void 0) {
1934
1938
  return void 0;
1935
1939
  }
1936
- return Math.max(min, Math.min(max, val));
1940
+ return Math.max(effectiveMin, Math.min(effectiveMax, val));
1937
1941
  },
1938
- [min, max]
1942
+ [effectiveMin, effectiveMax]
1939
1943
  );
1940
1944
  const handleValueChange = React3.useCallback(
1941
1945
  (newValue) => {
@@ -1950,23 +1954,23 @@ var init_NumberInput = __esm({
1950
1954
  const increment = React3.useCallback(() => {
1951
1955
  if (disabled) return;
1952
1956
  const currentValue = value ?? 0;
1953
- const newValue = precisionAdd(currentValue, step);
1957
+ const newValue = extendedValueMap ? changeByStep(currentValue, 1, extendedValueMap) : precisionAdd(currentValue, step);
1954
1958
  handleValueChange(newValue);
1955
1959
  if (isFocused) {
1956
1960
  const clampedValue = clampValue(newValue);
1957
1961
  setDisplayValue(formatValueForEdit(clampedValue));
1958
1962
  }
1959
- }, [disabled, value, step, handleValueChange, isFocused, clampValue, formatValueForEdit]);
1963
+ }, [disabled, value, step, handleValueChange, isFocused, clampValue, formatValueForEdit, extendedValueMap]);
1960
1964
  const decrement = React3.useCallback(() => {
1961
1965
  if (disabled) return;
1962
1966
  const currentValue = value ?? 0;
1963
- const newValue = precisionSubtract(currentValue, step);
1967
+ const newValue = extendedValueMap ? changeByStep(currentValue, -1, extendedValueMap) : precisionSubtract(currentValue, step);
1964
1968
  handleValueChange(newValue);
1965
1969
  if (isFocused) {
1966
1970
  const clampedValue = clampValue(newValue);
1967
1971
  setDisplayValue(formatValueForEdit(clampedValue));
1968
1972
  }
1969
- }, [disabled, value, step, handleValueChange, isFocused, clampValue, formatValueForEdit]);
1973
+ }, [disabled, value, step, handleValueChange, isFocused, clampValue, formatValueForEdit, extendedValueMap]);
1970
1974
  const handleInputChange = React3.useCallback(
1971
1975
  (e) => {
1972
1976
  const inputValue = e.target.value;
@@ -1988,22 +1992,28 @@ var init_NumberInput = __esm({
1988
1992
  const parsed = parseValue(trimmedValue);
1989
1993
  if (parsed !== null) {
1990
1994
  const preciseValue = applyPrecision(parsed);
1991
- handleValueChange(preciseValue);
1995
+ const finalValue = extendedValueMap && preciseValue !== void 0 ? snapToStep(preciseValue, extendedValueMap) : preciseValue;
1996
+ handleValueChange(finalValue);
1992
1997
  } else {
1993
1998
  setDisplayValue(formatValue(value));
1994
1999
  }
1995
2000
  }
1996
2001
  onBlurProp?.(e);
1997
2002
  },
1998
- [displayValue, parseValue, handleValueChange, value, formatValue, applyPrecision, onBlurProp]
2003
+ [displayValue, parseValue, handleValueChange, value, formatValue, applyPrecision, onBlurProp, extendedValueMap]
1999
2004
  );
2000
2005
  const handleFocus = React3.useCallback(
2001
2006
  (e) => {
2002
2007
  setIsFocused(true);
2003
2008
  setDisplayValue(formatValueForEdit(value));
2009
+ if (selectAllOnFocus) {
2010
+ requestAnimationFrame(() => {
2011
+ inputRef.current?.select();
2012
+ });
2013
+ }
2004
2014
  onFocusProp?.(e);
2005
2015
  },
2006
- [value, formatValueForEdit, onFocusProp]
2016
+ [value, formatValueForEdit, onFocusProp, selectAllOnFocus]
2007
2017
  );
2008
2018
  const handleKeyDown = React3.useCallback(
2009
2019
  (e) => {
@@ -2015,9 +2025,11 @@ var init_NumberInput = __esm({
2015
2025
  decrement();
2016
2026
  } else if (e.key === "Enter") {
2017
2027
  inputRef.current?.blur();
2028
+ } else if (e.key === "Escape" && blurOnEscape) {
2029
+ inputRef.current?.blur();
2018
2030
  }
2019
2031
  },
2020
- [increment, decrement]
2032
+ [increment, decrement, blurOnEscape]
2021
2033
  );
2022
2034
  const handleMouseEnter = React3.useCallback(() => {
2023
2035
  setIsHovered(true);
@@ -2053,7 +2065,7 @@ var init_NumberInput = __esm({
2053
2065
  $size: size,
2054
2066
  $disabled: disabled
2055
2067
  }
2056
- ), unit && /* @__PURE__ */ React3__default.default.createElement(UnitText, { $size: size, $disabled: disabled }, unit)),
2068
+ )),
2057
2069
  showStepButtons && (showStepButtonsTrigger !== "hover" || isHovered || isFocused) && /* @__PURE__ */ React3__default.default.createElement(ButtonGroup, { $alert: alert, $disabled: disabled, $lineType: lineType }, /* @__PURE__ */ React3__default.default.createElement(
2058
2070
  StepButton,
2059
2071
  {
@@ -2120,6 +2132,7 @@ var init_SpinButton = __esm({
2120
2132
  precision,
2121
2133
  formatter,
2122
2134
  parser,
2135
+ valueMap,
2123
2136
  onChange,
2124
2137
  className,
2125
2138
  style,
@@ -2149,6 +2162,7 @@ var init_SpinButton = __esm({
2149
2162
  max,
2150
2163
  step,
2151
2164
  disabled,
2165
+ valueMap,
2152
2166
  onChange: handleValueChange
2153
2167
  }
2154
2168
  )), /* @__PURE__ */ React3__default.default.createElement(
@@ -2164,6 +2178,7 @@ var init_SpinButton = __esm({
2164
2178
  precision,
2165
2179
  formatter,
2166
2180
  parser,
2181
+ valueMap,
2167
2182
  ...inputProps,
2168
2183
  onChange: handleValueChange
2169
2184
  }