@allxsmith/bestax-bulma 5.8.4 → 5.9.0

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/index.cjs.js CHANGED
@@ -5560,6 +5560,17 @@ const useInsideControl = () => React.useContext(ControlContext);
5560
5560
  const FieldProvider = FieldContext.Provider;
5561
5561
  /** Provider for Control context — used internally by Control component. */
5562
5562
  const ControlProvider = ControlContext.Provider;
5563
+ const FieldLabelIdContext = React.createContext(undefined);
5564
+ /**
5565
+ * The id a labeled Field wants its single composed control to adopt (#495).
5566
+ * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the
5567
+ * user took over the association with an explicit `labelProps.htmlFor`.
5568
+ * Consumed only by the single-control bases (InputBase, SelectBase,
5569
+ * TextAreaBase). Internal; not part of the public API.
5570
+ */
5571
+ const useFieldLabelId = () => React.useContext(FieldLabelIdContext);
5572
+ /** Provider for the Field label-target id — used internally by Field. */
5573
+ const FieldLabelIdProvider = FieldLabelIdContext.Provider;
5563
5574
  const RadiosContext = React.createContext(undefined);
5564
5575
  const CheckboxesContext = React.createContext(undefined);
5565
5576
  /**
@@ -5767,15 +5778,19 @@ const FieldBody = ({ textColor, bgColor, className, children, ...props }) => {
5767
5778
  * @see {@link https://bulma.io/documentation/form/general/#field | Bulma Field documentation}
5768
5779
  *
5769
5780
  * @example
5770
- * // Labelled field
5781
+ * // Labelled field — the label auto-associates with the composed base
5771
5782
  * <Field label="Email">
5772
- * <input className="input" type="email" />
5783
+ * <Control>
5784
+ * <InputBase type="email" />
5785
+ * </Control>
5773
5786
  * </Field>
5774
5787
  *
5775
5788
  * @example
5776
5789
  * // Horizontal field
5777
5790
  * <Field horizontal label="Name">
5778
- * <input className="input" />
5791
+ * <Control>
5792
+ * <InputBase />
5793
+ * </Control>
5779
5794
  * </Field>
5780
5795
  */
5781
5796
  const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSize, labelProps, textColor, color: _fieldColor, bgColor, className, children, ...props }) => {
@@ -5802,13 +5817,24 @@ const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSi
5802
5817
  // Default labelSize to 'normal' when horizontal for proper baseline alignment
5803
5818
  const effectiveLabelSize = labelSize ?? (horizontal ? 'normal' : undefined);
5804
5819
  const labelClass = usePrefixedClassNames('label');
5820
+ // Auto-associate the label with a single composed base control (#495): the
5821
+ // label points at a generated id shared via context, which InputBase/
5822
+ // SelectBase/TextAreaBase adopt when the user supplied no id of their own.
5823
+ // Presence semantics on htmlFor — even an explicit `htmlFor: undefined`
5824
+ // means the caller owns the association. Grouped/addons fields hold several
5825
+ // controls, so no single association is generated for them.
5826
+ const generatedId = React.useId();
5827
+ const userWiredLabel = !!labelProps && 'htmlFor' in labelProps;
5828
+ const targetId = label && !userWiredLabel && !grouped && !hasAddons
5829
+ ? generatedId
5830
+ : undefined;
5805
5831
  let renderedLabel = null;
5806
5832
  if (label) {
5807
5833
  if (horizontal) {
5808
- renderedLabel = (jsxRuntime.jsx(FieldLabel, { size: effectiveLabelSize, children: jsxRuntime.jsx("label", { ...labelProps, className: classNames(labelClass, labelProps?.className), style: labelProps?.style, children: label }) }));
5834
+ renderedLabel = (jsxRuntime.jsx(FieldLabel, { size: effectiveLabelSize, children: jsxRuntime.jsx("label", { htmlFor: targetId, ...labelProps, className: classNames(labelClass, labelProps?.className), style: labelProps?.style, children: label }) }));
5809
5835
  }
5810
5836
  else {
5811
- renderedLabel = (jsxRuntime.jsx("label", { ...labelProps, className: classNames(labelClass, labelProps?.className), style: { display: 'block', ...(labelProps?.style || {}) }, children: label }));
5837
+ renderedLabel = (jsxRuntime.jsx("label", { htmlFor: targetId, ...labelProps, className: classNames(labelClass, labelProps?.className), style: { display: 'block', ...(labelProps?.style || {}) }, children: label }));
5812
5838
  }
5813
5839
  }
5814
5840
  // If horizontal, wrap children in FieldBody (unless the user already provided
@@ -5831,7 +5857,7 @@ const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSi
5831
5857
  content = jsxRuntime.jsx(FieldBody, { children: children });
5832
5858
  }
5833
5859
  }
5834
- return (jsxRuntime.jsx(FieldProvider, { value: true, children: jsxRuntime.jsxs("div", { className: fieldClass, ...rest, children: [renderedLabel, content] }) }));
5860
+ return (jsxRuntime.jsx(FieldProvider, { value: true, children: jsxRuntime.jsx(FieldLabelIdProvider, { value: targetId, children: jsxRuntime.jsxs("div", { className: fieldClass, ...rest, children: [renderedLabel, content] }) }) }));
5835
5861
  };
5836
5862
  FieldLabel.displayName = 'FieldLabel';
5837
5863
  FieldBody.displayName = 'FieldBody';
@@ -5845,18 +5871,28 @@ const Field = withSubComponents(FieldComponent, {
5845
5871
  * Associates the convenience `label` prop with its control (#368): generates
5846
5872
  * an id for the control and returns labelProps carrying a matching `htmlFor`.
5847
5873
  * A user-supplied `id` is used as the target instead of the generated one, and
5848
- * an explicit `labelProps.htmlFor` disables generation entirelythe user has
5849
- * taken over the association. Internal; not part of the public API.
5874
+ * an explicit `htmlFor` key in labelPropseven set to `undefined` — disables
5875
+ * generation entirely: the user has taken over the association (#495 presence
5876
+ * semantics). Internal; not part of the public API.
5850
5877
  */
5851
5878
  function useAutoLabelId({ label, id, labelProps, rendersLabel, }) {
5852
5879
  // Called unconditionally per the rules of hooks; SSR-safe on React 18 and 19.
5853
5880
  const generatedId = React.useId();
5854
5881
  // Truthiness mirrors Field's own `if (label)` render gate.
5855
5882
  const active = !!label && rendersLabel;
5856
- const controlId = id ?? (active && !labelProps?.htmlFor ? generatedId : undefined);
5883
+ // Presence, not truthiness: `htmlFor: undefined` is an explicit opt-out and
5884
+ // must not leave an orphan generated id on the control.
5885
+ const userWired = !!labelProps && 'htmlFor' in labelProps;
5886
+ const controlId = id ?? (active && !userWired ? generatedId : undefined);
5887
+ // Inactive with a label still means an own Field may render it (pickers'
5888
+ // inline mode, Taginput at maxTags) — the explicit `htmlFor: undefined`
5889
+ // tells Field the association is owned here, so it must not generate one
5890
+ // that would dangle (#495 presence semantics).
5857
5891
  const fieldLabelProps = active
5858
5892
  ? { htmlFor: controlId, ...labelProps }
5859
- : labelProps;
5893
+ : label
5894
+ ? { htmlFor: undefined, ...labelProps }
5895
+ : labelProps;
5860
5896
  return { controlId, fieldLabelProps };
5861
5897
  }
5862
5898
  /**
@@ -7668,6 +7704,7 @@ const InputBase = React.forwardRef(({ color, size, isRounded, isStatic, isHovere
7668
7704
  color,
7669
7705
  ...props,
7670
7706
  });
7707
+ const fieldLabelId = useFieldLabelId();
7671
7708
  const mainClass = usePrefixedClassNames('input', {
7672
7709
  [`is-${color}`]: !!color,
7673
7710
  [`is-${size}`]: !!size,
@@ -7678,7 +7715,10 @@ const InputBase = React.forwardRef(({ color, size, isRounded, isStatic, isHovere
7678
7715
  'is-loading': isLoading,
7679
7716
  });
7680
7717
  const inputClass = classNames(mainClass, bulmaHelperClasses, className);
7681
- return (jsxRuntime.jsx("input", { ref: ref, className: inputClass, disabled: disabled, readOnly: readOnly, ...rest }));
7718
+ return (jsxRuntime.jsx("input", { ref: ref, className: inputClass, disabled: disabled, readOnly: readOnly, ...rest,
7719
+ // After the spread: a labeled Field's generated id is adopted only
7720
+ // when no user id arrived (rest.id may be an undefined own key).
7721
+ id: rest.id ?? fieldLabelId }));
7682
7722
  });
7683
7723
  InputBase.displayName = 'InputBase';
7684
7724
 
@@ -7695,6 +7735,7 @@ const SelectBase = React.forwardRef(({ color, size, isRounded, isLoading, isActi
7695
7735
  color,
7696
7736
  ...props,
7697
7737
  });
7738
+ const fieldLabelId = useFieldLabelId();
7698
7739
  const mainClass = usePrefixedClassNames('select', {
7699
7740
  [`is-${color}`]: !!color,
7700
7741
  [`is-${size}`]: !!size,
@@ -7719,7 +7760,10 @@ const SelectBase = React.forwardRef(({ color, size, isRounded, isLoading, isActi
7719
7760
  if (multiple && typeof multipleSize === 'number') {
7720
7761
  selectProps.size = multipleSize;
7721
7762
  }
7722
- return (jsxRuntime.jsx("div", { className: selectClass, children: jsxRuntime.jsx("select", { ref: ref, className: innerSelectClass || undefined, ...selectProps, children: children }) }));
7763
+ return (jsxRuntime.jsx("div", { className: selectClass, children: jsxRuntime.jsx("select", { ref: ref, className: innerSelectClass || undefined, ...selectProps,
7764
+ // After the spread: a labeled Field's generated id is adopted only
7765
+ // when no user id arrived; the id belongs on the inner <select>.
7766
+ id: selectProps.id ?? fieldLabelId, children: children }) }));
7723
7767
  });
7724
7768
  SelectBase.displayName = 'SelectBase';
7725
7769
 
@@ -7736,6 +7780,7 @@ const TextAreaBase = React.forwardRef(({ color, size, isRounded, isStatic, isHov
7736
7780
  color,
7737
7781
  ...props,
7738
7782
  });
7783
+ const fieldLabelId = useFieldLabelId();
7739
7784
  // Note: `is-loading` is intentionally NOT applied to the <textarea> itself —
7740
7785
  // Bulma documents `<div class="control is-loading">` as the loading pattern
7741
7786
  // for textareas, not `<textarea class="textarea is-loading">`. The convenience
@@ -7751,7 +7796,10 @@ const TextAreaBase = React.forwardRef(({ color, size, isRounded, isStatic, isHov
7751
7796
  'has-fixed-size': hasFixedSize,
7752
7797
  });
7753
7798
  const textareaClass = classNames(mainClass, bulmaHelperClasses, className);
7754
- return (jsxRuntime.jsx("textarea", { ref: ref, className: textareaClass, disabled: disabled, readOnly: readOnly, rows: rows, ...rest }));
7799
+ return (jsxRuntime.jsx("textarea", { ref: ref, className: textareaClass, disabled: disabled, readOnly: readOnly, rows: rows, ...rest,
7800
+ // After the spread: a labeled Field's generated id is adopted only
7801
+ // when no user id arrived (rest.id may be an undefined own key).
7802
+ id: rest.id ?? fieldLabelId }));
7755
7803
  });
7756
7804
  TextAreaBase.displayName = 'TextAreaBase';
7757
7805