@allxsmith/bestax-bulma 5.27.7 → 5.27.8

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.
Files changed (40) hide show
  1. package/dist/esm/form/DateInputBase.js +2 -3
  2. package/dist/esm/form/DateInputBase.js.map +1 -1
  3. package/dist/esm/form/DateTimeInputBase.js +2 -3
  4. package/dist/esm/form/DateTimeInputBase.js.map +1 -1
  5. package/dist/esm/form/Field.js +36 -5
  6. package/dist/esm/form/Field.js.map +1 -1
  7. package/dist/esm/form/FormContext.js +53 -9
  8. package/dist/esm/form/FormContext.js.map +1 -1
  9. package/dist/esm/form/InputBase.js +6 -5
  10. package/dist/esm/form/InputBase.js.map +1 -1
  11. package/dist/esm/form/SelectBase.js +7 -5
  12. package/dist/esm/form/SelectBase.js.map +1 -1
  13. package/dist/esm/form/TextAreaBase.js +6 -5
  14. package/dist/esm/form/TextAreaBase.js.map +1 -1
  15. package/dist/esm/form/TimeInputBase.js +2 -3
  16. package/dist/esm/form/TimeInputBase.js.map +1 -1
  17. package/dist/esm/form/useAutoLabelId.js +8 -3
  18. package/dist/esm/form/useAutoLabelId.js.map +1 -1
  19. package/dist/esm/helpers/Theme.js +87 -17
  20. package/dist/esm/helpers/Theme.js.map +1 -1
  21. package/dist/esm/helpers/devWarnings.js +8 -3
  22. package/dist/esm/helpers/devWarnings.js.map +1 -1
  23. package/dist/esm/helpers/useFlexboxClasses.js +1 -1
  24. package/dist/esm/helpers/useOtherClasses.js +1 -1
  25. package/dist/esm/helpers/useSpacingClasses.js +1 -1
  26. package/dist/esm/helpers/useTypographyClasses.js +1 -1
  27. package/dist/esm/helpers/useVisibilityClasses.js +1 -1
  28. package/dist/index.cjs +202 -48
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/types/form/Field.d.ts +2 -2
  31. package/dist/types/form/FormContext.d.ts +47 -8
  32. package/dist/types/form/useAutoLabelId.d.ts +4 -2
  33. package/dist/types/helpers/Theme.d.ts +15 -1
  34. package/dist/types/helpers/devWarnings.d.ts +8 -0
  35. package/dist/types-cjs/form/Field.d.ts +2 -2
  36. package/dist/types-cjs/form/FormContext.d.ts +47 -8
  37. package/dist/types-cjs/form/useAutoLabelId.d.ts +4 -2
  38. package/dist/types-cjs/helpers/Theme.d.ts +15 -1
  39. package/dist/types-cjs/helpers/devWarnings.d.ts +8 -0
  40. package/package.json +18 -18
package/dist/index.cjs CHANGED
@@ -1444,8 +1444,13 @@ function isCustomElement(as) {
1444
1444
 
1445
1445
  // INTERNAL: deliberately not exported from src/index.ts.
1446
1446
  const warnedKeys = new Set();
1447
- // Fail closed: with no bundler and no Node (raw CDN ESM), reading `process`
1448
- // throws and warnings stay off, so production can never warn by accident.
1447
+ /**
1448
+ * Whether this is a development build. Fail closed: with no bundler and no
1449
+ * Node (raw CDN ESM), reading `process` throws and this is false, so
1450
+ * production can never warn by accident. Exported for a caller whose
1451
+ * development-only check costs something before it reaches `warnOnce`, so it
1452
+ * can skip that work in production too.
1453
+ */
1449
1454
  const isDev = () => {
1450
1455
  try {
1451
1456
  return process.env.NODE_ENV !== 'production';
@@ -9069,10 +9074,14 @@ const FieldLabelIdContext = React.createContext(undefined);
9069
9074
  * The id a labeled Field wants its single composed control to adopt (#495).
9070
9075
  * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the
9071
9076
  * user took over the association with an explicit `labelProps.htmlFor`.
9072
- * Consumed by the single-control bases (InputBase, SelectBase, TextAreaBase,
9073
- * and the date and time picker bases unless inline, #968) and, through
9074
- * `useAutoLabelId`, by the convenience inputs that render an input of their
9075
- * own (#939). Internal; not part of the public API.
9077
+ * Consumed through `useFieldLabelTarget` by the single-control bases
9078
+ * (InputBase, SelectBase, TextAreaBase, and the date and time picker bases
9079
+ * unless inline, #968) and, through `useAutoLabelId`, by the convenience
9080
+ * inputs that render an input of their own (#939). Read it only through
9081
+ * those, which report what they take: a control that read it directly would
9082
+ * report nothing and lose its label (#1004), and
9083
+ * `__tests__/field-label-readers.test.ts` fails on one. Internal; not part of
9084
+ * the public API.
9076
9085
  */
9077
9086
  const useFieldLabelId = () => React.useContext(FieldLabelIdContext);
9078
9087
  /** Provider for the Field label-target id — used internally by Field. */
@@ -9098,15 +9107,54 @@ const FieldLabelForContext = React.createContext({});
9098
9107
  * the outer label names it, and point at that label by its id, as a range
9099
9108
  * Slider's thumbs (#981) and Autocomplete's suggestion list (#998) do. The
9100
9109
  * `htmlFor` is only ever compared with a control's own id, never adopted, so
9101
- * it hands out no id for a control. The `id` is set only while that label
9102
- * renders with it. Unlike {@link useFieldLabelId}, it is set in a `grouped`
9103
- * or `hasAddons` Field too, so a label wired by hand names the control its
9104
- * `for` picks in those rows as well. Consumed through `useAutoLabelId`.
9110
+ * it hands out no id for a control. It keeps the generated id after the
9111
+ * label drops a `for` nothing took (#1004), which no control's id matches
9112
+ * then, so the value does not change under the content that reported it.
9113
+ * The `id` is set only while that label renders with it. Unlike
9114
+ * {@link useFieldLabelId}, it is set in a `grouped` or `hasAddons` Field
9115
+ * too, so a label wired by hand names the control its `for` picks in those
9116
+ * rows as well. Consumed through `useAutoLabelId`.
9105
9117
  * Internal; not part of the public API.
9106
9118
  */
9107
9119
  const useFieldLabelFor = () => React.useContext(FieldLabelForContext);
9108
9120
  /** Provider for the Field label's `htmlFor` target and id, used internally by Field. */
9109
9121
  const FieldLabelForProvider = FieldLabelForContext.Provider;
9122
+ const FieldLabelForReportContext = React.createContext(undefined);
9123
+ /**
9124
+ * Tells the nearest labeled Field that this content took its generated id
9125
+ * while `takesFor` is true (#1004). Once the Field's content has mounted, its
9126
+ * label keeps the generated `for` only while something has said so, so the
9127
+ * label renders none over a group, a `Checkbox`, `Radio` or `Switch`, an
9128
+ * inner `Field`, an input with an `id` of its own, markup of your own, or
9129
+ * nothing at all. Anything that puts the id from {@link useFieldLabelId} on
9130
+ * an element has to say so, or the label drops the `for` that names it, and
9131
+ * content that takes no id has nothing to do. Set under the same conditions
9132
+ * as {@link useFieldLabelId}, so a label wired by hand and a `grouped` or
9133
+ * `hasAddons` Field hear nothing. It reports from a layout effect, which a
9134
+ * server never runs and a hydrating client runs only after its first render,
9135
+ * so that render writes the `for` the way the server did.
9136
+ * Internal; not part of the public API.
9137
+ */
9138
+ const useReportFieldLabelFor = (takesFor) => {
9139
+ const report = React.useContext(FieldLabelForReportContext);
9140
+ useClientLayoutEffect(() => (takesFor ? report?.() : undefined), [report, takesFor]);
9141
+ };
9142
+ /** Provider for the labeled Field's report function, used internally by Field. */
9143
+ const FieldLabelForReportProvider = FieldLabelForReportContext.Provider;
9144
+ /**
9145
+ * The id a control with one input of its own renders with: the caller's
9146
+ * `id` when one arrived, otherwise the one a labeled Field offers (#495),
9147
+ * unless it has no input to put it on (`hasInput: false`, as in an `inline`
9148
+ * picker). It also tells that Field when it took the Field's id, through
9149
+ * {@link useReportFieldLabelFor}, so the label keeps its `for` (#1004). Used
9150
+ * by the single-control bases. Internal; not part of the public API.
9151
+ */
9152
+ const useFieldLabelTarget = (id, hasInput = true) => {
9153
+ const fieldLabelId = useFieldLabelId();
9154
+ const target = id ?? (hasInput ? fieldLabelId : undefined);
9155
+ useReportFieldLabelFor(fieldLabelId !== undefined && target === fieldLabelId);
9156
+ return target;
9157
+ };
9110
9158
  const RadiosContext = React.createContext(undefined);
9111
9159
  const CheckboxesContext = React.createContext(undefined);
9112
9160
  /**
@@ -9438,13 +9486,43 @@ const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSi
9438
9486
  const labelForTarget = userWiredLabel ? labelProps.htmlFor : targetId;
9439
9487
  const ownLabelFor = React.useMemo(() => ({ htmlFor: labelForTarget, id: labelId }), [labelForTarget, labelId]);
9440
9488
  const labelFor = label ? ownLabelFor : inheritedLabelFor;
9489
+ // Whether the label keeps its generated `for` (#1004). Content that takes
9490
+ // the Field's id says so from a layout effect, and this Field's own layout
9491
+ // effect runs after its content's in the same commit, so by then every
9492
+ // report has landed. Until it runs, on the server and in the first render
9493
+ // while hydrating, the label writes the `for` as it always has. From then
9494
+ // on it keeps the `for` only while some content holds the id, and content
9495
+ // that mounts or changes later reports when it does. Counted in a ref, and
9496
+ // state is set only once settled, so content that takes the id renders
9497
+ // the Field just once.
9498
+ const takersRef = React.useRef(0);
9499
+ const settledRef = React.useRef(false);
9500
+ const [forTaken, setForTaken] = React.useState(true);
9501
+ const settle = React.useCallback(() => {
9502
+ if (settledRef.current)
9503
+ setForTaken(takersRef.current > 0);
9504
+ }, []);
9505
+ const reportLabelFor = React.useCallback(() => {
9506
+ takersRef.current += 1;
9507
+ settle();
9508
+ return () => {
9509
+ takersRef.current -= 1;
9510
+ settle();
9511
+ };
9512
+ }, [settle]);
9513
+ useClientLayoutEffect(() => {
9514
+ settledRef.current = true;
9515
+ if (targetId)
9516
+ settle();
9517
+ }, [targetId, settle]);
9518
+ const renderedTargetId = forTaken ? targetId : undefined;
9441
9519
  let renderedLabel = null;
9442
9520
  if (label) {
9443
9521
  if (horizontal) {
9444
- renderedLabel = (jsxRuntime.jsx(FieldLabel, { size: effectiveLabelSize, children: jsxRuntime.jsx("label", { htmlFor: targetId, ...labelProps, id: labelId, className: classNames(labelClass, labelProps?.className), style: labelProps?.style, children: label }) }));
9522
+ renderedLabel = (jsxRuntime.jsx(FieldLabel, { size: effectiveLabelSize, children: jsxRuntime.jsx("label", { htmlFor: renderedTargetId, ...labelProps, id: labelId, className: classNames(labelClass, labelProps?.className), style: labelProps?.style, children: label }) }));
9445
9523
  }
9446
9524
  else {
9447
- renderedLabel = (jsxRuntime.jsx("label", { htmlFor: targetId, ...labelProps, id: labelId, className: classNames(labelClass, labelProps?.className), style: { display: 'block', ...(labelProps?.style || {}) }, children: label }));
9525
+ renderedLabel = (jsxRuntime.jsx("label", { htmlFor: renderedTargetId, ...labelProps, id: labelId, className: classNames(labelClass, labelProps?.className), style: { display: 'block', ...(labelProps?.style || {}) }, children: label }));
9448
9526
  }
9449
9527
  }
9450
9528
  // If horizontal, wrap children in FieldBody (unless the user already provided
@@ -9467,7 +9545,7 @@ const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSi
9467
9545
  content = jsxRuntime.jsx(FieldBody, { children: children });
9468
9546
  }
9469
9547
  }
9470
- return (jsxRuntime.jsx(FieldProvider, { value: true, children: jsxRuntime.jsx(FieldLabelIdProvider, { value: targetId, children: jsxRuntime.jsx(FieldLabelElementIdProvider, { value: targetId ? labelId : undefined, children: jsxRuntime.jsx(FieldLabelForProvider, { value: labelFor, children: jsxRuntime.jsxs("div", { className: fieldClass, ...rest, children: [renderedLabel, content] }) }) }) }) }));
9548
+ return (jsxRuntime.jsx(FieldProvider, { value: true, children: jsxRuntime.jsx(FieldLabelIdProvider, { value: targetId, children: jsxRuntime.jsx(FieldLabelElementIdProvider, { value: targetId ? labelId : undefined, children: jsxRuntime.jsx(FieldLabelForProvider, { value: labelFor, children: jsxRuntime.jsx(FieldLabelForReportProvider, { value: targetId ? reportLabelFor : undefined, children: jsxRuntime.jsxs("div", { className: fieldClass, ...rest, children: [renderedLabel, content] }) }) }) }) }) }));
9471
9549
  };
9472
9550
  FieldLabel.displayName = 'FieldLabel';
9473
9551
  FieldBody.displayName = 'FieldBody';
@@ -9485,8 +9563,10 @@ const Field = withSubComponents(FieldComponent, {
9485
9563
  * generation entirely: the user has taken over the association (#495 presence
9486
9564
  * semantics). When the control renders no label of its own, it adopts the id
9487
9565
  * a labeled Field around it offers, the way the bases do, so that Field's
9488
- * label names it (#939); a user `id` still wins there. With `needsLabelId`
9489
- * it also returns the id of whichever label names the control (#981).
9566
+ * label names it (#939); a user `id` still wins there. It tells that Field
9567
+ * when the control took its id, since the Field's label drops a `for`
9568
+ * nothing took (#1004). With `needsLabelId` it also returns the id of
9569
+ * whichever label names the control (#981).
9490
9570
  * Internal; not part of the public API.
9491
9571
  */
9492
9572
  function useAutoLabelId({ label, id, labelProps, rendersLabel, hasInput = true, needsLabelId = false, }) {
@@ -9507,6 +9587,9 @@ function useAutoLabelId({ label, id, labelProps, rendersLabel, hasInput = true,
9507
9587
  const userWired = !!labelProps && 'htmlFor' in labelProps;
9508
9588
  const adopted = !active && hasInput ? fieldLabelId : undefined;
9509
9589
  const controlId = id ?? (active && !userWired ? generatedId : adopted);
9590
+ // Tells a labeled Field around the control when its label's `for` names
9591
+ // the control, since it drops a `for` nothing took (#1004).
9592
+ useReportFieldLabelFor(fieldLabelId !== undefined && controlId === fieldLabelId);
9510
9593
  const ownLabelProps = { htmlFor: controlId, ...labelProps };
9511
9594
  const labelTarget = active ? ownLabelProps.htmlFor : fieldLabelFor.htmlFor;
9512
9595
  const labelled = !!controlId && labelTarget === controlId;
@@ -11569,7 +11652,9 @@ const InputBase = React.forwardRef(({ color, size, isRounded, isStatic, isHovere
11569
11652
  color,
11570
11653
  ...props,
11571
11654
  });
11572
- const fieldLabelId = useFieldLabelId();
11655
+ // A labeled Field's generated id when no user id arrived (rest.id may be
11656
+ // an undefined own key), reported to that Field (#1004).
11657
+ const id = useFieldLabelTarget(rest.id);
11573
11658
  const mainClass = usePrefixedClassNames('input', {
11574
11659
  [`is-${color}`]: !!color,
11575
11660
  [`is-${size}`]: !!size,
@@ -11581,9 +11666,8 @@ const InputBase = React.forwardRef(({ color, size, isRounded, isStatic, isHovere
11581
11666
  });
11582
11667
  const inputClass = classNames(mainClass, bulmaHelperClasses, className);
11583
11668
  return (jsxRuntime.jsx("input", { ref: ref, className: inputClass, disabled: disabled, readOnly: readOnly, ...rest,
11584
- // After the spread: a labeled Field's generated id is adopted only
11585
- // when no user id arrived (rest.id may be an undefined own key).
11586
- id: rest.id ?? fieldLabelId }));
11669
+ // After the spread, which may carry an undefined id key.
11670
+ id: id }));
11587
11671
  });
11588
11672
  InputBase.displayName = 'InputBase';
11589
11673
 
@@ -11600,7 +11684,9 @@ const SelectBase = React.forwardRef(({ color, size, isRounded, isLoading, isActi
11600
11684
  color,
11601
11685
  ...props,
11602
11686
  });
11603
- const fieldLabelId = useFieldLabelId();
11687
+ // A labeled Field's generated id when no user id arrived (rest.id may be
11688
+ // an undefined own key), reported to that Field (#1004).
11689
+ const id = useFieldLabelTarget(rest.id);
11604
11690
  const mainClass = usePrefixedClassNames('select', {
11605
11691
  [`is-${color}`]: !!color,
11606
11692
  [`is-${size}`]: !!size,
@@ -11626,9 +11712,9 @@ const SelectBase = React.forwardRef(({ color, size, isRounded, isLoading, isActi
11626
11712
  selectProps.size = multipleSize;
11627
11713
  }
11628
11714
  return (jsxRuntime.jsx("div", { className: selectClass, children: jsxRuntime.jsx("select", { ref: ref, className: innerSelectClass || undefined, ...selectProps,
11629
- // After the spread: a labeled Field's generated id is adopted only
11630
- // when no user id arrived; the id belongs on the inner <select>.
11631
- id: selectProps.id ?? fieldLabelId, children: children }) }));
11715
+ // After the spread, which may carry an undefined id key; the id
11716
+ // belongs on the inner <select>.
11717
+ id: id, children: children }) }));
11632
11718
  });
11633
11719
  SelectBase.displayName = 'SelectBase';
11634
11720
 
@@ -11645,7 +11731,9 @@ const TextAreaBase = React.forwardRef(({ color, size, isRounded, isStatic, isHov
11645
11731
  color,
11646
11732
  ...props,
11647
11733
  });
11648
- const fieldLabelId = useFieldLabelId();
11734
+ // A labeled Field's generated id when no user id arrived (rest.id may be
11735
+ // an undefined own key), reported to that Field (#1004).
11736
+ const id = useFieldLabelTarget(rest.id);
11649
11737
  // Note: `is-loading` is intentionally NOT applied to the <textarea> itself —
11650
11738
  // Bulma documents `<div class="control is-loading">` as the loading pattern
11651
11739
  // for textareas, not `<textarea class="textarea is-loading">`. The convenience
@@ -11662,9 +11750,8 @@ const TextAreaBase = React.forwardRef(({ color, size, isRounded, isStatic, isHov
11662
11750
  });
11663
11751
  const textareaClass = classNames(mainClass, bulmaHelperClasses, className);
11664
11752
  return (jsxRuntime.jsx("textarea", { ref: ref, className: textareaClass, disabled: disabled, readOnly: readOnly, rows: rows, ...rest,
11665
- // After the spread: a labeled Field's generated id is adopted only
11666
- // when no user id arrived (rest.id may be an undefined own key).
11667
- id: rest.id ?? fieldLabelId }));
11753
+ // After the spread, which may carry an undefined id key.
11754
+ id: id }));
11668
11755
  });
11669
11756
  TextAreaBase.displayName = 'TextAreaBase';
11670
11757
 
@@ -14159,8 +14246,7 @@ const DateInputBase = React.forwardRef((props, ref) => {
14159
14246
  // when the caller set none, as InputBase does, and the popover's ids
14160
14247
  // follow it. Inline there is no input to name, so nothing takes the
14161
14248
  // Field's id or builds on it.
14162
- const fieldLabelId = useFieldLabelId();
14163
- const id = idProp ?? (inline ? undefined : fieldLabelId);
14249
+ const id = useFieldLabelTarget(idProp, !inline);
14164
14250
  // The launcher gives way to the loading spinner of a Control this sits in.
14165
14251
  const controlLoading = useControlLoading();
14166
14252
  const triggerIcon = triggerIconProp ?? !controlLoading;
@@ -15341,8 +15427,7 @@ const TimeInputBase = React.forwardRef((props, ref) => {
15341
15427
  // when the caller set none, as InputBase does, and the popover's ids
15342
15428
  // follow it. Inline there is no input to name, so nothing takes the
15343
15429
  // Field's id or builds on it.
15344
- const fieldLabelId = useFieldLabelId();
15345
- const id = idProp ?? (inline ? undefined : fieldLabelId);
15430
+ const id = useFieldLabelTarget(idProp, !inline);
15346
15431
  // The launcher gives way to the loading spinner of a Control this sits in.
15347
15432
  const controlLoading = useControlLoading();
15348
15433
  const triggerIcon = triggerIconProp ?? !controlLoading;
@@ -15659,8 +15744,7 @@ const DateTimeInputBase = React.forwardRef((props, ref) => {
15659
15744
  // when the caller set none, as InputBase does, and the popover's ids
15660
15745
  // follow it. Inline there is no input to name, so nothing takes the
15661
15746
  // Field's id or builds on it.
15662
- const fieldLabelId = useFieldLabelId();
15663
- const id = idProp ?? (inline ? undefined : fieldLabelId);
15747
+ const id = useFieldLabelTarget(idProp, !inline);
15664
15748
  // The launcher gives way to the loading spinner of a Control this sits in.
15665
15749
  const controlLoading = useControlLoading();
15666
15750
  const triggerIcon = triggerIconProp ?? !controlLoading;
@@ -16444,8 +16528,15 @@ const GridComponent = ({ isFixed = false, gap, columnGap, rowGap, minCol, fixedC
16444
16528
  };
16445
16529
  const Grid = withSubComponents(GridComponent, { Cell }, 'Grid');
16446
16530
 
16447
- // --- FULL Bulma v1 CSS variable keys (auto-generated from CSSVAR_KEYS) ---
16448
- const bulmaCssVars = [
16531
+ // --- Bulma v1 CSS variables Theme sets (originally generated from
16532
+ // CSSVAR_KEYS), in two lists by where Bulma declares them ---
16533
+ /**
16534
+ * Variables a value set on an ancestor reaches. Bulma declares them on
16535
+ * `:root` (or a theme scope), or on no component in its plain state, so the
16536
+ * value Theme writes on its wrapper or at `:root` is the one the components
16537
+ * under it use.
16538
+ */
16539
+ const bulmaGlobalVars = [
16449
16540
  // scheme
16450
16541
  '--bulma-scheme-h',
16451
16542
  '--bulma-scheme-s',
@@ -16562,6 +16653,36 @@ const bulmaCssVars = [
16562
16653
  '--bulma-skeleton-block-min-height',
16563
16654
  '--bulma-skeleton-lines-gap',
16564
16655
  '--bulma-skeleton-line-height',
16656
+ // control
16657
+ '--bulma-control-radius',
16658
+ '--bulma-control-radius-small',
16659
+ '--bulma-control-border-width',
16660
+ '--bulma-control-height',
16661
+ '--bulma-control-line-height',
16662
+ '--bulma-control-padding-vertical',
16663
+ '--bulma-control-padding-horizontal',
16664
+ '--bulma-control-size',
16665
+ '--bulma-control-focus-shadow-l',
16666
+ // columns
16667
+ '--bulma-column-gap',
16668
+ // grid
16669
+ '--bulma-grid-cell-column-start',
16670
+ ];
16671
+ /**
16672
+ * Variables Bulma declares on the component's own element, such as
16673
+ * `--bulma-card-radius` on `.card`. An element that declares a variable uses
16674
+ * its own value whatever its ancestors set, so a value Theme writes for one
16675
+ * of these, on its wrapper or at `:root`, never reaches the component.
16676
+ *
16677
+ * They stay in `BulmaVars`, and so stay valid `bulmaVars` keys and variable
16678
+ * props, because taking a key out would be a breaking change. Setting one
16679
+ * warns in development instead; see `warnComponentVars`.
16680
+ *
16681
+ * `scripts/css-var-scopes.test.mjs` holds this split to Bulma's compiled
16682
+ * stylesheet in both directions, so a Bulma upgrade that moves a variable
16683
+ * fails there.
16684
+ */
16685
+ const bulmaComponentVars = [
16565
16686
  // breadcrumb
16566
16687
  '--bulma-breadcrumb-item-color',
16567
16688
  '--bulma-breadcrumb-item-hover-color',
@@ -16911,16 +17032,6 @@ const bulmaCssVars = [
16911
17032
  '--bulma-subtitle-line-height',
16912
17033
  '--bulma-subtitle-strong-color',
16913
17034
  '--bulma-subtitle-strong-weight',
16914
- // control
16915
- '--bulma-control-radius',
16916
- '--bulma-control-radius-small',
16917
- '--bulma-control-border-width',
16918
- '--bulma-control-height',
16919
- '--bulma-control-line-height',
16920
- '--bulma-control-padding-vertical',
16921
- '--bulma-control-padding-horizontal',
16922
- '--bulma-control-size',
16923
- '--bulma-control-focus-shadow-l',
16924
17035
  // file
16925
17036
  '--bulma-file-radius',
16926
17037
  '--bulma-file-name-border-color',
@@ -16971,14 +17082,11 @@ const bulmaCssVars = [
16971
17082
  '--bulma-input-icon-hover-color',
16972
17083
  '--bulma-input-icon-focus-color',
16973
17084
  '--bulma-input-radius',
16974
- // columns
16975
- '--bulma-column-gap',
16976
17085
  // grid
16977
17086
  '--bulma-grid-gap',
16978
17087
  '--bulma-grid-column-count',
16979
17088
  '--bulma-grid-column-min',
16980
17089
  '--bulma-grid-cell-column-span',
16981
- '--bulma-grid-cell-column-start',
16982
17090
  // footer
16983
17091
  '--bulma-footer-background-color',
16984
17092
  '--bulma-footer-color',
@@ -17004,6 +17112,8 @@ const bulmaCssVars = [
17004
17112
  '--bulma-section-padding-medium',
17005
17113
  '--bulma-section-padding-large',
17006
17114
  ];
17115
+ /** Every Bulma CSS variable Theme accepts: the two lists above. */
17116
+ const bulmaCssVars = [...bulmaGlobalVars, ...bulmaComponentVars];
17007
17117
  /**
17008
17118
  * Convert a Bulma CSS variable name to a camelCase prop name.
17009
17119
  * @param {string} varName - CSS variable name (e.g., '--bulma-primary-h').
@@ -17122,6 +17232,44 @@ const themeColumnGapVar = (columnGap) => {
17122
17232
  `bulmaVars={{ '--bulma-column-gap': '${columnGap}' }} instead.`);
17123
17233
  return columnGap;
17124
17234
  };
17235
+ /**
17236
+ * `bulmaComponentVars` as a lookup, built by `warnComponentVars` the first
17237
+ * time it is needed.
17238
+ */
17239
+ let componentVarKeys;
17240
+ /**
17241
+ * Warn in development when a Theme is given variables Bulma declares on the
17242
+ * component itself (`bulmaComponentVars`), whether through `bulmaVars` or a
17243
+ * variable prop such as `cardRadius`. Theme writes them where they can never
17244
+ * win, so nothing changes on the page, and saying so is the only way to find
17245
+ * out short of reading Bulma's stylesheet.
17246
+ *
17247
+ * Keyed by the set of variables, so a Theme that keeps passing the same ones
17248
+ * warns once, and a different set warns again. An empty value writes nothing,
17249
+ * so it is not reported.
17250
+ *
17251
+ * All of this is development-only, so it returns before doing anything in
17252
+ * production, and it builds its lookup on the first development call rather
17253
+ * than when the module loads.
17254
+ */
17255
+ const warnComponentVars = (vars) => {
17256
+ if (!isDev()) {
17257
+ return;
17258
+ }
17259
+ const keys = (componentVarKeys ?? (componentVarKeys = new Set(bulmaComponentVars)));
17260
+ const inert = Object.entries(vars)
17261
+ .filter(([key, value]) => value && keys.has(key))
17262
+ .map(([key]) => key)
17263
+ .sort();
17264
+ if (inert.length === 0) {
17265
+ return;
17266
+ }
17267
+ const one = inert.length === 1;
17268
+ warnOnce(`Theme:component-vars:${inert.join(',')}`, `[bestax-bulma] <Theme>: Bulma declares ${inert.join(', ')} on the ` +
17269
+ `component itself, so a value set on Theme never reaches ` +
17270
+ `${one ? 'it' : 'them'}. Set ${one ? 'it' : 'them'} on that ` +
17271
+ 'component instead, with className or style, or through Sass.');
17272
+ };
17125
17273
  /** The one `<style>` element every `isRoot` Theme writes into. */
17126
17274
  const ROOT_STYLE_ID = 'bestax-bulma-theme-vars';
17127
17275
  /**
@@ -17283,6 +17431,12 @@ const Theme = ({ bulmaVars = {}, children, className, isRoot = false, colorMode,
17283
17431
  }
17284
17432
  return vars;
17285
17433
  }, [bulmaVars, bulmaVarProps, radiusVar, columnGapVar]);
17434
+ // From an effect rather than the render body, so rendering does none of
17435
+ // this work, and a server render none at all. In production it returns
17436
+ // at its development check before looking at the variables.
17437
+ React.useEffect(() => {
17438
+ warnComponentVars(mergedVars);
17439
+ }, [mergedVars]);
17286
17440
  // This Theme's place among root Themes; see `rootThemeRules`.
17287
17441
  const [rootOrder] = React.useState(() => nextRootOrder++);
17288
17442
  // The `:root` rules this Theme contributes, or '' when it contributes none.