@allxsmith/bestax-bulma 5.16.11 → 5.18.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.esm.js CHANGED
@@ -1671,6 +1671,75 @@ const Breadcrumb = ({ className, alignment, separator, size, children, ...props
1671
1671
  return (jsx("nav", { className: breadcrumbClasses, "aria-label": "breadcrumbs", ...rest, children: jsx("ul", { children: children }) }));
1672
1672
  };
1673
1673
 
1674
+ /**
1675
+ * The runtime mirror of `AnchorOnlyAttributes`, keyed so the two cannot drift.
1676
+ *
1677
+ * `Record<keyof …, true>` is what links them: the day React adds an anchor
1678
+ * attribute, every component deriving its props from `as` accepts it and this
1679
+ * object stops compiling until it is named here. A plain array beside a derived
1680
+ * type drifts in the one direction that matters — the type accepts the new
1681
+ * attribute and the filter lets it leak onto a `<div>`.
1682
+ */
1683
+ const ANCHOR_ONLY_ATTRS = {
1684
+ href: true,
1685
+ target: true,
1686
+ download: true,
1687
+ hrefLang: true,
1688
+ ping: true,
1689
+ referrerPolicy: true,
1690
+ media: true,
1691
+ type: true,
1692
+ };
1693
+ /**
1694
+ * `props` without the keys named in `strip`.
1695
+ *
1696
+ * The SET is per component and deliberately not shared, because the right
1697
+ * answer differs and the differences are principled: how open the component's
1698
+ * `as` is, and which of these attributes its own tags legitimately take. What
1699
+ * IS shared is the derived source of truth above and this function. Each caller
1700
+ * declares its delta next to the set it passes, which is the only place that
1701
+ * stays true when a component's `as` changes.
1702
+ */
1703
+ function omitAttrs(props, strip) {
1704
+ const out = {};
1705
+ // `Reflect.ownKeys`, not `Object.entries`: the latter drops symbol-keyed props.
1706
+ // React enumerates props with `for...in`, which never reports a symbol, so
1707
+ // nothing renders differently either way. It is not the same change for all
1708
+ // three callers: Menu filtered by rest-destructure and kept them already,
1709
+ // while Dropdown and Level filtered through `Object.entries` and did not, so
1710
+ // this restores one and widens two. Symbols are the only shape where those
1711
+ // two disagreed, and keeping them is the side a spread is on.
1712
+ for (const key of Reflect.ownKeys(props)) {
1713
+ // Enumerability, for the same reason in the other direction: `Reflect.ownKeys`
1714
+ // also reports NON-enumerable own props, which every filter this replaced left
1715
+ // behind. Copying one out would both add a prop the old code dropped and make
1716
+ // it enumerable on the way, so widening the key source must not widen this.
1717
+ if (!Object.prototype.propertyIsEnumerable.call(props, key))
1718
+ continue;
1719
+ const value = props[key];
1720
+ // `hasOwnProperty`, not `key in strip`: `in` walks the prototype chain, so a
1721
+ // prop named `toString`, `valueOf`, `constructor` or `hasOwnProperty` was
1722
+ // stripped although no caller named it — and anything written to
1723
+ // `Object.prototype` would start deleting props that share its keys.
1724
+ if (typeof key === 'symbol' ||
1725
+ !Object.prototype.hasOwnProperty.call(strip, key)) {
1726
+ // `defineProperty`, not `out[key] = value`: assignment consults the
1727
+ // prototype chain for a setter, and `__proto__` has one. A prop named
1728
+ // `__proto__` would be swallowed by it — dropped from the result AND
1729
+ // replacing the result's prototype with its value. A spread and a rest
1730
+ // destructure both DEFINE, which is what makes them immune, so this has
1731
+ // to define too.
1732
+ Object.defineProperty(out, key, {
1733
+ value,
1734
+ writable: true,
1735
+ enumerable: true,
1736
+ configurable: true,
1737
+ });
1738
+ }
1739
+ }
1740
+ return out;
1741
+ }
1742
+
1674
1743
  /**
1675
1744
  * Merges helper-emitted inline styles (e.g., `bulmaHelperStyles` from
1676
1745
  * `useBulmaClasses`) with a user-supplied `style` prop.
@@ -1747,6 +1816,34 @@ const CardComponent = ({ className, children, textColor, color, bgColor, hasShad
1747
1816
  hasCompoundComponents(children) &&
1748
1817
  children, hasFooter && (jsx("footer", { className: prefixedClassNames(classPrefix, 'card-footer'), children: Array.isArray(footer) ? (footer.map((item, idx) => (jsx("span", { className: prefixedClassNames(classPrefix, 'card-footer-item'), children: item }, idx)))) : (jsx("span", { className: prefixedClassNames(classPrefix, 'card-footer-item'), children: footer })) }))] }));
1749
1818
  };
1819
+ /**
1820
+ * The set withheld from a non-anchor `Card.FooterItem` (`span`/`button`): the
1821
+ * derived anchor-only attributes, minus `type` (also valid on a `<button>` as
1822
+ * `submit`/`button`/`reset`, so stripping it there would remove a working
1823
+ * attribute — the same trade `DropdownItem`'s own `STRIP_FROM_NON_ANCHOR`
1824
+ * accepts, in `./Dropdown.tsx`), plus `rel` (React declares it on
1825
+ * `HTMLAttributes` for every element, so the derived set alone would not
1826
+ * withhold it — the same addition `Level.Item` makes).
1827
+ */
1828
+ const STRIP_FROM_NON_ANCHOR$2 = (() => {
1829
+ const { type: _type, ...rest } = ANCHOR_ONLY_ATTRS;
1830
+ return { ...rest, rel: true };
1831
+ })();
1832
+ /**
1833
+ * The set withheld from a non-button `Card.FooterItem` (`span`/`a`), keyed so
1834
+ * it stops compiling until a button attribute React adds is named here.
1835
+ */
1836
+ const STRIP_FROM_NON_BUTTON = {
1837
+ disabled: true,
1838
+ form: true,
1839
+ formAction: true,
1840
+ formEncType: true,
1841
+ formMethod: true,
1842
+ formNoValidate: true,
1843
+ formTarget: true,
1844
+ name: true,
1845
+ value: true,
1846
+ };
1750
1847
  /**
1751
1848
  * Card header compound component. Wraps children in a `.card-header` element.
1752
1849
  *
@@ -1777,13 +1874,14 @@ const CardHeader = ({ className, children, centered, color, bgColor, textColor,
1777
1874
  * @param {CardHeaderTitleProps} props - Props for the CardHeaderTitle component.
1778
1875
  * @returns {JSX.Element} The rendered card header title.
1779
1876
  */
1780
- const CardHeaderTitle = ({ className, children, centered, color, bgColor, textColor, ...props }) => {
1877
+ const CardHeaderTitle = ({ as = 'div', className, children, centered, color, bgColor, textColor, ...props }) => {
1781
1878
  const { bulmaHelperClasses, rest } = useBulmaClasses({
1782
1879
  color: textColor ?? color,
1783
1880
  backgroundColor: bgColor,
1784
1881
  ...props,
1785
1882
  });
1786
- return (jsx("div", { className: classNames(usePrefixedClassNames('card-header-title', {
1883
+ const Tag = as;
1884
+ return (jsx(Tag, { className: classNames(usePrefixedClassNames('card-header-title', {
1787
1885
  'is-centered': centered,
1788
1886
  }), bulmaHelperClasses, className), ...rest, children: children }));
1789
1887
  };
@@ -1854,13 +1952,40 @@ const CardFooter = ({ className, children, color, bgColor, textColor, ...props }
1854
1952
  * @param {CardFooterItemProps} props - Props for the CardFooterItem component.
1855
1953
  * @returns {JSX.Element} The rendered card footer item.
1856
1954
  */
1857
- const CardFooterItem = ({ className, children, color, bgColor, textColor, ...props }) => {
1955
+ const CardFooterItem = ({ as = 'span', className, children, color, bgColor, textColor, ...props }) => {
1858
1956
  const { bulmaHelperClasses, rest } = useBulmaClasses({
1859
1957
  color: textColor ?? color,
1860
1958
  backgroundColor: bgColor,
1861
1959
  ...props,
1862
1960
  });
1863
- return (jsx("span", { className: classNames(usePrefixedClassNames('card-footer-item'), bulmaHelperClasses, className), ...rest, children: children }));
1961
+ const itemClasses = classNames(usePrefixedClassNames('card-footer-item'), bulmaHelperClasses, className);
1962
+ // The anchor's own attributes reach an `<a>` and nothing else, and the button's a
1963
+ // `<button>` — `STRIP_FROM_NON_ANCHOR` above names the anchor set and why `type`
1964
+ // stays while `rel` is added, and `STRIP_FROM_NON_BUTTON` the button set.
1965
+ if (as === 'a') {
1966
+ return (jsx("a", { className: itemClasses, ...omitAttrs(rest, STRIP_FROM_NON_BUTTON), children: children }));
1967
+ }
1968
+ const forwarded = omitAttrs(rest, STRIP_FROM_NON_ANCHOR$2);
1969
+ if (as === 'button') {
1970
+ const forwardedType = forwarded.type;
1971
+ return (jsx("button", { className: itemClasses, ...forwarded,
1972
+ // A footer item button must not submit an enclosing form by default —
1973
+ // `<button>` defaults to `type="submit"`, and a Save/Cancel action row
1974
+ // sitting in a form is the common case this `as` exists for.
1975
+ //
1976
+ // A MISSING `type` is not the only way that default arrives: `type` is
1977
+ // typed here as the `<a>` MIME string (`STRIP_FROM_NON_ANCHOR` above
1978
+ // says why it is not withheld), so `as="button" type="text/html"`
1979
+ // compiles, and HTML's INVALID-value default for a button's `type` is
1980
+ // submit too. So anything that is not one of the three native button
1981
+ // types falls back to `button` rather than being forwarded.
1982
+ type: forwardedType === 'submit' ||
1983
+ forwardedType === 'reset' ||
1984
+ forwardedType === 'button'
1985
+ ? forwardedType
1986
+ : 'button', children: children }));
1987
+ }
1988
+ return (jsx("span", { className: itemClasses, ...omitAttrs(forwarded, STRIP_FROM_NON_BUTTON), children: children }));
1864
1989
  };
1865
1990
  // Attach nested Title and Icon components to CardHeader
1866
1991
  const CardHeaderCompound = withSubComponents(CardHeader, {
@@ -1876,75 +2001,6 @@ const Card = withSubComponents(CardComponent, {
1876
2001
  FooterItem: CardFooterItem,
1877
2002
  }, 'Card');
1878
2003
 
1879
- /**
1880
- * The runtime mirror of `AnchorOnlyAttributes`, keyed so the two cannot drift.
1881
- *
1882
- * `Record<keyof …, true>` is what links them: the day React adds an anchor
1883
- * attribute, every component deriving its props from `as` accepts it and this
1884
- * object stops compiling until it is named here. A plain array beside a derived
1885
- * type drifts in the one direction that matters — the type accepts the new
1886
- * attribute and the filter lets it leak onto a `<div>`.
1887
- */
1888
- const ANCHOR_ONLY_ATTRS = {
1889
- href: true,
1890
- target: true,
1891
- download: true,
1892
- hrefLang: true,
1893
- ping: true,
1894
- referrerPolicy: true,
1895
- media: true,
1896
- type: true,
1897
- };
1898
- /**
1899
- * `props` without the keys named in `strip`.
1900
- *
1901
- * The SET is per component and deliberately not shared, because the right
1902
- * answer differs and the differences are principled: how open the component's
1903
- * `as` is, and which of these attributes its own tags legitimately take. What
1904
- * IS shared is the derived source of truth above and this function. Each caller
1905
- * declares its delta next to the set it passes, which is the only place that
1906
- * stays true when a component's `as` changes.
1907
- */
1908
- function omitAttrs(props, strip) {
1909
- const out = {};
1910
- // `Reflect.ownKeys`, not `Object.entries`: the latter drops symbol-keyed props.
1911
- // React enumerates props with `for...in`, which never reports a symbol, so
1912
- // nothing renders differently either way. It is not the same change for all
1913
- // three callers: Menu filtered by rest-destructure and kept them already,
1914
- // while Dropdown and Level filtered through `Object.entries` and did not, so
1915
- // this restores one and widens two. Symbols are the only shape where those
1916
- // two disagreed, and keeping them is the side a spread is on.
1917
- for (const key of Reflect.ownKeys(props)) {
1918
- // Enumerability, for the same reason in the other direction: `Reflect.ownKeys`
1919
- // also reports NON-enumerable own props, which every filter this replaced left
1920
- // behind. Copying one out would both add a prop the old code dropped and make
1921
- // it enumerable on the way, so widening the key source must not widen this.
1922
- if (!Object.prototype.propertyIsEnumerable.call(props, key))
1923
- continue;
1924
- const value = props[key];
1925
- // `hasOwnProperty`, not `key in strip`: `in` walks the prototype chain, so a
1926
- // prop named `toString`, `valueOf`, `constructor` or `hasOwnProperty` was
1927
- // stripped although no caller named it — and anything written to
1928
- // `Object.prototype` would start deleting props that share its keys.
1929
- if (typeof key === 'symbol' ||
1930
- !Object.prototype.hasOwnProperty.call(strip, key)) {
1931
- // `defineProperty`, not `out[key] = value`: assignment consults the
1932
- // prototype chain for a setter, and `__proto__` has one. A prop named
1933
- // `__proto__` would be swallowed by it — dropped from the result AND
1934
- // replacing the result's prototype with its value. A spread and a rest
1935
- // destructure both DEFINE, which is what makes them immune, so this has
1936
- // to define too.
1937
- Object.defineProperty(out, key, {
1938
- value,
1939
- writable: true,
1940
- enumerable: true,
1941
- configurable: true,
1942
- });
1943
- }
1944
- }
1945
- return out;
1946
- }
1947
-
1948
2004
  /**
1949
2005
  * Checks if code is running in a browser environment.
1950
2006
  * @deprecated Dropdown's internal SSR guard, exported by accident; it will
@@ -3148,6 +3204,38 @@ const warnDeprecatedColorProp = (component, value, hint) => {
3148
3204
  `a visual effect. It will be removed in the next major version. ${hint}`);
3149
3205
  };
3150
3206
 
3207
+ /** A count read as a whole number from zero, or `fallback` when it's no number. */
3208
+ function whole(count, fallback) {
3209
+ return Number.isFinite(count) ? Math.max(Math.floor(count), 0) : fallback;
3210
+ }
3211
+ function range(from, to) {
3212
+ return Array.from({ length: Math.max(to - from + 1, 0) }, (_, i) => from + i);
3213
+ }
3214
+ /**
3215
+ * The pages to show for `current` of `total`: the first and last
3216
+ * `boundaries`, `siblings` on each side of the current one, and a gap for
3217
+ * each run left out. A gap of a single page shows that page instead, and the
3218
+ * window around the current page slides inward near either end, so the row
3219
+ * keeps its length as the page moves.
3220
+ */
3221
+ function pageItems(total, current, siblings, boundaries) {
3222
+ const windowSize = siblings * 2 + 1;
3223
+ // Every page fits in the room the boundary pages, the window and two gaps take.
3224
+ if (total <= boundaries * 2 + windowSize + 2)
3225
+ return range(1, total);
3226
+ const lowest = boundaries + 2;
3227
+ const highest = total - boundaries - 1;
3228
+ const start = Math.min(Math.max(current - siblings, lowest), highest - windowSize + 1);
3229
+ const end = start + windowSize - 1;
3230
+ const gap = (from, to, name) => to === from ? [from] : [name];
3231
+ return [
3232
+ ...range(1, boundaries),
3233
+ ...gap(boundaries + 1, start - 1, 'start-gap'),
3234
+ ...range(start, end),
3235
+ ...gap(end + 1, total - boundaries, 'end-gap'),
3236
+ ...range(total - boundaries + 1, total),
3237
+ ];
3238
+ }
3151
3239
  /**
3152
3240
  * "Previous" navigation button.
3153
3241
  *
@@ -3155,9 +3243,9 @@ const warnDeprecatedColorProp = (component, value, hint) => {
3155
3243
  * @param {PaginationPreviousNextProps} props - Props for the PaginationPrevious component.
3156
3244
  * @returns {JSX.Element} The rendered previous button.
3157
3245
  */
3158
- const PaginationPrevious = ({ className, disabled, children, ...props }) => (jsx("a", { className: classNames(usePrefixedClassNames('pagination-previous'), className, {
3246
+ const PaginationPrevious = ({ className, disabled, children, ...props }) => (jsx("a", { className: classNames(usePrefixedClassNames('pagination-previous', {
3159
3247
  'is-disabled': disabled,
3160
- }), "aria-disabled": disabled, tabIndex: disabled ? -1 : 0, ...props, onClick: disabled
3248
+ }), className), "aria-disabled": disabled, tabIndex: disabled ? -1 : 0, ...props, onClick: disabled
3161
3249
  ? e => {
3162
3250
  e.preventDefault();
3163
3251
  e.stopPropagation();
@@ -3170,9 +3258,7 @@ const PaginationPrevious = ({ className, disabled, children, ...props }) => (jsx
3170
3258
  * @param {PaginationPreviousNextProps} props - Props for the PaginationNext component.
3171
3259
  * @returns {JSX.Element} The rendered next button.
3172
3260
  */
3173
- const PaginationNext = ({ className, disabled, children, ...props }) => (jsx("a", { className: classNames(usePrefixedClassNames('pagination-next'), className, {
3174
- 'is-disabled': disabled,
3175
- }), "aria-disabled": disabled, tabIndex: disabled ? -1 : 0, ...props, onClick: disabled
3261
+ const PaginationNext = ({ className, disabled, children, ...props }) => (jsx("a", { className: classNames(usePrefixedClassNames('pagination-next', { 'is-disabled': disabled }), className), "aria-disabled": disabled, tabIndex: disabled ? -1 : 0, ...props, onClick: disabled
3176
3262
  ? e => {
3177
3263
  e.preventDefault();
3178
3264
  e.stopPropagation();
@@ -3186,7 +3272,8 @@ const PaginationNext = ({ className, disabled, children, ...props }) => (jsx("a"
3186
3272
  * @returns {JSX.Element} The rendered pagination.
3187
3273
  * @see {@link https://bulma.io/documentation/components/pagination/ | Bulma Pagination documentation}
3188
3274
  */
3189
- const PaginationComponent = ({ color, textColor, bgColor, size, align, rounded, className, children, ...props }) => {
3275
+ const PaginationComponent = ({ color, textColor, bgColor, size, align, rounded, total, current, onPageChange, siblingCount = 1, boundaryCount = 1, previousLabel = 'Previous', nextLabel = 'Next', disabled, getPageHref, getPageLabel, className, children, ...props }) => {
3276
+ const [kept, setKept] = React.useState(1);
3190
3277
  warnDeprecatedColorProp('Pagination', color, 'Use the textColor / bgColor helper props instead.');
3191
3278
  const { bulmaHelperClasses, rest } = useBulmaClasses({
3192
3279
  color: textColor,
@@ -3201,7 +3288,43 @@ const PaginationComponent = ({ color, textColor, bgColor, size, align, rounded,
3201
3288
  'is-rounded': rounded,
3202
3289
  });
3203
3290
  const paginationClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
3204
- return (jsx("nav", { className: paginationClasses, role: "navigation", "aria-label": "pagination", ...rest, children: children }));
3291
+ // A child that renders nothing (`{show && …}` when false) is no children.
3292
+ const fromTotal = total !== undefined && React.Children.toArray(children).length === 0;
3293
+ let content = children;
3294
+ if (fromTotal) {
3295
+ const pages = Number.isFinite(total) ? Math.max(Math.floor(total), 0) : 0;
3296
+ // A current page that's no number reads as the first.
3297
+ const page = Math.min(Math.max(whole(current ?? kept, 1), 1), Math.max(pages, 1));
3298
+ const choose = (next) => {
3299
+ if (next === page)
3300
+ return;
3301
+ if (current === undefined)
3302
+ setKept(next);
3303
+ onPageChange?.(next);
3304
+ };
3305
+ /**
3306
+ * What a link to `target` is given, beside what it renders. With no
3307
+ * `getPageHref` it's a button; a link that's `off` goes nowhere.
3308
+ */
3309
+ const linkTo = (target, off) => ({
3310
+ href: off || !getPageHref ? undefined : getPageHref(target),
3311
+ role: getPageHref ? undefined : 'button',
3312
+ // A link that's off is disabled too, and the parts drop its clicks.
3313
+ onClick: () => choose(target),
3314
+ onKeyDown: getPageHref
3315
+ ? undefined
3316
+ : (e) => {
3317
+ if (off || (e.key !== 'Enter' && e.key !== ' '))
3318
+ return;
3319
+ e.preventDefault();
3320
+ choose(target);
3321
+ },
3322
+ });
3323
+ const atStart = disabled || page <= 1;
3324
+ const atEnd = disabled || page >= pages;
3325
+ content = (jsxs(Fragment, { children: [jsx(PaginationPrevious, { disabled: atStart, ...linkTo(page - 1, atStart), children: previousLabel }), jsx(PaginationNext, { disabled: atEnd, ...linkTo(page + 1, atEnd), children: nextLabel }), jsx(PaginationList, { children: pageItems(pages, page, whole(siblingCount, 1), whole(boundaryCount, 1)).map(item => typeof item === 'number' ? (jsx(PaginationLink, { "aria-label": getPageLabel ? getPageLabel(item) : `Page ${item}`, active: item === page, disabled: disabled, ...linkTo(item, Boolean(disabled)), children: item }, item)) : (jsx(PaginationEllipsis, {}, item))) })] }));
3326
+ }
3327
+ return (jsx("nav", { className: paginationClasses, role: "navigation", "aria-label": "pagination", ...rest, children: content }));
3205
3328
  };
3206
3329
  /**
3207
3330
  * Container for page links and ellipsis.
@@ -3241,10 +3364,10 @@ const PaginationLink = ({ className, textColor, bgColor, active, disabled, onCli
3241
3364
  onClick(e);
3242
3365
  }
3243
3366
  };
3244
- return (jsx("li", { children: jsx("a", { className: classNames(usePrefixedClassNames('pagination-link'), bulmaHelperClasses, className, {
3367
+ return (jsx("li", { children: jsx("a", { className: classNames(usePrefixedClassNames('pagination-link', {
3245
3368
  'is-current': active,
3246
3369
  'is-disabled': disabled,
3247
- }), "aria-current": active ? 'page' : undefined, "aria-disabled": disabled, tabIndex: disabled ? -1 : 0, onClick: handleClick, ...rest, children: children }) }));
3370
+ }), bulmaHelperClasses, className), "aria-current": active ? 'page' : undefined, "aria-disabled": disabled, tabIndex: disabled ? -1 : 0, onClick: handleClick, ...rest, children: children }) }));
3248
3371
  };
3249
3372
  /**
3250
3373
  * Ellipsis separator.