@allxsmith/bestax-bulma 5.16.8 → 5.16.10

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 CHANGED
@@ -1281,6 +1281,22 @@ const avatarSizes = [
1281
1281
  '96x96',
1282
1282
  '128x128',
1283
1283
  ];
1284
+ /**
1285
+ * The roles a caller can use to say "this avatar is not a control", and so claim
1286
+ * the non-interactive treatment for a custom `as` target we would otherwise have
1287
+ * to guess about.
1288
+ *
1289
+ * Read by VALUE, not by presence. Any role at all used to count, which let
1290
+ * `role="button"` — a claim of the opposite — route a real control into the
1291
+ * decorative branch and come out `aria-hidden` and nameless. `img` is what the
1292
+ * fallback itself applies; `presentation` and `none` are the standard ways to say
1293
+ * an element carries no semantics, which is what pairs with `alt=""`.
1294
+ */
1295
+ const NON_INTERACTIVE_ROLES = [
1296
+ 'img',
1297
+ 'presentation',
1298
+ 'none',
1299
+ ];
1284
1300
  /**
1285
1301
  * Derives a small set of initials from a name (e.g. "Ada Lovelace" -> "AL").
1286
1302
  */
@@ -1375,13 +1391,44 @@ const Avatar = React.forwardRef(function Avatar(avatarProps, ref) {
1375
1391
  const combinedClasses = classNames(avatarClasses, bulmaHelperClasses, className);
1376
1392
  const initialsClass = usePrefixedClassNames('avatar-initials');
1377
1393
  const Tag = as ?? (href ? 'a' : 'figure');
1378
- // A custom `as` component given an href is being used as a link — the same
1379
- // condition under which isLinkLike forwards href/target/rel below — so it
1380
- // counts as interactive too. Otherwise alt="" would mark a real link
1381
- // decorative (aria-hidden) and it could render nameless.
1394
+ // A custom component counts as interactive whether or not it was given OUR
1395
+ // href: a router link takes `to`, creates the anchor itself, and cannot be
1396
+ // classified from the props it arrives with (#668). Marking a real link as a
1397
+ // picture is the worse failure — and `alt=""` would go further and mark it
1398
+ // decorative (aria-hidden), leaving it nameless.
1399
+ //
1400
+ // A custom ELEMENT still needs the href. A hyphenated tag renders a real DOM
1401
+ // element of that name, so nothing is hidden from us: without a link to follow
1402
+ // it is still a picture. `Navbar.Link` draws the same line for `role="button"`.
1403
+ //
1404
+ // Where we are guessing, the caller settles it: an explicit `role` or
1405
+ // `aria-hidden` states the semantics, so a custom component that really is a
1406
+ // wrapper gets `role="img"` and its `alt=""` opt-out back. `role` alone would
1407
+ // be a half-override — interactivity also drives the decorative opt-out and the
1408
+ // name fallback, and overriding one of the three is worse than overriding none.
1409
+ //
1410
+ // An `href` ENDS the guess, so it outranks the signal. `as="a"`, `as="button"`
1411
+ // and a target we were handed an href for are known to be interactive, and there
1412
+ // the rule that an interactive element always carries an accessible name is not
1413
+ // the caller's to waive: without this, `as={RouterLink} href="/x" role="img"`
1414
+ // with `alt=""` rendered a real anchor as `aria-hidden` and nameless — the very
1415
+ // failure #668 is about. `Navbar.Link` orders the same two the same way.
1416
+ //
1417
+ // The signal has to MEAN what it is used for, so both halves read a value rather
1418
+ // than a presence — the way `Navbar.Link` reads `role === 'button'`. A role only
1419
+ // claims to be a picture if it says so: `role="button"` or `role="link"` is the
1420
+ // opposite claim, and taking any role as the signal handed an interactive-role
1421
+ // element `aria-hidden` and no name. Likewise `aria-hidden={false}` denies
1422
+ // hiding, so only a truthy one counts.
1423
+ const ariaHidden = rest['aria-hidden'];
1424
+ const statesItIsNotAControl = (rest.role !== undefined && NON_INTERACTIVE_ROLES.includes(rest.role)) ||
1425
+ ariaHidden === true ||
1426
+ ariaHidden === 'true';
1427
+ const customTargetStatesSemantics = typeof Tag !== 'string' && href == null && statesItIsNotAControl;
1382
1428
  const isInteractive = Tag === 'a' ||
1383
1429
  Tag === 'button' ||
1384
- ((typeof Tag !== 'string' || isCustomElement(Tag)) && href != null);
1430
+ (typeof Tag !== 'string' && !customTargetStatesSemantics) ||
1431
+ (isCustomElement(Tag) && href != null);
1385
1432
  // Only forward link attributes when rendering an anchor or a custom (non-DOM)
1386
1433
  // component; a plain `as="div"` must not receive a stray `href`/`target`/`rel`.
1387
1434
  const isLinkLike = Tag === 'a' || typeof Tag !== 'string' || isCustomElement(Tag);
@@ -1643,18 +1690,6 @@ const Breadcrumb = ({ className, alignment, separator, size, children, ...props
1643
1690
  */
1644
1691
  const mergeBulmaStyles = (helperStyles, style) => helperStyles || style ? { ...helperStyles, ...style } : undefined;
1645
1692
 
1646
- /**
1647
- * Wrap each footer item in a `.card-footer-item` span.
1648
- * @param {CardProps['footer']} footer - Footer content (single node or array).
1649
- * @param {string | undefined} classPrefix - Bulma class prefix.
1650
- * @returns {React.ReactNode[] | null} Wrapped footer items, or null if no footer.
1651
- */
1652
- const renderFooter = (footer, classPrefix) => {
1653
- if (!footer)
1654
- return null;
1655
- const items = Array.isArray(footer) ? footer : [footer];
1656
- return items.map((item, idx) => (jsxRuntime.jsx("span", { className: prefixedClassNames(classPrefix, 'card-footer-item'), children: item }, idx)));
1657
- };
1658
1693
  /**
1659
1694
  * Check if children contain any Card compound sub-components.
1660
1695
  * @param {React.ReactNode} children - The children to inspect.
@@ -1702,6 +1737,9 @@ const CardComponent = ({ className, children, textColor, color, bgColor, hasShad
1702
1737
  'is-centered': headerCentered,
1703
1738
  }), children: header })), headerIcon] }));
1704
1739
  };
1740
+ // Any falsy footer (including `0`) and an empty array render no footer bar,
1741
+ // rather than a stray `0` or an empty `.card-footer`.
1742
+ const hasFooter = Array.isArray(footer) ? footer.length > 0 : Boolean(footer);
1705
1743
  return (jsxRuntime.jsxs("div", { className: cardClasses, style: mergeBulmaStyles(bulmaHelperStyles, style), ...rest, children: [renderHeader(header, headerIcon, headerCentered, classPrefix), image && (jsxRuntime.jsx("div", { className: prefixedClassNames(classPrefix, 'card-image'), children: typeof image === 'string' ? (jsxRuntime.jsx("figure", { className: prefixedClassNames(classPrefix, 'image'), children: jsxRuntime.jsx("img", { src: image, alt: imageAlt ?? 'Card image' }) })) : (image) })), typeof children !== 'undefined' &&
1706
1744
  children !== null &&
1707
1745
  children !== '' &&
@@ -1709,9 +1747,7 @@ const CardComponent = ({ className, children, textColor, color, bgColor, hasShad
1709
1747
  children !== null &&
1710
1748
  children !== '' &&
1711
1749
  hasCompoundComponents(children) &&
1712
- children, footer && (jsxRuntime.jsx("footer", { className: prefixedClassNames(classPrefix, 'card-footer'), children: Array.isArray(footer)
1713
- ? footer.map((item, idx) => (jsxRuntime.jsx("span", { className: prefixedClassNames(classPrefix, 'card-footer-item'), children: item }, idx)))
1714
- : footer && (jsxRuntime.jsx("span", { className: prefixedClassNames(classPrefix, 'card-footer-item'), children: footer })) }))] }));
1750
+ children, hasFooter && (jsxRuntime.jsx("footer", { className: prefixedClassNames(classPrefix, 'card-footer'), children: Array.isArray(footer) ? (footer.map((item, idx) => (jsxRuntime.jsx("span", { className: prefixedClassNames(classPrefix, 'card-footer-item'), children: item }, idx)))) : (jsxRuntime.jsx("span", { className: prefixedClassNames(classPrefix, 'card-footer-item'), children: footer })) }))] }));
1715
1751
  };
1716
1752
  /**
1717
1753
  * Card header compound component. Wraps children in a `.card-header` element.
@@ -1841,8 +1877,6 @@ const Card = withSubComponents(CardComponent, {
1841
1877
  Footer: CardFooter,
1842
1878
  FooterItem: CardFooterItem,
1843
1879
  }, 'Card');
1844
- /** Internal test-only exports. Not part of the public API. */
1845
- const __test_exports__ = { renderFooter };
1846
1880
 
1847
1881
  /**
1848
1882
  * The runtime mirror of `AnchorOnlyAttributes`, keyed so the two cannot drift.
@@ -1915,6 +1949,9 @@ function omitAttrs(props, strip) {
1915
1949
 
1916
1950
  /**
1917
1951
  * Checks if code is running in a browser environment.
1952
+ * @deprecated Dropdown's internal SSR guard, exported by accident; it will
1953
+ * be removed in the next major. Check `typeof window !== 'undefined' &&
1954
+ * typeof document !== 'undefined'` instead.
1918
1955
  * @param win - Window object.
1919
1956
  * @param doc - Document object.
1920
1957
  * @returns {boolean} True if in browser, false otherwise.
@@ -2017,7 +2054,10 @@ const DropdownComponent = React.forwardRef(function DropdownComponent({ label, c
2017
2054
  /* istanbul ignore next: dropdownRef.current is never null once mounted */
2018
2055
  if (!dropdownRef.current)
2019
2056
  return [];
2020
- return Array.from(dropdownRef.current.querySelectorAll('[role="menuitem"]')).filter(el => !el.hasAttribute('disabled') &&
2057
+ return Array.from(
2058
+ // Every menu-item role, so an item a caller gives `menuitemcheckbox`
2059
+ // or `menuitemradio` (a filter or sort menu) stays reachable.
2060
+ dropdownRef.current.querySelectorAll('[role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"]')).filter(el => !el.hasAttribute('disabled') &&
2021
2061
  el.getAttribute('aria-disabled') !== 'true');
2022
2062
  };
2023
2063
  // Focus the pending menu item once the menu becomes visible; the item is
@@ -2185,7 +2225,11 @@ const DropdownItem = ((itemProps) => {
2185
2225
  const forwarded = Component === 'a' ? rest : omitAttrs(rest, STRIP_FROM_NON_ANCHOR$1);
2186
2226
  return (jsxRuntime.jsx(Component, { className: classNames(usePrefixedClassNames('dropdown-item', {
2187
2227
  'is-active': active,
2188
- }), bulmaHelperClasses, className), tabIndex: 0, role: "menuitem", "data-testid": "dropdown-item", ...forwarded, ...(Component === 'button'
2228
+ }), bulmaHelperClasses, className), tabIndex: 0, "data-testid": "dropdown-item", ...forwarded,
2229
+ // After `forwarded` for the same reason as `type` below: a spread
2230
+ // carrying `role: undefined` would otherwise erase the default, and an
2231
+ // item with no role drops out of the menu and its arrow-key order.
2232
+ role: forwarded.role ?? 'menuitem', ...(Component === 'button'
2189
2233
  ? {
2190
2234
  type: forwarded.type ?? 'button',
2191
2235
  }
@@ -2840,7 +2884,7 @@ const NavbarBurger = React.forwardRef(function NavbarBurger({ className, active,
2840
2884
  });
2841
2885
  return (jsxRuntime.jsxs("button", { ref: ref, type: "button", className: classNames(usePrefixedClassNames('navbar-burger', {
2842
2886
  'is-active': active,
2843
- }), bulmaHelperClasses, className), "aria-label": props['aria-label'] || 'menu', "aria-expanded": props['aria-expanded'] ?? !!active, ...rest, children: [jsxRuntime.jsx("span", { "aria-hidden": "true" }), jsxRuntime.jsx("span", { "aria-hidden": "true" }), jsxRuntime.jsx("span", { "aria-hidden": "true" }), children] }));
2887
+ }), bulmaHelperClasses, className), "aria-label": props['aria-label'] || 'menu', "aria-expanded": props['aria-expanded'] ?? !!active, ...rest, children: [jsxRuntime.jsx("span", { "aria-hidden": "true" }), jsxRuntime.jsx("span", { "aria-hidden": "true" }), jsxRuntime.jsx("span", { "aria-hidden": "true" }), jsxRuntime.jsx("span", { "aria-hidden": "true" }), children] }));
2844
2888
  });
2845
2889
  NavbarBurger.displayName = 'NavbarBurger';
2846
2890
  /**
@@ -2901,7 +2945,27 @@ const NavbarLink = React.forwardRef(function NavbarLink(linkProps, ref) {
2901
2945
  });
2902
2946
  const dropdownContext = React.useContext(NavbarDropdownContext);
2903
2947
  const hasHref = rest.href !== undefined;
2904
- const isNativeInteractive = Component === 'button' || hasHref;
2948
+ // What a custom component renders cannot be read off its input props, and the
2949
+ // prop that ends in an anchor belongs to the router, not to us — `to`, `state`,
2950
+ // `params` and a dozen further spellings all get there. Sniffing for more names
2951
+ // trades one wrong guess for another, so a non-string `as` counts as
2952
+ // interactive: announcing a real anchor as a button, and layering a synthetic
2953
+ // click over its navigation, is the worse of the two failures (#668).
2954
+ //
2955
+ // A custom ELEMENT stays out of it. A hyphenated tag is a real DOM element and
2956
+ // none of those is natively interactive, so `<x-trigger>` keeps the fallback
2957
+ // exactly like `as="span"` — the same line `Avatar` draws for `role="img"`.
2958
+ //
2959
+ // Where we are guessing, the caller settles it: a custom target that declares
2960
+ // `role="button"` is saying it is a button and not a link, so it takes the
2961
+ // whole fallback — including the click, which is the half it could not supply
2962
+ // itself. `Avatar` gives the same escape hatch to the same guess. An `href`
2963
+ // still wins: a target with somewhere to navigate is a link whatever role it
2964
+ // claims.
2965
+ const customTargetIsButton = typeof Component !== 'string' && rest.role === 'button';
2966
+ const isNativeInteractive = Component === 'button' ||
2967
+ (typeof Component !== 'string' && !customTargetIsButton) ||
2968
+ hasHref;
2905
2969
  // Guarded like Button's disabled blocker: these run on whatever `as` renders,
2906
2970
  // and a custom target's callback need not take a DOM event. One declaring
2907
2971
  // `onKeyDown: (k: {key: string}) => void` reaches `e.preventDefault()` and
@@ -6102,6 +6166,7 @@ const notification = {
6102
6166
  const NotificationItem = ({ instance, onClose }) => {
6103
6167
  const { message, color, isLight, duration = 3000, hasDelete = true, indefinite = false, pauseOnHover = true, } = instance.options;
6104
6168
  const [isPaused, setIsPaused] = React.useState(false);
6169
+ const urgent = color === 'danger' || color === 'warning';
6105
6170
  const handleClose = React.useCallback(() => {
6106
6171
  onClose(instance.id);
6107
6172
  }, [onClose, instance.id]);
@@ -6120,11 +6185,13 @@ const NotificationItem = ({ instance, onClose }) => {
6120
6185
  if (pauseOnHover)
6121
6186
  setIsPaused(false);
6122
6187
  }, [pauseOnHover]);
6123
- return (jsxRuntime.jsx(Notification, { color: color, isLight: isLight, hasDelete: hasDelete, onDelete: handleClose, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: { pointerEvents: 'auto' }, children: message }));
6188
+ return (jsxRuntime.jsx(Notification, { color: color, isLight: isLight, hasDelete: hasDelete, onDelete: handleClose, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: { pointerEvents: 'auto' }, children: urgent ? (jsxRuntime.jsx("span", { role: "alert", "aria-live": "assertive", children: message })) : (jsxRuntime.jsx("span", { role: "status", "aria-live": "polite", children: message })) }));
6124
6189
  };
6125
6190
  /**
6126
6191
  * Container component for rendering programmatic notifications.
6127
- * Place once at your app root to enable the notification API.
6192
+ * Place once at your app root to enable the notification API. Mount it
6193
+ * before calling `notification`: a notification shown while no container is
6194
+ * mounted doesn't appear when one mounts, only alongside the next call.
6128
6195
  *
6129
6196
  * @function
6130
6197
  * @param {{ position?: NotificationPosition }} props - Container props.
@@ -13427,7 +13494,6 @@ exports.ToastContainer = ToastContainer;
13427
13494
  exports.Tooltip = Tooltip;
13428
13495
  exports.Tr = Tr;
13429
13496
  exports.UnorderedList = UnorderedList;
13430
- exports.__test_exports__ = __test_exports__;
13431
13497
  exports.checkboxColors = checkboxColors;
13432
13498
  exports.checkboxSizes = checkboxSizes;
13433
13499
  exports.classNames = classNames;