@sia.soul/sia-react-ui 0.1.48 → 0.1.49

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/dist/core.css CHANGED
@@ -7458,11 +7458,15 @@ fieldset:disabled .sia-input-number__floating-placeholder {
7458
7458
  }
7459
7459
  .sia-form-item {
7460
7460
  display: grid;
7461
- grid-template-columns: minmax(90px, 140px) minmax(0, 1fr);
7461
+ grid-template-columns: var(--sia-form-label-width, var(--sia-form-auto-label-width, 0px)) minmax(0, 1fr);
7462
7462
  gap: 8px 14px;
7463
7463
  margin-bottom: 6px;
7464
7464
  color: var(--sia-color-text);
7465
7465
  }
7466
+ .sia-form-item__label-content {
7467
+ display: inline-block;
7468
+ width: max-content;
7469
+ }
7466
7470
  .sia-form-item__label {
7467
7471
  padding-top: 8px;
7468
7472
  text-align: right;
@@ -7554,6 +7558,7 @@ fieldset:disabled .sia-input-number__floating-placeholder {
7554
7558
  gap: 8px;
7555
7559
  }
7556
7560
  .sia-form--inline .sia-form-item__label {
7561
+ flex: 0 0 var(--sia-form-label-width, var(--sia-form-auto-label-width, 0px));
7557
7562
  text-align: left;
7558
7563
  }
7559
7564
  .sia-form-error-list {
package/dist/index.cjs CHANGED
@@ -6352,9 +6352,51 @@ function FormRoot({
6352
6352
  const instance = internalForm;
6353
6353
  instance.configure(initialValues, { onFinish, onFinishFailed, onValuesChange });
6354
6354
  const context = (0, import_react29.useMemo)(() => instance, [instance]);
6355
+ const formRef = (0, import_react29.useRef)(null);
6356
+ (0, import_react29.useLayoutEffect)(() => {
6357
+ const root = formRef.current;
6358
+ if (!root) return;
6359
+ let frame = 0;
6360
+ const observed = /* @__PURE__ */ new Set();
6361
+ const measure = () => {
6362
+ frame = 0;
6363
+ const labels = [...root.querySelectorAll(".sia-form-item__label-content")].filter((label) => label.closest(".sia-form") === root);
6364
+ const next = new Set(labels);
6365
+ observed.forEach((label) => {
6366
+ if (!next.has(label)) {
6367
+ resizeObserver.unobserve(label);
6368
+ observed.delete(label);
6369
+ }
6370
+ });
6371
+ let width = 0;
6372
+ labels.forEach((label) => {
6373
+ if (!observed.has(label)) {
6374
+ resizeObserver.observe(label);
6375
+ observed.add(label);
6376
+ }
6377
+ if (label.getClientRects().length) width = Math.max(width, label.offsetWidth);
6378
+ });
6379
+ const value = `${Math.ceil(width)}px`;
6380
+ if (root.style.getPropertyValue("--sia-form-auto-label-width") !== value) root.style.setProperty("--sia-form-auto-label-width", value);
6381
+ };
6382
+ const schedule = () => {
6383
+ if (!frame) frame = requestAnimationFrame(measure);
6384
+ };
6385
+ const resizeObserver = new ResizeObserver(schedule);
6386
+ resizeObserver.observe(root);
6387
+ const mutations = new MutationObserver(schedule);
6388
+ mutations.observe(root, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: ["class", "style", "hidden"] });
6389
+ measure();
6390
+ return () => {
6391
+ resizeObserver.disconnect();
6392
+ mutations.disconnect();
6393
+ if (frame) cancelAnimationFrame(frame);
6394
+ };
6395
+ }, []);
6355
6396
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(FormContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(PlaceholderModeContext.Provider, { value: resolvedPlaceholderMode, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ControlSizeContext.Provider, { value: size, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
6356
6397
  "form",
6357
6398
  {
6399
+ ref: formRef,
6358
6400
  ...withTitleTooltip(props),
6359
6401
  className: `sia-form sia-form--${layout} sia-form--${size}${disabled ? " is-disabled" : ""} ${className}`.trim(),
6360
6402
  "data-required-mark": requiredMark,
@@ -6447,10 +6489,10 @@ function FormItem({
6447
6489
  const inputWrap = /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "sia-form-item__input-wrap", children: content });
6448
6490
  const hasError = status === "error" && Boolean(helpContent);
6449
6491
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { ref: itemRef, className: `sia-form-item${status ? ` sia-form-item--${status}` : ""} ${className}`.trim(), "data-sia-form-field": key || void 0, children: [
6450
- label ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { id: labelId, className: "sia-form-item__label", children: [
6492
+ label ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { id: labelId, className: "sia-form-item__label", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "sia-form-item__label-content", children: [
6451
6493
  ruleRequired ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "sia-form-item__required-mark", "aria-hidden": "true", children: "*" }) : null,
6452
6494
  label
6453
- ] }) : null,
6495
+ ] }) }) : null,
6454
6496
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "sia-form-item__control", children: [
6455
6497
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
6456
6498
  Tooltip,
package/dist/index.css CHANGED
@@ -7458,11 +7458,15 @@ fieldset:disabled .sia-input-number__floating-placeholder {
7458
7458
  }
7459
7459
  .sia-form-item {
7460
7460
  display: grid;
7461
- grid-template-columns: minmax(90px, 140px) minmax(0, 1fr);
7461
+ grid-template-columns: var(--sia-form-label-width, var(--sia-form-auto-label-width, 0px)) minmax(0, 1fr);
7462
7462
  gap: 8px 14px;
7463
7463
  margin-bottom: 6px;
7464
7464
  color: var(--sia-color-text);
7465
7465
  }
7466
+ .sia-form-item__label-content {
7467
+ display: inline-block;
7468
+ width: max-content;
7469
+ }
7466
7470
  .sia-form-item__label {
7467
7471
  padding-top: 8px;
7468
7472
  text-align: right;
@@ -7554,6 +7558,7 @@ fieldset:disabled .sia-input-number__floating-placeholder {
7554
7558
  gap: 8px;
7555
7559
  }
7556
7560
  .sia-form--inline .sia-form-item__label {
7561
+ flex: 0 0 var(--sia-form-label-width, var(--sia-form-auto-label-width, 0px));
7557
7562
  text-align: left;
7558
7563
  }
7559
7564
  .sia-form-error-list {
package/dist/index.d.cts CHANGED
@@ -736,7 +736,7 @@ interface FormProps extends Omit<FormHTMLAttributes<HTMLFormElement>, "onSubmit"
736
736
  /** 表单初始值 */
737
737
  initialValues?: FormValues;
738
738
  /**
739
- * 布局方式。
739
+ * 布局方式;horizontal 与 inline 默认按当前表单内最宽标签对齐,vertical 保持标签在控件上方。
740
740
  * @defaultValue "horizontal"
741
741
  */
742
742
  layout?: "horizontal" | "vertical" | "inline";
@@ -769,7 +769,7 @@ declare function FormRoot({ form, initialValues, layout, size: sizeProp, placeho
769
769
  interface FormItemProps {
770
770
  /** 绑定到表单值的字段名或嵌套路径,例如 ["user", "name"]。 */
771
771
  name?: NamePath;
772
- /** 字段标签,支持文本或 React 节点。 */
772
+ /** 字段标签,支持文本或 React 节点;横向及行内布局未指定标签列宽时,与同一 Form 内最宽的可见标签对齐,测量包含必填标记。 */
773
773
  label?: ReactNode;
774
774
  /**
775
775
  * 字段的校验规则,按配置执行。
package/dist/index.d.ts CHANGED
@@ -736,7 +736,7 @@ interface FormProps extends Omit<FormHTMLAttributes<HTMLFormElement>, "onSubmit"
736
736
  /** 表单初始值 */
737
737
  initialValues?: FormValues;
738
738
  /**
739
- * 布局方式。
739
+ * 布局方式;horizontal 与 inline 默认按当前表单内最宽标签对齐,vertical 保持标签在控件上方。
740
740
  * @defaultValue "horizontal"
741
741
  */
742
742
  layout?: "horizontal" | "vertical" | "inline";
@@ -769,7 +769,7 @@ declare function FormRoot({ form, initialValues, layout, size: sizeProp, placeho
769
769
  interface FormItemProps {
770
770
  /** 绑定到表单值的字段名或嵌套路径,例如 ["user", "name"]。 */
771
771
  name?: NamePath;
772
- /** 字段标签,支持文本或 React 节点。 */
772
+ /** 字段标签,支持文本或 React 节点;横向及行内布局未指定标签列宽时,与同一 Form 内最宽的可见标签对齐,测量包含必填标记。 */
773
773
  label?: ReactNode;
774
774
  /**
775
775
  * 字段的校验规则,按配置执行。
package/dist/index.js CHANGED
@@ -1413,7 +1413,7 @@ var Drawer2 = Object.assign(DrawerRoot, {
1413
1413
  });
1414
1414
 
1415
1415
  // src/components/Form.tsx
1416
- import { Children as Children3, cloneElement as cloneElement2, createContext as createContext2, forwardRef as forwardRef2, isValidElement as isValidElement2, useContext as useContext2, useEffect as useEffect3, useId as useId3, useMemo as useMemo4, useRef as useRef5, useSyncExternalStore } from "react";
1416
+ import { Children as Children3, cloneElement as cloneElement2, createContext as createContext2, forwardRef as forwardRef2, isValidElement as isValidElement2, useContext as useContext2, useEffect as useEffect3, useId as useId3, useLayoutEffect as useLayoutEffect2, useMemo as useMemo4, useRef as useRef5, useSyncExternalStore } from "react";
1417
1417
  import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1418
1418
  var Switch = forwardRef2(function Switch2({
1419
1419
  label,
@@ -1660,9 +1660,51 @@ function FormRoot({
1660
1660
  const instance = internalForm;
1661
1661
  instance.configure(initialValues, { onFinish, onFinishFailed, onValuesChange });
1662
1662
  const context = useMemo4(() => instance, [instance]);
1663
+ const formRef = useRef5(null);
1664
+ useLayoutEffect2(() => {
1665
+ const root = formRef.current;
1666
+ if (!root) return;
1667
+ let frame = 0;
1668
+ const observed = /* @__PURE__ */ new Set();
1669
+ const measure = () => {
1670
+ frame = 0;
1671
+ const labels = [...root.querySelectorAll(".sia-form-item__label-content")].filter((label) => label.closest(".sia-form") === root);
1672
+ const next = new Set(labels);
1673
+ observed.forEach((label) => {
1674
+ if (!next.has(label)) {
1675
+ resizeObserver.unobserve(label);
1676
+ observed.delete(label);
1677
+ }
1678
+ });
1679
+ let width = 0;
1680
+ labels.forEach((label) => {
1681
+ if (!observed.has(label)) {
1682
+ resizeObserver.observe(label);
1683
+ observed.add(label);
1684
+ }
1685
+ if (label.getClientRects().length) width = Math.max(width, label.offsetWidth);
1686
+ });
1687
+ const value = `${Math.ceil(width)}px`;
1688
+ if (root.style.getPropertyValue("--sia-form-auto-label-width") !== value) root.style.setProperty("--sia-form-auto-label-width", value);
1689
+ };
1690
+ const schedule = () => {
1691
+ if (!frame) frame = requestAnimationFrame(measure);
1692
+ };
1693
+ const resizeObserver = new ResizeObserver(schedule);
1694
+ resizeObserver.observe(root);
1695
+ const mutations = new MutationObserver(schedule);
1696
+ mutations.observe(root, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: ["class", "style", "hidden"] });
1697
+ measure();
1698
+ return () => {
1699
+ resizeObserver.disconnect();
1700
+ mutations.disconnect();
1701
+ if (frame) cancelAnimationFrame(frame);
1702
+ };
1703
+ }, []);
1663
1704
  return /* @__PURE__ */ jsx9(FormContext.Provider, { value: context, children: /* @__PURE__ */ jsx9(PlaceholderModeContext.Provider, { value: resolvedPlaceholderMode, children: /* @__PURE__ */ jsx9(ControlSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx9(
1664
1705
  "form",
1665
1706
  {
1707
+ ref: formRef,
1666
1708
  ...withTitleTooltip(props),
1667
1709
  className: `sia-form sia-form--${layout} sia-form--${size}${disabled ? " is-disabled" : ""} ${className}`.trim(),
1668
1710
  "data-required-mark": requiredMark,
@@ -1755,10 +1797,10 @@ function FormItem({
1755
1797
  const inputWrap = /* @__PURE__ */ jsx9("div", { className: "sia-form-item__input-wrap", children: content });
1756
1798
  const hasError = status === "error" && Boolean(helpContent);
1757
1799
  return /* @__PURE__ */ jsxs9("div", { ref: itemRef, className: `sia-form-item${status ? ` sia-form-item--${status}` : ""} ${className}`.trim(), "data-sia-form-field": key || void 0, children: [
1758
- label ? /* @__PURE__ */ jsxs9("div", { id: labelId, className: "sia-form-item__label", children: [
1800
+ label ? /* @__PURE__ */ jsx9("div", { id: labelId, className: "sia-form-item__label", children: /* @__PURE__ */ jsxs9("span", { className: "sia-form-item__label-content", children: [
1759
1801
  ruleRequired ? /* @__PURE__ */ jsx9("span", { className: "sia-form-item__required-mark", "aria-hidden": "true", children: "*" }) : null,
1760
1802
  label
1761
- ] }) : null,
1803
+ ] }) }) : null,
1762
1804
  /* @__PURE__ */ jsxs9("div", { className: "sia-form-item__control", children: [
1763
1805
  /* @__PURE__ */ jsx9(
1764
1806
  Tooltip,
@@ -4652,7 +4694,7 @@ function Treemap({
4652
4694
  }
4653
4695
 
4654
4696
  // src/components/Table/TableCellContent.tsx
4655
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef13, useState as useState16 } from "react";
4697
+ import { useLayoutEffect as useLayoutEffect3, useRef as useRef13, useState as useState16 } from "react";
4656
4698
  import { jsx as jsx20 } from "react/jsx-runtime";
4657
4699
  var pendingLayouts = /* @__PURE__ */ new Map();
4658
4700
  var layoutFrame;
@@ -4674,7 +4716,7 @@ function TableCellContent({ children, ellipsis, title }) {
4674
4716
  const ref = useRef13(null);
4675
4717
  const [overflowing, setOverflowing] = useState16(false);
4676
4718
  const customContent = typeof children !== "string" && typeof children !== "number" && children != null;
4677
- useLayoutEffect2(() => {
4719
+ useLayoutEffect3(() => {
4678
4720
  const element = ref.current;
4679
4721
  if (!element || !ellipsis || !customContent) return;
4680
4722
  const normalizeLayouts = (parent, layouts) => {
@@ -4710,7 +4752,7 @@ function TableCellContent({ children, ellipsis, title }) {
4710
4752
  }
4711
4753
 
4712
4754
  // src/components/Table/TableCanvasLayer.tsx
4713
- import { useLayoutEffect as useLayoutEffect3, useRef as useRef14 } from "react";
4755
+ import { useLayoutEffect as useLayoutEffect4, useRef as useRef14 } from "react";
4714
4756
 
4715
4757
  // src/components/Table/utils.ts
4716
4758
  var AUTO_WIDTH_COLUMN_KEYS = /* @__PURE__ */ new Set(["action", "actions", "operation", "operations"]);
@@ -4766,7 +4808,7 @@ function toTablePageParams(current, pageSize) {
4766
4808
  import { jsx as jsx21 } from "react/jsx-runtime";
4767
4809
  function TableCanvasLayer({ viewport, rows, columns, widths, rowHeight, headerHeight }) {
4768
4810
  const canvasRef = useRef14(null);
4769
- useLayoutEffect3(() => {
4811
+ useLayoutEffect4(() => {
4770
4812
  const canvas = canvasRef.current;
4771
4813
  const scroller = viewport.current;
4772
4814
  if (!canvas || !scroller) return;
@@ -8425,7 +8467,7 @@ var InputSelect = forwardRef7(function InputSelect2({
8425
8467
  });
8426
8468
 
8427
8469
  // src/components/QueryForm.tsx
8428
- import { Children as Children4, useLayoutEffect as useLayoutEffect4, useRef as useRef18, useState as useState20 } from "react";
8470
+ import { Children as Children4, useLayoutEffect as useLayoutEffect5, useRef as useRef18, useState as useState20 } from "react";
8429
8471
  import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
8430
8472
  function QueryForm({
8431
8473
  fields,
@@ -8481,7 +8523,7 @@ function QueryForm({
8481
8523
  const rowRef = useRef18(null);
8482
8524
  const actionsRef = useRef18(null);
8483
8525
  const [fittingCount, setFittingCount] = useState20(limit);
8484
- useLayoutEffect4(() => {
8526
+ useLayoutEffect5(() => {
8485
8527
  if (!collapsed) return;
8486
8528
  const row = rowRef.current;
8487
8529
  const actions = actionsRef.current;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sia.soul/sia-react-ui",
3
- "version": "0.1.48",
3
+ "version": "0.1.49",
4
4
  "description": "Sia Design components and tokens for React",
5
5
  "publishConfig": {
6
6
  "access": "public",