@allxsmith/bestax-bulma 5.52.0 → 5.54.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.
Files changed (145) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/Avatars.js +7 -2
  4. package/dist/esm/components/Avatars.js.map +1 -1
  5. package/dist/esm/components/Badge.js +7 -2
  6. package/dist/esm/components/Badge.js.map +1 -1
  7. package/dist/esm/components/Command.js +19 -9
  8. package/dist/esm/components/Command.js.map +1 -1
  9. package/dist/esm/components/Modal.js +2 -1
  10. package/dist/esm/components/Modal.js.map +1 -1
  11. package/dist/esm/components/Pagination.js +9 -1
  12. package/dist/esm/components/Pagination.js.map +1 -1
  13. package/dist/esm/components/Sidebar.js +3 -1
  14. package/dist/esm/components/Sidebar.js.map +1 -1
  15. package/dist/esm/components/Steps.js +5 -1
  16. package/dist/esm/components/Steps.js.map +1 -1
  17. package/dist/esm/components/Toast.js +8 -5
  18. package/dist/esm/components/Toast.js.map +1 -1
  19. package/dist/esm/elements/Notification.js +4 -2
  20. package/dist/esm/elements/Notification.js.map +1 -1
  21. package/dist/esm/elements/RingProgress.js +6 -1
  22. package/dist/esm/elements/RingProgress.js.map +1 -1
  23. package/dist/esm/form/Autocomplete.js +7 -2
  24. package/dist/esm/form/Autocomplete.js.map +1 -1
  25. package/dist/esm/form/Checkbox.js +3 -2
  26. package/dist/esm/form/Checkbox.js.map +1 -1
  27. package/dist/esm/form/CheckboxCard.js +3 -2
  28. package/dist/esm/form/CheckboxCard.js.map +1 -1
  29. package/dist/esm/form/Combobox.js +10 -4
  30. package/dist/esm/form/Combobox.js.map +1 -1
  31. package/dist/esm/form/DateInputBase.js +15 -6
  32. package/dist/esm/form/DateInputBase.js.map +1 -1
  33. package/dist/esm/form/DateRangeInputBase.js +15 -5
  34. package/dist/esm/form/DateRangeInputBase.js.map +1 -1
  35. package/dist/esm/form/DateTimeInputBase.js +15 -6
  36. package/dist/esm/form/DateTimeInputBase.js.map +1 -1
  37. package/dist/esm/form/Fieldset.js +64 -0
  38. package/dist/esm/form/Fieldset.js.map +1 -0
  39. package/dist/esm/form/File.js +4 -1
  40. package/dist/esm/form/File.js.map +1 -1
  41. package/dist/esm/form/FormContext.js +17 -1
  42. package/dist/esm/form/FormContext.js.map +1 -1
  43. package/dist/esm/form/InputBase.js +3 -2
  44. package/dist/esm/form/InputBase.js.map +1 -1
  45. package/dist/esm/form/Numberinput.js +3 -2
  46. package/dist/esm/form/Numberinput.js.map +1 -1
  47. package/dist/esm/form/PinInput.js +3 -2
  48. package/dist/esm/form/PinInput.js.map +1 -1
  49. package/dist/esm/form/Radio.js +3 -2
  50. package/dist/esm/form/Radio.js.map +1 -1
  51. package/dist/esm/form/RadioCard.js +3 -2
  52. package/dist/esm/form/RadioCard.js.map +1 -1
  53. package/dist/esm/form/Rate.js +12 -3
  54. package/dist/esm/form/Rate.js.map +1 -1
  55. package/dist/esm/form/SelectBase.js +3 -2
  56. package/dist/esm/form/SelectBase.js.map +1 -1
  57. package/dist/esm/form/Slider.js +10 -6
  58. package/dist/esm/form/Slider.js.map +1 -1
  59. package/dist/esm/form/Switch.js +3 -1
  60. package/dist/esm/form/Switch.js.map +1 -1
  61. package/dist/esm/form/Taginput.js +12 -5
  62. package/dist/esm/form/Taginput.js.map +1 -1
  63. package/dist/esm/form/TextAreaBase.js +3 -2
  64. package/dist/esm/form/TextAreaBase.js.map +1 -1
  65. package/dist/esm/form/TimeInputBase.js +13 -6
  66. package/dist/esm/form/TimeInputBase.js.map +1 -1
  67. package/dist/esm/form/_pickerInternals/PickerPopover.js +4 -2
  68. package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
  69. package/dist/esm/form/_pickerInternals/useLocaleDefaults.js +80 -0
  70. package/dist/esm/form/_pickerInternals/useLocaleDefaults.js.map +1 -0
  71. package/dist/esm/helpers/LocaleProvider.js +156 -0
  72. package/dist/esm/helpers/LocaleProvider.js.map +1 -0
  73. package/dist/esm/helpers/localeFormat.js +108 -0
  74. package/dist/esm/helpers/localeFormat.js.map +1 -0
  75. package/dist/esm/helpers/localeInfo.js +109 -0
  76. package/dist/esm/helpers/localeInfo.js.map +1 -0
  77. package/dist/esm/helpers/portal.js +14 -1
  78. package/dist/esm/helpers/portal.js.map +1 -1
  79. package/dist/extras.css +1 -1
  80. package/dist/extras.css.map +1 -1
  81. package/dist/index.cjs +690 -73
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.esm.js +2 -0
  84. package/dist/index.esm.js.map +1 -1
  85. package/dist/types/components/Avatars.d.ts +1 -1
  86. package/dist/types/components/Badge.d.ts +1 -1
  87. package/dist/types/components/Command.d.ts +4 -2
  88. package/dist/types/components/Pagination.d.ts +3 -0
  89. package/dist/types/components/Steps.d.ts +4 -1
  90. package/dist/types/elements/RingProgress.d.ts +3 -2
  91. package/dist/types/form/Autocomplete.d.ts +6 -1
  92. package/dist/types/form/Combobox.d.ts +3 -2
  93. package/dist/types/form/DateInputBase.d.ts +25 -3
  94. package/dist/types/form/DateRangeInputBase.d.ts +25 -3
  95. package/dist/types/form/DateTimeInputBase.d.ts +25 -3
  96. package/dist/types/form/Fieldset.d.ts +86 -0
  97. package/dist/types/form/File.d.ts +2 -1
  98. package/dist/types/form/FormContext.d.ts +12 -0
  99. package/dist/types/form/Rate.d.ts +4 -1
  100. package/dist/types/form/Slider.d.ts +9 -2
  101. package/dist/types/form/Taginput.d.ts +8 -2
  102. package/dist/types/form/TimeInputBase.d.ts +5 -1
  103. package/dist/types/form/_pickerInternals/PickerPopover.d.ts +6 -0
  104. package/dist/types/form/_pickerInternals/useLocaleDefaults.d.ts +49 -0
  105. package/dist/types/helpers/LocaleProvider.d.ts +131 -0
  106. package/dist/types/helpers/localeFormat.d.ts +26 -0
  107. package/dist/types/helpers/localeInfo.d.ts +23 -0
  108. package/dist/types/helpers/portal.d.ts +11 -0
  109. package/dist/types/index.d.ts +3 -0
  110. package/dist/types-cjs/components/Avatars.d.ts +1 -1
  111. package/dist/types-cjs/components/Badge.d.ts +1 -1
  112. package/dist/types-cjs/components/Command.d.ts +4 -2
  113. package/dist/types-cjs/components/Pagination.d.ts +3 -0
  114. package/dist/types-cjs/components/Steps.d.ts +4 -1
  115. package/dist/types-cjs/elements/RingProgress.d.ts +3 -2
  116. package/dist/types-cjs/form/Autocomplete.d.ts +6 -1
  117. package/dist/types-cjs/form/Combobox.d.ts +3 -2
  118. package/dist/types-cjs/form/DateInputBase.d.ts +25 -3
  119. package/dist/types-cjs/form/DateRangeInputBase.d.ts +25 -3
  120. package/dist/types-cjs/form/DateTimeInputBase.d.ts +25 -3
  121. package/dist/types-cjs/form/Fieldset.d.ts +86 -0
  122. package/dist/types-cjs/form/File.d.ts +2 -1
  123. package/dist/types-cjs/form/FormContext.d.ts +12 -0
  124. package/dist/types-cjs/form/Rate.d.ts +4 -1
  125. package/dist/types-cjs/form/Slider.d.ts +9 -2
  126. package/dist/types-cjs/form/Taginput.d.ts +8 -2
  127. package/dist/types-cjs/form/TimeInputBase.d.ts +5 -1
  128. package/dist/types-cjs/form/_pickerInternals/PickerPopover.d.ts +6 -0
  129. package/dist/types-cjs/form/_pickerInternals/useLocaleDefaults.d.ts +49 -0
  130. package/dist/types-cjs/helpers/LocaleProvider.d.ts +131 -0
  131. package/dist/types-cjs/helpers/localeFormat.d.ts +26 -0
  132. package/dist/types-cjs/helpers/localeInfo.d.ts +23 -0
  133. package/dist/types-cjs/helpers/portal.d.ts +11 -0
  134. package/dist/types-cjs/index.d.ts +3 -0
  135. package/dist/versions/bestax-no-dark-mode.css +1 -1
  136. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  137. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  138. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  139. package/dist/versions/bestax-no-helpers.css +1 -1
  140. package/dist/versions/bestax-no-helpers.css.map +1 -1
  141. package/dist/versions/bestax-prefixed.css +1 -1
  142. package/dist/versions/bestax-prefixed.css.map +1 -1
  143. package/package.json +1 -1
  144. package/src/scss/form/_fieldset.scss +108 -0
  145. package/src/scss/form/_index.scss +1 -0
package/dist/index.cjs CHANGED
@@ -1792,6 +1792,360 @@ function flattenChildren(children, keyPrefix = '') {
1792
1792
  });
1793
1793
  }
1794
1794
 
1795
+ // INTERNAL: deliberately not exported from src/index.ts. What a locale says
1796
+ // about its direction, read from `Intl.Locale` where the engine has the data,
1797
+ // and about its week, read from a copy of CLDR's week data.
1798
+ /**
1799
+ * Scripts written right to left: every script for which ICU's text info
1800
+ * says `rtl`, as Node reported it, and `Aran`, the Nastaliq form of Arabic
1801
+ * that WebKit fills in for Urdu. Read only where the engine has no text info
1802
+ * of its own, which includes Firefox before 153.
1803
+ */
1804
+ const RTL_SCRIPTS = ' Adlm Arab Aran Armi Avst Chrs Cprt Elym Gara Hatr Hebr Hung Khar Lydi ' +
1805
+ 'Mand Mani Mend Merc Mero Narb Nbat Nkoo Orkh Ougr Palm Phli Phlp Phnx ' +
1806
+ 'Prti Rohg Samr Sarb Sidt Sogd Sogo Syrc Thaa Yezi ';
1807
+ /**
1808
+ * Widely used languages whose usual script reads right to left, for an engine
1809
+ * that can't fill in a locale's script with `maximize()`.
1810
+ */
1811
+ const RTL_LANGUAGES = ' ar ckb dv fa he iw ji ks mzn nqo pnb ps sd syr ug ur yi ';
1812
+ /**
1813
+ * The regions whose week doesn't start on Monday, by the day it starts on
1814
+ * (0 = Sunday, 5 = Friday, 6 = Saturday), from CLDR 48's week data as Node
1815
+ * reported it. The library reads this rather than `Intl.Locale`'s week info
1816
+ * because engines disagree: Firefox before 153 has none, and WebKit's differs
1817
+ * from Node's, Chromium's and current Firefox's for China, Algeria, Jordan and
1818
+ * Iceland among others, so an inline calendar rendered on the server would
1819
+ * fail to hydrate there. With one table, the server and every browser agree.
1820
+ */
1821
+ const WEEK_STARTS = [
1822
+ [
1823
+ 0,
1824
+ ' AG AS BD BR BS BT BU BW BZ CA CO DM DO ET GT GU HK HN ID IL IN IS JM JP ' +
1825
+ 'KE KH KR LA MH MM MO MT MX MZ NI NP PA PE PH PK PR PT PY RH SA SG SV TH ' +
1826
+ 'TT TW UM US VE VI WS YD YE ZA ZW ',
1827
+ ],
1828
+ [5, ' MV '],
1829
+ [6, ' AF BH DJ DZ EG IQ IR JO KW LY OM QA SD SY '],
1830
+ ];
1831
+ /** Whether a space-separated list, padded with spaces, holds `code`. */
1832
+ const listed = (list, code) => list.includes(` ${code} `);
1833
+ /** The `-u-fw-` keyword's values, by the day they name. */
1834
+ const FW_DAYS = {
1835
+ sun: 0,
1836
+ mon: 1,
1837
+ tue: 2,
1838
+ wed: 3,
1839
+ thu: 4,
1840
+ fri: 5,
1841
+ sat: 6,
1842
+ };
1843
+ /**
1844
+ * The canonical form of a BCP 47 tag (`"en-us"` becomes `"en-US"`), or
1845
+ * `undefined` for an empty or missing one. Throws a `RangeError` for a tag
1846
+ * `Intl` refuses, as `Intl.DateTimeFormat` would.
1847
+ */
1848
+ function canonicalLocale(tag) {
1849
+ if (!tag)
1850
+ return undefined;
1851
+ return Intl.getCanonicalLocales(tag)[0];
1852
+ }
1853
+ /**
1854
+ * The direction a locale's script is written in: from `Intl.Locale`'s text
1855
+ * info, else from the script `maximize()` fills in, else from the language.
1856
+ *
1857
+ * @param locale - A canonical tag, as `canonicalLocale` returns.
1858
+ */
1859
+ function localeDirection(locale) {
1860
+ const intlLocale = new Intl.Locale(locale);
1861
+ const info = intlLocale;
1862
+ const direction = typeof info.getTextInfo === 'function'
1863
+ ? info.getTextInfo().direction
1864
+ : info.textInfo?.direction;
1865
+ if (direction === 'rtl' || direction === 'ltr')
1866
+ return direction;
1867
+ if (typeof intlLocale.maximize === 'function') {
1868
+ const script = intlLocale.maximize().script;
1869
+ return script && listed(RTL_SCRIPTS, script) ? 'rtl' : 'ltr';
1870
+ }
1871
+ return listed(RTL_LANGUAGES, intlLocale.language) ? 'rtl' : 'ltr';
1872
+ }
1873
+ /**
1874
+ * The day a locale's week starts on, 0 for Sunday, as `getWeekInfo()` reads
1875
+ * it: the tag's `-u-fw-` keyword, else the region its `-u-rg-` keyword names,
1876
+ * else its own region or the one `maximize()` fills in, looked up in CLDR's
1877
+ * week data, where a region not listed starts on Monday.
1878
+ *
1879
+ * @param locale - A canonical tag, as `canonicalLocale` returns.
1880
+ */
1881
+ function localeFirstDay(locale) {
1882
+ const fw = /-u(?:-[a-z0-9]{2,8})*?-fw-([a-z]{3})(?=-|$)/i.exec(locale);
1883
+ if (fw && fw[1].toLowerCase() in FW_DAYS)
1884
+ return FW_DAYS[fw[1].toLowerCase()];
1885
+ const rg = /-u(?:-[a-z0-9]{2,8})*?-rg-([a-z]{2})[a-z0-9]{1,4}(?=-|$)/i.exec(locale);
1886
+ const intlLocale = new Intl.Locale(locale);
1887
+ const region = rg
1888
+ ? rg[1].toUpperCase()
1889
+ : typeof intlLocale.maximize === 'function'
1890
+ ? intlLocale.maximize().region
1891
+ : intlLocale.region;
1892
+ if (region) {
1893
+ for (const [day, regions] of WEEK_STARTS) {
1894
+ if (listed(regions, region))
1895
+ return day;
1896
+ }
1897
+ }
1898
+ return 1;
1899
+ }
1900
+
1901
+ const LocaleContext = React.createContext(null);
1902
+ /** The nearest provider's wrapper element, for `LocalePortalScope` to test targets against. */
1903
+ const LocaleElementContext = React.createContext(null);
1904
+ /** A tag in canonical form, or `undefined`, warning about one `Intl` refuses. */
1905
+ function validLocale(tag) {
1906
+ try {
1907
+ return canonicalLocale(tag);
1908
+ }
1909
+ catch {
1910
+ warnOnce(`locale-provider-invalid:${tag}`, `[bestax-bulma] <LocaleProvider locale="${tag}">: not a language ` +
1911
+ 'tag Intl accepts, so it is ignored. Use a BCP 47 tag such as ' +
1912
+ '"en-US", with a hyphen rather than an underscore.');
1913
+ return undefined;
1914
+ }
1915
+ }
1916
+ /**
1917
+ * Sets the language and writing direction for the part of the app inside it, on a wrapper `<div>` and on what the library portals out of it.
1918
+ *
1919
+ * The wrapper carries `dir` and `lang`, so CSS and the components that read
1920
+ * the computed direction follow it, as they follow `<html dir>`. A `locale`
1921
+ * alone sets the direction of its script, and a `dir` sets the direction
1922
+ * whatever the locale. A nested provider keeps whatever it leaves unset.
1923
+ *
1924
+ * Inside it, the date and time pickers take its `locale` unless given their
1925
+ * own, and their week starts on the first day of the locale they use unless
1926
+ * `firstDayOfWeek` is set, and a picker with a `locale` of its own is read
1927
+ * like a nested provider. With a `locale`, the numbers the library writes,
1928
+ * such as page numbers and badge counts, follow it, and so does the
1929
+ * filtering in `Combobox`, `Autocomplete`, `Taginput` and `Command`, which then ignores
1930
+ * accents where the language treats letters as the same. The library's
1931
+ * portaled content, such as a `Popover` panel, a `Modal` with `portal`, a
1932
+ * `Toast` or a `Portal`'s children, keeps the same `dir` and `lang` though
1933
+ * it renders outside the wrapper: in a container outside the wrapper, it
1934
+ * sits in a `display: contents` element that carries them. Without a
1935
+ * provider none of this changes.
1936
+ *
1937
+ * @function
1938
+ * @param {LocaleProviderProps} props - Props for the LocaleProvider.
1939
+ * @returns {JSX.Element} The wrapper, inside the context.
1940
+ *
1941
+ * @example
1942
+ * <LocaleProvider locale="ar-EG">
1943
+ * <App />
1944
+ * </LocaleProvider>
1945
+ */
1946
+ const LocaleProvider = React.forwardRef(({ locale: localeProp, dir: dirProp, className, children, ...props }, ref) => {
1947
+ const outer = React.useContext(LocaleContext);
1948
+ const ownLocale = React.useMemo(() => validLocale(localeProp), [localeProp]);
1949
+ const ownLocaleDir = React.useMemo(() => (ownLocale ? localeDirection(ownLocale) : undefined), [ownLocale]);
1950
+ const locale = ownLocale || outer?.locale;
1951
+ const dir = dirProp || ownLocaleDir || outer?.dir;
1952
+ const value = React.useMemo(() => ({ locale, dir }), [locale, dir]);
1953
+ const { bulmaHelperClasses, rest } = useBulmaClasses(props);
1954
+ // The wrapper, for portaled content to tell whether its target is inside
1955
+ // it, and the caller's ref. A callback ref's cleanup is held and run on
1956
+ // detach, as Toast and Modal do, since React 18 discards the return value.
1957
+ const elementRef = React.useRef(null);
1958
+ const consumerCleanupRef = React.useRef(null);
1959
+ const setElement = React.useCallback((node) => {
1960
+ elementRef.current = node;
1961
+ if (typeof ref === 'function') {
1962
+ if (node === null) {
1963
+ const consumerCleanup = consumerCleanupRef.current;
1964
+ consumerCleanupRef.current = null;
1965
+ if (consumerCleanup)
1966
+ consumerCleanup();
1967
+ else
1968
+ ref(null);
1969
+ return;
1970
+ }
1971
+ const cleanup = ref(node);
1972
+ consumerCleanupRef.current =
1973
+ typeof cleanup === 'function' ? cleanup : null;
1974
+ }
1975
+ else if (ref) {
1976
+ ref.current = node;
1977
+ }
1978
+ }, [ref]);
1979
+ return (jsxRuntime.jsx(LocaleContext.Provider, { value: value, children: jsxRuntime.jsx(LocaleElementContext.Provider, { value: elementRef, children: jsxRuntime.jsx("div", { ref: setElement, className: classNames(bulmaHelperClasses, className) || undefined, ...rest, dir: dir, lang: locale, children: children }) }) }));
1980
+ });
1981
+ LocaleProvider.displayName = 'LocaleProvider';
1982
+ /** What `useLocale` returns outside a provider, the same object each time. */
1983
+ const noLocale = {};
1984
+ /**
1985
+ * The locale and direction the nearest `LocaleProvider` sets, for an app's own `Intl` calls or its own portaled content; both are `undefined` outside one.
1986
+ *
1987
+ * It isn't the page's direction: with no provider, or one that sets no
1988
+ * direction, the page's `<html dir>` still decides. To act on the direction
1989
+ * an element is laid out in, read `getComputedStyle(element).direction`, as
1990
+ * the library's components do.
1991
+ *
1992
+ * @function
1993
+ * @returns {LocaleContextValue} The nearest provider's `locale` and `dir`.
1994
+ *
1995
+ * @example
1996
+ * const { locale } = useLocale();
1997
+ * const price = new Intl.NumberFormat(locale, {
1998
+ * style: 'currency',
1999
+ * currency: 'EUR',
2000
+ * }).format(12.5);
2001
+ */
2002
+ function useLocale() {
2003
+ return React.useContext(LocaleContext) ?? noLocale;
2004
+ }
2005
+ /**
2006
+ * INTERNAL, deliberately not exported from `src/index.ts`. The nearest
2007
+ * provider's settings, or `null` outside any provider, so a caller can tell
2008
+ * "no provider" from "a provider that sets nothing".
2009
+ */
2010
+ function useLocaleScope() {
2011
+ return React.useContext(LocaleContext);
2012
+ }
2013
+ const displayContents = { display: 'contents' };
2014
+ /**
2015
+ * INTERNAL, deliberately not exported from `src/index.ts`. Keeps the `dir`
2016
+ * and `lang` of the nearest provider, or the `scope` given in their place,
2017
+ * on content the library portals into `target`, which has left the
2018
+ * provider's wrapper behind.
2019
+ *
2020
+ * A target inside the provider's own wrapper gets the content as it is: it
2021
+ * inherits from the wrapper, and follows it when the provider changes.
2022
+ * Content that must be its container's direct child, a `<tr>` portaled into
2023
+ * a `<tbody>` there, stays one. Any other target, `document.body` included,
2024
+ * gets the content inside a `display: contents` element carrying the
2025
+ * values, which adds no box. So does content with a `scope` of its own, a
2026
+ * picker's panel, since the provider's values aren't its own.
2027
+ *
2028
+ * Which of the two is decided once, when the content mounts, and kept while
2029
+ * it stays: switching between them would put a different element in its
2030
+ * place and remount everything inside, losing typed text, focus and timers.
2031
+ * A change of locale or direction updates the wrapper's attributes instead.
2032
+ * A target is never left bare because something else, such as `<html>`,
2033
+ * happens to carry the same values, since that can stop being true without
2034
+ * the content remounting. Outside a provider it renders the children alone,
2035
+ * so nothing changes there.
2036
+ */
2037
+ function LocalePortalScope({ children, target, scope, }) {
2038
+ const provider = React.useContext(LocaleContext);
2039
+ const element = React.useContext(LocaleElementContext);
2040
+ const [wrap] = React.useState(() => scope !== undefined || !element?.current?.contains(target));
2041
+ if (!provider || !wrap)
2042
+ return jsxRuntime.jsx(jsxRuntime.Fragment, { children: children });
2043
+ const values = scope ?? provider;
2044
+ return (jsxRuntime.jsx("div", { dir: values.dir, lang: values.locale, style: displayContents, children: children }));
2045
+ }
2046
+
2047
+ // INTERNAL: deliberately not exported from src/index.ts. Number formatting
2048
+ // and text matching in a LocaleProvider's locale. Both return `null` outside
2049
+ // a provider that gives a locale, so each caller keeps the formatting and the
2050
+ // matching it has always had there.
2051
+ /** A combining mark: an accent, a vowel sign or a point written on a letter. */
2052
+ const MARK = /\p{M}/u;
2053
+ /**
2054
+ * The locale a component formats and matches in: inside a `LocaleProvider`,
2055
+ * the component's own locale when it has one (a picker's `locale`), else the
2056
+ * provider's; outside a provider, none.
2057
+ */
2058
+ function useScopedLocale(own) {
2059
+ const scope = useLocaleScope();
2060
+ if (!scope)
2061
+ return undefined;
2062
+ return scope.locale;
2063
+ }
2064
+ /**
2065
+ * A formatter for numbers shown on screen, in the locale of the
2066
+ * `LocaleProvider` around the component, or `null` outside one that gives a
2067
+ * locale. Formatters are kept per set of options, since building one is the
2068
+ * expensive part.
2069
+ *
2070
+ * @param own - The component's own locale, such as a picker's `locale`,
2071
+ * which wins inside a provider.
2072
+ */
2073
+ function useNumberFormat(own) {
2074
+ const locale = useScopedLocale();
2075
+ return React.useMemo(() => {
2076
+ if (!locale)
2077
+ return null;
2078
+ const formats = new Map();
2079
+ return (value, options) => {
2080
+ const key = options ? JSON.stringify(options) : '';
2081
+ let format = formats.get(key);
2082
+ if (!format) {
2083
+ format = new Intl.NumberFormat(locale, options);
2084
+ formats.set(key, format);
2085
+ }
2086
+ return format.format(value);
2087
+ };
2088
+ }, [locale]);
2089
+ }
2090
+ /**
2091
+ * A matcher for filtering a list by what was typed, in the locale of the
2092
+ * `LocaleProvider` around the component, or `null` outside one that gives a
2093
+ * locale. It compares with `Intl.Collator` at `usage: 'search'` and
2094
+ * `sensitivity: 'base'`, so it ignores case and accents where the language
2095
+ * treats the letters as the same: "cafe" finds "Café", while in Swedish "a"
2096
+ * doesn't find "å", a letter of its own there. Marks the language ignores
2097
+ * count for nothing on either side, so in Arabic محمد finds مُحَمَّد and the
2098
+ * other way round. An empty query, or one of nothing but such marks,
2099
+ * matches everything.
2100
+ */
2101
+ function useLocaleMatcher() {
2102
+ const locale = useScopedLocale();
2103
+ return React.useMemo(() => {
2104
+ if (!locale)
2105
+ return null;
2106
+ const collator = new Intl.Collator(locale, {
2107
+ usage: 'search',
2108
+ sensitivity: 'base',
2109
+ });
2110
+ return (text, query) => {
2111
+ const needle = query.normalize('NFC');
2112
+ if (collator.compare(needle, '') === 0)
2113
+ return true;
2114
+ // Compared by code point, so a slice never splits a surrogate pair.
2115
+ const chars = Array.from(text.normalize('NFC'));
2116
+ const marks = chars.map(char => MARK.test(char));
2117
+ // A slice equal to the needle can be longer or shorter than it: the
2118
+ // marks the collator ignores, Arabic harakat or Hebrew niqqud, take
2119
+ // code points on one side and not the other, and the expansions the
2120
+ // collator makes, "ß" against "ss" or "æ" against "ae", turn one letter
2121
+ // into two. So each slice runs from a letter to just before the next
2122
+ // letter, never cutting a letter from its marks, and the slices from
2123
+ // one start grow until they hold twice the needle's letters, which
2124
+ // those expansions can't get past. That keeps the work proportional to
2125
+ // the text's length, however long a label is, rather than to its
2126
+ // square.
2127
+ const most = 2 * Array.from(needle).filter(char => !MARK.test(char)).length;
2128
+ for (let start = 0; start < chars.length; start++) {
2129
+ if (marks[start])
2130
+ continue;
2131
+ let letters = 0;
2132
+ for (let end = start + 1; end <= chars.length; end++) {
2133
+ if (!marks[end - 1])
2134
+ letters++;
2135
+ if (letters > most)
2136
+ break;
2137
+ if (marks[end])
2138
+ continue;
2139
+ if (collator.compare(chars.slice(start, end).join(''), needle) === 0) {
2140
+ return true;
2141
+ }
2142
+ }
2143
+ }
2144
+ return false;
2145
+ };
2146
+ }, [locale]);
2147
+ }
2148
+
1795
2149
  /**
1796
2150
  * The `Avatars` component renders an overlapping/stacked group of `Avatar`s, the "members" list pattern.
1797
2151
  *
@@ -1806,6 +2160,7 @@ function flattenChildren(children, keyPrefix = '') {
1806
2160
  */
1807
2161
  const AvatarsComponent = ({ className, max, size, shape, spacing = 'md', spaced = false, surplusLabel, style, children, ...props }) => {
1808
2162
  const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });
2163
+ const formatNumber = useNumberFormat();
1809
2164
  // A preset spacing maps to a class; a numeric spacing sets the CSS var inline
1810
2165
  // (mirrors Sidebar's inline --bulma-* width var).
1811
2166
  const isPresetSpacing = typeof spacing === 'string';
@@ -1837,11 +2192,14 @@ const AvatarsComponent = ({ className, max, size, shape, spacing = 'md', spaced
1837
2192
  React.cloneElement(child, {
1838
2193
  ...(size !== undefined ? { size } : {}),
1839
2194
  ...(shape !== undefined ? { shape } : {}),
1840
- })), overflowCount > 0 && (jsxRuntime.jsx(Avatar, { initials: `+${overflowCount}`, alt:
2195
+ })), overflowCount > 0 && (jsxRuntime.jsx(Avatar, { initials: formatNumber
2196
+ ? formatNumber(overflowCount, { signDisplay: 'always' })
2197
+ : `+${overflowCount}`, alt:
1841
2198
  // `||` (not a plain ternary): an empty string from surplusLabel
1842
2199
  // would make the bubble decorative (alt="") and hide the count
1843
2200
  // from assistive tech — fall back to the default label instead.
1844
- surplusLabel?.(overflowCount) || `${overflowCount} more`, size: size, shape: shape, className: surplusClass }))] }));
2201
+ surplusLabel?.(overflowCount) ||
2202
+ `${formatNumber ? formatNumber(overflowCount) : overflowCount} more`, size: size, shape: shape, className: surplusClass }))] }));
1845
2203
  };
1846
2204
  const Avatars = withSubComponents(AvatarsComponent, { Avatar }, 'Avatars');
1847
2205
 
@@ -1891,15 +2249,19 @@ const Badge = ({ className, badgeClassName, content, max = 99, dot = false, show
1891
2249
  // A negative or non-integer max is nonsensical; fall back to the default
1892
2250
  // rather than render e.g. "-1+" (mirrors Avatars' max sanitization).
1893
2251
  const sanitizedMax = Number.isInteger(max) && max >= 0 ? max : 99;
2252
+ const formatNumber = useNumberFormat();
1894
2253
  const displayValue = React.useMemo(() => {
1895
2254
  if (dot || !hasContent)
1896
2255
  return undefined;
1897
2256
  // max only applies to numeric content; any other node renders verbatim.
1898
2257
  if (typeof content === 'number') {
1899
- return content > sanitizedMax ? `${sanitizedMax}+` : String(content);
2258
+ const write = formatNumber ?? String;
2259
+ return content > sanitizedMax
2260
+ ? `${write(sanitizedMax)}+`
2261
+ : write(content);
1900
2262
  }
1901
2263
  return content;
1902
- }, [dot, hasContent, content, sanitizedMax]);
2264
+ }, [dot, hasContent, content, sanitizedMax, formatNumber]);
1903
2265
  // Only primitive content produces a meaningful aria-label; a custom node
1904
2266
  // supplies its own accessible text, so we leave role="status" unlabeled.
1905
2267
  const ariaLabel = typeof displayValue === 'string' || typeof displayValue === 'number'
@@ -3970,6 +4332,17 @@ function usePortalContainer() {
3970
4332
  * also reaches what the library's components portal, such as Popover's
3971
4333
  * `appendToBody` panel or a `Modal` with `portal`.
3972
4334
  *
4335
+ * Inside a `LocaleProvider`, the children keep its `dir` and `lang`. A
4336
+ * container inside the provider's own wrapper takes the children as they
4337
+ * are, and they follow the provider through the page. Any other,
4338
+ * `document.body` included, gets them inside one `<div>` carrying the
4339
+ * provider's values, with `display: contents` so it adds no box. It is
4340
+ * still an element, so content that must be the container's direct child,
4341
+ * a `<tr>` in a `<tbody>`, or that a direct-child selector styles, belongs
4342
+ * in a container inside the provider. Which of the two is settled when the
4343
+ * children mount, so a change of locale updates them in place rather than
4344
+ * remounting them.
4345
+ *
3973
4346
  * Tab order and focus follow the DOM too. Content portaled from inside a
3974
4347
  * focus trap is no longer inside the trapped element, so the trap neither
3975
4348
  * reaches it nor holds focus there: render nested overlays inside the
@@ -3999,7 +4372,8 @@ function Portal({ children, container, disabled = false }) {
3999
4372
  return jsxRuntime.jsx(jsxRuntime.Fragment, { children: children });
4000
4373
  if (!hydrated)
4001
4374
  return null;
4002
- return reactDom.createPortal(children, resolveContainer(container));
4375
+ const target = resolveContainer(container);
4376
+ return reactDom.createPortal(jsxRuntime.jsx(LocalePortalScope, { target: target, children: children }), target);
4003
4377
  }
4004
4378
 
4005
4379
  // INTERNAL: deliberately not exported from src/index.ts.
@@ -4911,7 +5285,7 @@ const ModalRoot = React.forwardRef(function ModalRoot({ active, isActive, onClos
4911
5285
  modalElement = (jsxRuntime.jsx(ModalCloseContext.Provider, { value: onClose, children: modalElement }));
4912
5286
  if (isPortaled) {
4913
5287
  const target = resolveContainer(typeof portal === 'boolean' ? undefined : portal);
4914
- return reactDom.createPortal(modalElement, target);
5288
+ return reactDom.createPortal(jsxRuntime.jsx(LocalePortalScope, { target: target, children: modalElement }), target);
4915
5289
  }
4916
5290
  return modalElement;
4917
5291
  });
@@ -5322,6 +5696,7 @@ const PaginationComponent = ({ color, textColor, bgColor, size, align, rounded,
5322
5696
  backgroundColor: bgColor,
5323
5697
  ...props,
5324
5698
  });
5699
+ const formatNumber = useNumberFormat();
5325
5700
  // Generate Bulma classes with prefix
5326
5701
  const bulmaClasses = usePrefixedClassNames('pagination', {
5327
5702
  [`is-${color}`]: color,
@@ -5364,7 +5739,13 @@ const PaginationComponent = ({ color, textColor, bgColor, size, align, rounded,
5364
5739
  });
5365
5740
  const atStart = disabled || page <= 1;
5366
5741
  const atEnd = disabled || page >= pages;
5367
- content = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(PaginationPrevious, { disabled: atStart, ...linkTo(page - 1, atStart), children: previousLabel }), jsxRuntime.jsx(PaginationNext, { disabled: atEnd, ...linkTo(page + 1, atEnd), children: nextLabel }), jsxRuntime.jsx(PaginationList, { children: pageItems(pages, page, whole(siblingCount, 1), whole(boundaryCount, 1)).map(item => typeof item === 'number' ? (jsxRuntime.jsx(PaginationLink, { "aria-label": getPageLabel ? getPageLabel(item) : `Page ${item}`, active: item === page, disabled: disabled, ...linkTo(item, Boolean(disabled)), children: item }, item)) : (jsxRuntime.jsx(PaginationEllipsis, {}, item))) })] }));
5742
+ content = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(PaginationPrevious, { disabled: atStart, ...linkTo(page - 1, atStart), children: previousLabel }), jsxRuntime.jsx(PaginationNext, { disabled: atEnd, ...linkTo(page + 1, atEnd), children: nextLabel }), jsxRuntime.jsx(PaginationList, { children: pageItems(pages, page, whole(siblingCount, 1), whole(boundaryCount, 1)).map(item => {
5743
+ if (typeof item !== 'number') {
5744
+ return jsxRuntime.jsx(PaginationEllipsis, {}, item);
5745
+ }
5746
+ const shown = formatNumber ? formatNumber(item) : item;
5747
+ return (jsxRuntime.jsx(PaginationLink, { "aria-label": getPageLabel ? getPageLabel(item) : `Page ${shown}`, active: item === page, disabled: disabled, ...linkTo(item, Boolean(disabled)), children: shown }, item));
5748
+ }) })] }));
5368
5749
  }
5369
5750
  return (jsxRuntime.jsx("nav", { className: paginationClasses, role: "navigation", "aria-label": "pagination", ...rest, children: content }));
5370
5751
  };
@@ -8069,6 +8450,7 @@ const ContextMenu = withSubComponents(ContextMenuComponent, {
8069
8450
  */
8070
8451
  const Step = ({ isActive = false, isCompleted = false, label, icon, clickable = false, onClick, stepNumber, completedIcon, className, children, ...props }) => {
8071
8452
  const { bulmaHelperClasses, rest } = useBulmaClasses(props);
8453
+ const formatNumber = useNumberFormat();
8072
8454
  const stepClasses = classNames(usePrefixedClassNames('steps-segment', {
8073
8455
  'is-active': isActive,
8074
8456
  'is-completed': isCompleted,
@@ -8081,7 +8463,9 @@ const Step = ({ isActive = false, isCompleted = false, label, icon, clickable =
8081
8463
  const markerContent = icon ||
8082
8464
  (isCompleted && resolvedCompletedIcon
8083
8465
  ? resolvedCompletedIcon
8084
- : (stepNumber ?? null));
8466
+ : stepNumber == null || !formatNumber
8467
+ ? (stepNumber ?? null)
8468
+ : formatNumber(stepNumber));
8085
8469
  const title = label || children;
8086
8470
  const current = isActive ? 'step' : undefined;
8087
8471
  // The step stays a list item, and a real button inside it does the
@@ -8786,7 +9170,8 @@ const SidebarComponent = React.forwardRef(({ isOpen, onClose, position = 'left',
8786
9170
  }
8787
9171
  // Render to portal for proper stacking
8788
9172
  if (typeof document !== 'undefined') {
8789
- return reactDom.createPortal(sidebarContent, resolveContainer());
9173
+ const target = resolveContainer();
9174
+ return reactDom.createPortal(jsxRuntime.jsx(LocalePortalScope, { target: target, children: sidebarContent }), target);
8790
9175
  }
8791
9176
  return null;
8792
9177
  });
@@ -9051,7 +9436,8 @@ const Toast = React.forwardRef(({ message, type = 'default', actionType, positio
9051
9436
  }
9052
9437
  const toastContent = jsxRuntime.jsx("div", { className: containerClasses, children: toastElement });
9053
9438
  if (typeof document !== 'undefined') {
9054
- return reactDom.createPortal(toastContent, resolveContainer(container));
9439
+ const target = resolveContainer(container);
9440
+ return reactDom.createPortal(jsxRuntime.jsx(LocalePortalScope, { target: target, children: toastContent }), target);
9055
9441
  }
9056
9442
  return null;
9057
9443
  });
@@ -9213,10 +9599,11 @@ const ToastContainer = ({ position = 'top-right' }) => {
9213
9599
  return null;
9214
9600
  }
9215
9601
  const stacks = groupIntoPositionStacks(toastList, t => t.props.position, position, toastStackOrder);
9216
- return reactDom.createPortal(stacks.map(stack => (jsxRuntime.jsx("div", { className: `toast-container is-${stack.position}`, children: stack.items.map(t => {
9217
- const { queue: _queue, ...toastProps } = t.props;
9218
- return (jsxRuntime.jsx(Toast, { ...toastProps, position: stack.position, onClose: () => toast.close(t.id) }, t.id));
9219
- }) }, stack.key))), resolveContainer());
9602
+ const target = resolveContainer();
9603
+ return reactDom.createPortal(jsxRuntime.jsx(LocalePortalScope, { target: target, children: stacks.map(stack => (jsxRuntime.jsx("div", { className: `toast-container is-${stack.position}`, children: stack.items.map(t => {
9604
+ const { queue: _queue, ...toastProps } = t.props;
9605
+ return (jsxRuntime.jsx(Toast, { ...toastProps, position: stack.position, onClose: () => toast.close(t.id) }, t.id));
9606
+ }) }, stack.key))) }), target);
9220
9607
  };
9221
9608
 
9222
9609
  /**
@@ -10566,6 +10953,22 @@ const useInsideControl = () => React.useContext(ControlContext);
10566
10953
  const FieldProvider = FieldContext.Provider;
10567
10954
  /** Provider for Control context — used internally by Control component. */
10568
10955
  const ControlProvider = ControlContext.Provider;
10956
+ const FieldsetDisabledContext = React.createContext(false);
10957
+ /**
10958
+ * An input's `disabled`: its own prop when the caller set one, otherwise
10959
+ * whether a disabled `Fieldset` holds it. A `<fieldset disabled>` disables the
10960
+ * native controls inside on its own, and this carries the same state to what
10961
+ * the browser doesn't reach, such as Rate's stars, the time wheels, and the
10962
+ * `is-disabled` classes. The content of a Fieldset's legend reads the state
10963
+ * from outside that Fieldset, as the browser leaves the first legend's
10964
+ * controls enabled. Internal; not part of the public API.
10965
+ */
10966
+ const useFieldsetDisabled = (disabled) => {
10967
+ const inherited = React.useContext(FieldsetDisabledContext);
10968
+ return disabled ?? inherited;
10969
+ };
10970
+ /** Provider for a Fieldset's disabled state, used internally by Fieldset. */
10971
+ const FieldsetDisabledProvider = FieldsetDisabledContext.Provider;
10569
10972
  // Each Field-shaping prop, with what takes its place on a `Field` the caller
10570
10973
  // wraps around the `Control`. `message` needs nothing there, because the
10571
10974
  // wrapper still renders it inside `Field > Control`. The other Field-level
@@ -10847,7 +11250,8 @@ const checkboxSizes = ['small', 'normal', 'medium', 'large'];
10847
11250
  * <Checkbox value="vue">Vue</Checkbox>
10848
11251
  * </Checkboxes>
10849
11252
  */
10850
- const Checkbox = React.forwardRef(({ color, size, className, children, textColor, disabled, name, value, checked, defaultChecked, indeterminate, onChange, ...props }, ref) => {
11253
+ const Checkbox = React.forwardRef(({ color, size, className, children, textColor, disabled: disabledProp, name, value, checked, defaultChecked, indeterminate, onChange, ...props }, ref) => {
11254
+ const disabled = useFieldsetDisabled(disabledProp);
10851
11255
  const { bulmaHelperClasses, rest } = useBulmaClasses({
10852
11256
  color: textColor,
10853
11257
  ...props,
@@ -12082,7 +12486,8 @@ const Field = withSubComponents(FieldComponent, {
12082
12486
  * @returns {JSX.Element} The rendered input element.
12083
12487
  * @see {@link https://bulma.io/documentation/form/input/ | Bulma Input documentation}
12084
12488
  */
12085
- const InputBase = React.forwardRef(({ color, size, isRounded, isStatic, isHovered, isFocused, isLoading, className, disabled, readOnly, ...props }, ref) => {
12489
+ const InputBase = React.forwardRef(({ color, size, isRounded, isStatic, isHovered, isFocused, isLoading, className, disabled: disabledProp, readOnly, ...props }, ref) => {
12490
+ const disabled = useFieldsetDisabled(disabledProp);
12086
12491
  const { bulmaHelperClasses, rest } = useBulmaClasses({
12087
12492
  color,
12088
12493
  ...props,
@@ -12339,20 +12744,26 @@ function setRefs$1(node, own, forwarded) {
12339
12744
  /**
12340
12745
  * The default filter: the actions whose label, keywords or description hold
12341
12746
  * the search, ignoring case and the spaces around it, label matches first and
12342
- * the order otherwise kept. An empty search keeps them all.
12747
+ * the order otherwise kept. An empty search keeps them all. `matchText`, a
12748
+ * `LocaleProvider`'s locale-aware matcher, replaces the lowercased
12749
+ * comparison when there is one.
12343
12750
  */
12344
- const filterActions = (query, actions) => {
12345
- const term = query.trim().toLowerCase();
12346
- if (term === '')
12751
+ const filterActions = (query, actions, matchText) => {
12752
+ const search = query.trim();
12753
+ if (search === '')
12347
12754
  return actions;
12755
+ const term = search.toLowerCase();
12756
+ const holds = matchText
12757
+ ? (text) => matchText(text, search)
12758
+ : (text) => text.toLowerCase().includes(term);
12348
12759
  const byLabel = [];
12349
12760
  const byOther = [];
12350
12761
  for (const action of actions) {
12351
- if (action.label.toLowerCase().includes(term)) {
12762
+ if (holds(action.label)) {
12352
12763
  byLabel.push(action);
12353
12764
  }
12354
- else if (action.description?.toLowerCase().includes(term) ||
12355
- action.keywords?.some(keyword => keyword.toLowerCase().includes(term))) {
12765
+ else if ((action.description !== undefined && holds(action.description)) ||
12766
+ action.keywords?.some(holds)) {
12356
12767
  byOther.push(action);
12357
12768
  }
12358
12769
  }
@@ -12588,9 +12999,12 @@ CommandEmpty.displayName = 'CommandEmpty';
12588
12999
  * The field, and the actions that match the search, grouped, or the empty
12589
13000
  * message. The search is the parts root's, read from its context.
12590
13001
  */
12591
- const CommandActionsContent = ({ actions, filter = filterActions, placeholder, empty, }) => {
13002
+ const CommandActionsContent = ({ actions, filter, placeholder, empty, }) => {
12592
13003
  const { query } = useCommand();
12593
- const shown = filter(query, actions);
13004
+ const matchText = useLocaleMatcher();
13005
+ const shown = filter
13006
+ ? filter(query, actions)
13007
+ : filterActions(query, actions, matchText);
12594
13008
  // Each group where the matches first name it, and the actions with none
12595
13009
  // together where the first of them is, so the best match stays on top.
12596
13010
  const sections = new Map();
@@ -13740,7 +14154,8 @@ const NotificationContainer = ({ position = 'top-right' }) => {
13740
14154
  return null;
13741
14155
  }
13742
14156
  const stacks = groupIntoPositionStacks(items, item => item.options.position, position, notificationStackOrder);
13743
- return reactDom.createPortal(jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [stacks.map(stack => (jsxRuntime.jsx("div", { style: notificationStackStyle(stack.position), children: stack.items.map(item => (jsxRuntime.jsx(NotificationItem, { instance: item, onClose: notification.close, registerMessage: registerMessage }, item.id))) }, stack.key))), jsxRuntime.jsx(StatusRegion, { items: politeItems, describe: describe })] }), resolveContainer());
14157
+ const target = resolveContainer();
14158
+ return reactDom.createPortal(jsxRuntime.jsxs(LocalePortalScope, { target: target, children: [stacks.map(stack => (jsxRuntime.jsx("div", { style: notificationStackStyle(stack.position), children: stack.items.map(item => (jsxRuntime.jsx(NotificationItem, { instance: item, onClose: notification.close, registerMessage: registerMessage }, item.id))) }, stack.key))), jsxRuntime.jsx(StatusRegion, { items: politeItems, describe: describe })] }), target);
13744
14159
  };
13745
14160
 
13746
14161
  /**
@@ -13886,13 +14301,17 @@ const RingProgress = React.forwardRef(({ className, textColor, bgColor, value, m
13886
14301
  const labelClass = usePrefixedClassNames('ring-progress-label');
13887
14302
  // A section's color class, prefixed like the rest.
13888
14303
  const classPrefix = useClassPrefix();
14304
+ const formatNumber = useNumberFormat();
14305
+ const writeShare = (share) => formatNumber
14306
+ ? formatNumber(share / 100, { style: 'percent' })
14307
+ : `${share}%`;
13889
14308
  const roleProps = sections
13890
14309
  ? {
13891
14310
  role: 'img',
13892
14311
  'aria-label': [
13893
14312
  label || rest['aria-label'],
13894
14313
  sections
13895
- .map((section, i) => `${section.label} ${Math.round(arcs[i].length)}%`)
14314
+ .map((section, i) => `${section.label} ${writeShare(Math.round(arcs[i].length))}`)
13896
14315
  .join(', '),
13897
14316
  ]
13898
14317
  .filter(Boolean)
@@ -14349,7 +14768,8 @@ const checkboxCardColors = [
14349
14768
  * <CheckboxCard value="domain" title="Custom domain" description="Bring your own." />
14350
14769
  * </Checkboxes>
14351
14770
  */
14352
- const CheckboxCard = React.forwardRef(({ title, description, children, hasIndicator = true, color, className, textColor, disabled, name, value, checked, defaultChecked, indeterminate, onChange, ...props }, ref) => {
14771
+ const CheckboxCard = React.forwardRef(({ title, description, children, hasIndicator = true, color, className, textColor, disabled: disabledProp, name, value, checked, defaultChecked, indeterminate, onChange, ...props }, ref) => {
14772
+ const disabled = useFieldsetDisabled(disabledProp);
14353
14773
  const { bulmaHelperClasses, rest } = useBulmaClasses({
14354
14774
  color: textColor,
14355
14775
  ...props,
@@ -14544,6 +14964,61 @@ const CheckboxesComponent = ({ label, labelSize, labelProps, horizontal, message
14544
14964
  };
14545
14965
  const Checkboxes = withSubComponents(CheckboxesComponent, { Checkbox }, 'Checkboxes');
14546
14966
 
14967
+ // What an unlabeled Field passes on: no label names anything inside.
14968
+ const NO_LABEL = {};
14969
+ /**
14970
+ * The `Fieldset` component groups a section of a form in a native
14971
+ * `<fieldset>`, named by its `legend`, which a `disabled` switches off as a
14972
+ * whole.
14973
+ *
14974
+ * It starts its own Field scope: inside it, nothing reads as inside a
14975
+ * `Field` or `Control`, so the convenience inputs render their own `Field`,
14976
+ * and a labeled `Field` around the Fieldset names nothing in it.
14977
+ *
14978
+ * @function
14979
+ * @param {FieldsetProps} props - Props for the Fieldset component.
14980
+ * @returns {JSX.Element} The rendered fieldset.
14981
+ *
14982
+ * @example
14983
+ * <Fieldset legend="Shipping address" message="We only ship within the EU.">
14984
+ * <Input label="Street" name="street" />
14985
+ * <Input label="City" name="city" />
14986
+ * </Fieldset>
14987
+ *
14988
+ * @example
14989
+ * // A form that's saving
14990
+ * <Fieldset disabled={saving} variant="unstyled">
14991
+ * <Input label="Name" name="name" />
14992
+ * <Rate label="Rating" name="rating" />
14993
+ * </Fieldset>
14994
+ */
14995
+ const Fieldset = React.forwardRef(({ legend, legendProps, variant = 'default', disabled, message, messageColor, textColor, bgColor, className, children, 'aria-describedby': ariaDescribedBy, ...props }, ref) => {
14996
+ const { bulmaHelperClasses, rest } = useBulmaClasses({
14997
+ color: textColor,
14998
+ backgroundColor: bgColor,
14999
+ ...props,
15000
+ });
15001
+ const mainClass = usePrefixedClassNames('fieldset', {
15002
+ 'is-filled': variant === 'filled',
15003
+ 'is-unstyled': variant === 'unstyled',
15004
+ });
15005
+ const legendClass = usePrefixedClassNames('fieldset-legend');
15006
+ const helpClass = usePrefixedClassNames('help', {
15007
+ [`is-${messageColor}`]: !!messageColor,
15008
+ });
15009
+ // The legend's controls take the state from outside, as the browser
15010
+ // leaves the first legend's controls enabled, and the content takes this
15011
+ // Fieldset's on top of it, as a disabled one disables those inside it.
15012
+ const outerDisabled = useFieldsetDisabled(undefined);
15013
+ const groupDisabled = !!disabled || outerDisabled;
15014
+ const messageId = `${React.useId()}-message`;
15015
+ const describedBy = [ariaDescribedBy, message ? messageId : undefined]
15016
+ .filter(Boolean)
15017
+ .join(' ') || undefined;
15018
+ return (jsxRuntime.jsx(FieldProvider, { value: false, children: jsxRuntime.jsx(ControlProvider, { value: false, children: jsxRuntime.jsx(FieldLabelIdProvider, { value: undefined, children: jsxRuntime.jsx(FieldLabelElementIdProvider, { value: undefined, children: jsxRuntime.jsx(FieldLabelForProvider, { value: NO_LABEL, children: jsxRuntime.jsx(FieldLabelForReportProvider, { value: undefined, children: jsxRuntime.jsxs("fieldset", { ref: ref, className: classNames(mainClass, bulmaHelperClasses, className), disabled: disabled, "aria-describedby": describedBy, ...rest, children: [legend ? (jsxRuntime.jsx("legend", { ...legendProps, className: classNames(legendClass, legendProps?.className), children: legend })) : null, jsxRuntime.jsx(FieldsetDisabledProvider, { value: groupDisabled, children: children }), message ? (jsxRuntime.jsx("p", { id: messageId, className: helpClass, children: message })) : null] }) }) }) }) }) }) }));
15019
+ });
15020
+ Fieldset.displayName = 'Fieldset';
15021
+
14547
15022
  /**
14548
15023
  * The `File` component provides a Bulma-styled file input, supporting color, size, boxed/fullwidth/align styles, icons, "has name", and filename display.
14549
15024
  *
@@ -14583,10 +15058,12 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
14583
15058
  : undefined);
14584
15059
  onChange?.(event);
14585
15060
  };
15061
+ const formatNumber = useNumberFormat();
14586
15062
  const pickedText = picked &&
14587
15063
  (picked.count === 1
14588
15064
  ? picked.firstName
14589
- : (pickedFilesLabel?.(picked.count) ?? `${picked.count} files`));
15065
+ : (pickedFilesLabel?.(picked.count) ??
15066
+ `${formatNumber ? formatNumber(picked.count) : picked.count} files`));
14590
15067
  const shownName = fileName ?? pickedText;
14591
15068
  const insideField = useInsideField();
14592
15069
  const insideControl = useInsideControl();
@@ -14704,7 +15181,8 @@ const radioSizes = ['small', 'normal', 'medium', 'large'];
14704
15181
  * <Radio value="blue">Blue</Radio>
14705
15182
  * </Radios>
14706
15183
  */
14707
- const Radio = React.forwardRef(({ color, size, className, children, textColor, disabled, name, value, checked, defaultChecked, onChange, ...props }, ref) => {
15184
+ const Radio = React.forwardRef(({ color, size, className, children, textColor, disabled: disabledProp, name, value, checked, defaultChecked, onChange, ...props }, ref) => {
15185
+ const disabled = useFieldsetDisabled(disabledProp);
14708
15186
  const { bulmaHelperClasses, rest } = useBulmaClasses({
14709
15187
  color: textColor,
14710
15188
  ...props,
@@ -14774,7 +15252,8 @@ const radioCardColors = [
14774
15252
  * <RadioCard value="express" title="Express" description="Arrives tomorrow." />
14775
15253
  * </Radios>
14776
15254
  */
14777
- const RadioCard = React.forwardRef(({ title, description, children, hasIndicator = true, color, className, textColor, disabled, name, value, checked, defaultChecked, onChange, ...props }, ref) => {
15255
+ const RadioCard = React.forwardRef(({ title, description, children, hasIndicator = true, color, className, textColor, disabled: disabledProp, name, value, checked, defaultChecked, onChange, ...props }, ref) => {
15256
+ const disabled = useFieldsetDisabled(disabledProp);
14778
15257
  const { bulmaHelperClasses, rest } = useBulmaClasses({
14779
15258
  color: textColor,
14780
15259
  ...props,
@@ -14973,7 +15452,8 @@ const switchSizes = ['small', 'normal', 'medium', 'large'];
14973
15452
  * Feature enabled
14974
15453
  * </Switch>
14975
15454
  */
14976
- const Switch = React.forwardRef(({ color, size, isRounded, isThin, isOutlined, isRtl, passiveType, className, children, textColor, disabled, ...props }, ref) => {
15455
+ const Switch = React.forwardRef(({ color, size, isRounded, isThin, isOutlined, isRtl, passiveType, className, children, textColor, disabled: disabledProp, ...props }, ref) => {
15456
+ const disabled = useFieldsetDisabled(disabledProp);
14977
15457
  const { bulmaHelperClasses, rest } = useBulmaClasses({
14978
15458
  color: textColor,
14979
15459
  ...props,
@@ -15075,10 +15555,11 @@ const Slider = React.forwardRef((props, ref) => {
15075
15555
  }
15076
15556
  // Destructure base / shared props from a `SliderBaseProps` view. None of
15077
15557
  // these fields differ between the two branches, so this view is safe.
15078
- const { label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, min = 0, max = 100, step = 1, size, color, isRounded = false, isCircle = false, disabled = false, showOutput = false, tooltip, ticks, marks, orientation = 'horizontal', scale, getAriaValueText, formatOutput, className,
15558
+ const { label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, min = 0, max = 100, step = 1, size, color, isRounded = false, isCircle = false, disabled: disabledProp, showOutput = false, tooltip, ticks, marks, orientation = 'horizontal', scale, getAriaValueText, formatOutput, className,
15079
15559
  // Strip the discriminated/union fields from `restProps` so they don't
15080
15560
  // flow back into `useBulmaClasses` / spread onto inputs.
15081
15561
  range: _range, value: _value, defaultValue: _defaultValue, onChange: _onChange, ariaLabel: _ariaLabel, minDistance: _minDistance, nameLow: _nameLow, nameHigh: _nameHigh, ...restProps } = props;
15562
+ const disabled = useFieldsetDisabled(disabledProp);
15082
15563
  const insideField = useInsideField();
15083
15564
  const insideControl = useInsideControl();
15084
15565
  const ownField = rendersOwnField('Slider', {
@@ -15174,11 +15655,13 @@ const Slider = React.forwardRef((props, ref) => {
15174
15655
  : 0;
15175
15656
  // Scale helper
15176
15657
  const scaleValue = React.useCallback((v) => (scale ? scale(v) : v), [scale]);
15177
- // Format helper
15658
+ // Format helper: the caller's, else the locale's, else the number as is.
15659
+ const formatNumber = useNumberFormat();
15660
+ const writeNumber = React.useCallback((v) => (formatNumber ? formatNumber(v) : v.toString()), [formatNumber]);
15178
15661
  const formatValue = React.useCallback((v) => {
15179
15662
  const scaled = scaleValue(v);
15180
- return formatOutput ? formatOutput(scaled) : scaled.toString();
15181
- }, [formatOutput, scaleValue]);
15663
+ return formatOutput ? formatOutput(scaled) : writeNumber(scaled);
15664
+ }, [formatOutput, scaleValue, writeNumber]);
15182
15665
  // --- Handlers ---
15183
15666
  const handleSingleChange = React.useCallback((e) => {
15184
15667
  const newValue = parseFloat(e.target.value);
@@ -15298,7 +15781,7 @@ const Slider = React.forwardRef((props, ref) => {
15298
15781
  ariaProps['aria-valuetext'] = getAriaValueText(value);
15299
15782
  }
15300
15783
  else if (scale) {
15301
- ariaProps['aria-valuetext'] = scaleValue(value).toString();
15784
+ ariaProps['aria-valuetext'] = writeNumber(scaleValue(value));
15302
15785
  }
15303
15786
  return ariaProps;
15304
15787
  };
@@ -15498,7 +15981,8 @@ const ArrowDropDown = () => (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill:
15498
15981
  */
15499
15982
  const Numberinput = React.forwardRef(({
15500
15983
  // Field props
15501
- label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue, min, max, step = 1, size, color, inputColor, controlsPosition = 'both', controlsRounded = false, compact = false, bare, variant = 'plusminus', disabled = false, editable = true, isLoading = false, exponential = false, onChange, className, ...props }, ref) => {
15984
+ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue, min, max, step = 1, size, color, inputColor, controlsPosition = 'both', controlsRounded = false, compact = false, bare, variant = 'plusminus', disabled: disabledProp, editable = true, isLoading = false, exponential = false, onChange, className, ...props }, ref) => {
15985
+ const disabled = useFieldsetDisabled(disabledProp);
15502
15986
  const insideField = useInsideField();
15503
15987
  // Bare controls join their parent's row, which a `.control` does not lay
15504
15988
  // out. `useInsideControl()` is true anywhere below a `Control`, even past
@@ -15708,7 +16192,8 @@ const toAsciiDigits = (text) => text.replace(/\p{Nd}/gu, digit => {
15708
16192
  */
15709
16193
  const PinInput = React.forwardRef(({
15710
16194
  // Field props
15711
- label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, length = 6, value: controlledValue, defaultValue = '', type = 'number', isMasked = false, color, size, isRounded = false, disabled = false, onChange, onComplete, onPaste, onFocus, onBlur, className, ...props }, ref) => {
16195
+ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, length = 6, value: controlledValue, defaultValue = '', type = 'number', isMasked = false, color, size, isRounded = false, disabled: disabledProp, onChange, onComplete, onPaste, onFocus, onBlur, className, ...props }, ref) => {
16196
+ const disabled = useFieldsetDisabled(disabledProp);
15712
16197
  const insideField = useInsideField();
15713
16198
  const insideControl = useInsideControl();
15714
16199
  const ownField = rendersOwnField('PinInput', {
@@ -15891,7 +16376,8 @@ function getFillPercent(iconIndex, value) {
15891
16376
  * // With Font Awesome icons
15892
16377
  * <Rate iconName="star" iconLibrary="fa" iconVariant="solid" />
15893
16378
  */
15894
- const Rate = React.forwardRef(({ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue = 0, max = 5, size, disabled = false, showScore = false, showText = false, texts, onChange, customIcon, spaced = false, rtl = false, iconName, iconLibrary: iconLibraryProp, iconVariant, iconFeatures, color, precision = 1, customText, name, form, className, ...props }, ref) => {
16379
+ const Rate = React.forwardRef(({ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue = 0, max = 5, size, disabled: disabledProp, showScore = false, showText = false, texts, onChange, customIcon, spaced = false, rtl = false, iconName, iconLibrary: iconLibraryProp, iconVariant, iconFeatures, color, precision = 1, customText, name, form, className, ...props }, ref) => {
16380
+ const disabled = useFieldsetDisabled(disabledProp);
15895
16381
  const insideField = useInsideField();
15896
16382
  const insideControl = useInsideControl();
15897
16383
  const ownField = rendersOwnField('Rate', {
@@ -15909,6 +16395,7 @@ const Rate = React.forwardRef(({ label, labelSize, labelProps, horizontal, messa
15909
16395
  callerProps: props,
15910
16396
  });
15911
16397
  const { bulmaHelperClasses, rest } = useBulmaClasses(props);
16398
+ const formatNumber = useNumberFormat();
15912
16399
  const starBaseId = React.useId();
15913
16400
  const [internalValue, setInternalValue] = React.useState(defaultValue);
15914
16401
  const [hoverValue, setHoverValue] = React.useState(null);
@@ -16017,7 +16504,13 @@ const Rate = React.forwardRef(({ label, labelSize, labelProps, horizontal, messa
16017
16504
  };
16018
16505
  // Format score display
16019
16506
  const getScoreDisplay = () => {
16020
- if (precision < 1 && currentValue % 1 !== 0) {
16507
+ const fractional = precision < 1 && currentValue % 1 !== 0;
16508
+ if (formatNumber) {
16509
+ return formatNumber(currentValue, fractional
16510
+ ? { minimumFractionDigits: 1, maximumFractionDigits: 1 }
16511
+ : undefined);
16512
+ }
16513
+ if (fractional) {
16021
16514
  return currentValue.toFixed(1);
16022
16515
  }
16023
16516
  return currentValue;
@@ -16161,7 +16654,7 @@ const isEnabled = (item) => typeof item === 'string' || !item.disabled;
16161
16654
  * onSelect={(item) => console.log(item)}
16162
16655
  * />
16163
16656
  */
16164
- const Autocomplete = React.forwardRef(({ data = [], value: controlledValue, placeholder, field = 'label', clearable = false, openOnFocus = false, keepFirst = false, keepOpen = false, selectOnClickOutside = false, maxHeight = 200, loading = false, disabled = false, checkInfiniteScroll = false, infiniteScrollDistance = 50, color, size, onInput, onSelect, onActiveChange, onInfiniteScroll, itemTemplate, header, footer, empty, name, form, required, id,
16657
+ const Autocomplete = React.forwardRef(({ data = [], value: controlledValue, placeholder, field = 'label', clearable = false, openOnFocus = false, keepFirst = false, keepOpen = false, selectOnClickOutside = false, maxHeight = 200, loading = false, disabled: disabledProp, checkInfiniteScroll = false, infiniteScrollDistance = 50, color, size, onInput, onSelect, onActiveChange, onInfiniteScroll, itemTemplate, header, footer, empty, name, form, required, id,
16165
16658
  // Deprecated no-ops, taken here so they stay off the wrapper.
16166
16659
  // eslint-disable-next-line @typescript-eslint/no-unused-vars -- deprecated no-op
16167
16660
  selected,
@@ -16169,6 +16662,7 @@ selected,
16169
16662
  dropdown,
16170
16663
  // Field props
16171
16664
  label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, className, ...props }, ref) => {
16665
+ const disabled = useFieldsetDisabled(disabledProp);
16172
16666
  const insideField = useInsideField();
16173
16667
  // The suggestion list points `aria-labelledby` at the label that names
16174
16668
  // the input, so it needs that label's id.
@@ -16180,6 +16674,7 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
16180
16674
  needsLabelId: true,
16181
16675
  });
16182
16676
  const { bulmaHelperClasses, rest } = useBulmaClasses(props);
16677
+ const matchText = useLocaleMatcher();
16183
16678
  const { classPrefix } = useConfig();
16184
16679
  const containerRef = React.useRef(null);
16185
16680
  const inputRef = React.useRef(null);
@@ -16209,6 +16704,8 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
16209
16704
  // Filter data based on input
16210
16705
  const filteredData = data.filter(item => {
16211
16706
  const displayValue = getDisplayValue(item);
16707
+ if (matchText)
16708
+ return matchText(displayValue, inputValue);
16212
16709
  return displayValue.toLowerCase().includes(inputValue.toLowerCase());
16213
16710
  });
16214
16711
  // The dropdown shows the options or, when nothing matches, the `empty`
@@ -16891,7 +17388,8 @@ const asList = (value) => value == null ? [] : Array.isArray(value) ? value : [v
16891
17388
  const ComboboxFromData = React.forwardRef((props, ref) => {
16892
17389
  const { data, value, defaultValue,
16893
17390
  // Called below through `props`, which knows which value it takes.
16894
- onChange: _onChange, multiple = false, placeholder, name, empty, itemTemplate, onSelect, onOpenChange, inline = false, disabled = false, required = false, form, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ariaCloseLabel, children, ...rest } = props;
17391
+ onChange: _onChange, multiple = false, placeholder, name, empty, itemTemplate, onSelect, onOpenChange, inline = false, disabled: disabledProp, required = false, form, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ariaCloseLabel, children, ...rest } = props;
17392
+ const disabled = useFieldsetDisabled(disabledProp);
16895
17393
  // A name given in place of a label is the field's and the list's, not
16896
17394
  // the wrapper's. Only the ones given are passed, since an
16897
17395
  // `aria-labelledby` that's there at all, even undefined, keeps the
@@ -16914,6 +17412,7 @@ const ComboboxFromData = React.forwardRef((props, ref) => {
16914
17412
  };
16915
17413
  const controlled = value !== undefined;
16916
17414
  const [ownValue, setOwnValue] = React.useState(() => asList(defaultValue));
17415
+ const matchText = useLocaleMatcher();
16917
17416
  const picked = controlled ? asList(value) : ownValue;
16918
17417
  const change = (next) => {
16919
17418
  if (!controlled)
@@ -16941,8 +17440,11 @@ const ComboboxFromData = React.forwardRef((props, ref) => {
16941
17440
  }
16942
17441
  setQuery(null);
16943
17442
  };
16944
- const term = (query ?? '').trim().toLowerCase();
16945
- const shown = items.filter(item => labelOf(item).toLowerCase().includes(term));
17443
+ const typed = (query ?? '').trim();
17444
+ const term = typed.toLowerCase();
17445
+ const shown = items.filter(item => matchText
17446
+ ? matchText(labelOf(item), typed)
17447
+ : labelOf(item).toLowerCase().includes(term));
16946
17448
  const inputRef = React.useRef(null);
16947
17449
  const select = (pick) => {
16948
17450
  onSelect?.(pick);
@@ -17086,7 +17588,8 @@ const isComposing = (e) => e.nativeEvent.isComposing || e.nativeEvent.keyCode ==
17086
17588
  */
17087
17589
  const Taginput = React.forwardRef(({
17088
17590
  // Field props
17089
- label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue = [], data: dataProp, placeholder, field = 'label', allowNew = true, allowDuplicates = false, openOnFocus = false, removeOnKeys = true, confirmKeys = ['Enter', ','], closable = true, attached = false, maxTags, maxlength, disabled = false, readonly = false, rounded = false, ellipsis = false, hasCounter = true, onPasteSeparators = [','], beforeAdding, createTag, keepFirst = false, keepOpen = true, loading = false, ariaCloseLabel, icon, iconLibrary: iconLibraryProp, iconVariant, iconFeatures, color, tagColor, size, onChange, onAdd, onRemove, onTyping, tagTemplate, name, form, id, className, ...props }, ref) => {
17591
+ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue = [], data: dataProp, placeholder, field = 'label', allowNew = true, allowDuplicates = false, openOnFocus = false, removeOnKeys = true, confirmKeys = ['Enter', ','], closable = true, attached = false, maxTags, maxlength, disabled: disabledProp, readonly = false, rounded = false, ellipsis = false, hasCounter = true, onPasteSeparators = [','], beforeAdding, createTag, keepFirst = false, keepOpen = true, loading = false, ariaCloseLabel, icon, iconLibrary: iconLibraryProp, iconVariant, iconFeatures, color, tagColor, size, onChange, onAdd, onRemove, onTyping, tagTemplate, name, form, id, className, ...props }, ref) => {
17592
+ const disabled = useFieldsetDisabled(disabledProp);
17090
17593
  const insideField = useInsideField();
17091
17594
  const insideControl = useInsideControl();
17092
17595
  const ownField = rendersOwnField('Taginput', {
@@ -17100,6 +17603,8 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
17100
17603
  const { bulmaHelperClasses, rest } = useBulmaClasses(props);
17101
17604
  const { classPrefix } = useConfig();
17102
17605
  const defaultIconLibrary = useIconLibrary();
17606
+ const formatNumber = useNumberFormat();
17607
+ const matchText = useLocaleMatcher();
17103
17608
  const resolvedLibrary = iconLibraryProp || defaultIconLibrary || 'fa';
17104
17609
  const pcn = (...args) => prefixedClassNames(classPrefix, ...args);
17105
17610
  const containerRef = React.useRef(null);
@@ -17141,7 +17646,9 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
17141
17646
  // Filter autocomplete data
17142
17647
  const filteredData = data.filter(item => {
17143
17648
  const displayValue = item.toLowerCase();
17144
- const matchesInput = displayValue.includes(inputValue.toLowerCase());
17649
+ const matchesInput = matchText
17650
+ ? matchText(item, inputValue)
17651
+ : displayValue.includes(inputValue.toLowerCase());
17145
17652
  const notAlreadyAdded = allowDuplicates ||
17146
17653
  !tags.some(tag => getDisplayValue(tag).toLowerCase() === displayValue);
17147
17654
  const hasInput = inputValue || (openOnFocus && isActive);
@@ -17391,10 +17898,11 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
17391
17898
  const combinedClasses = classNames(taginputClasses, bulmaHelperClasses, className);
17392
17899
  // Counter text
17393
17900
  const showCounter = hasCounter && (maxTags !== undefined || maxlength !== undefined);
17901
+ const write = formatNumber ?? String;
17394
17902
  const counterText = maxTags !== undefined
17395
- ? `${tags.length} / ${maxTags}`
17903
+ ? `${write(tags.length)} / ${write(maxTags)}`
17396
17904
  : maxlength !== undefined
17397
- ? `${inputValue.length} / ${maxlength}`
17905
+ ? `${write(inputValue.length)} / ${write(maxlength)}`
17398
17906
  : '';
17399
17907
  const counterClasses = pcn('help', 'counter');
17400
17908
  const tagsClasses = pcn('tags');
@@ -17457,7 +17965,8 @@ const TagInput = Taginput;
17457
17965
  * @returns {JSX.Element} The rendered select element.
17458
17966
  * @see {@link https://bulma.io/documentation/form/select/ | Bulma Select documentation}
17459
17967
  */
17460
- const SelectBase = React.forwardRef(({ color, size, isRounded, isLoading, isActive, isHovered, isFocused, isFullwidth, isFullWidth, className, disabled, children, multiple, multipleSize, ...props }, ref) => {
17968
+ const SelectBase = React.forwardRef(({ color, size, isRounded, isLoading, isActive, isHovered, isFocused, isFullwidth, isFullWidth, className, disabled: disabledProp, children, multiple, multipleSize, ...props }, ref) => {
17969
+ const disabled = useFieldsetDisabled(disabledProp);
17461
17970
  const { bulmaHelperClasses, rest } = useBulmaClasses({
17462
17971
  color,
17463
17972
  ...props,
@@ -17504,7 +18013,8 @@ SelectBase.displayName = 'SelectBase';
17504
18013
  * @returns {JSX.Element} The rendered textarea element.
17505
18014
  * @see {@link https://bulma.io/documentation/form/textarea/ | Bulma Textarea documentation}
17506
18015
  */
17507
- const TextAreaBase = React.forwardRef(({ color, size, isRounded, isStatic, isHovered, isFocused, isLoading: _isLoading, isActive, hasFixedSize, className, disabled, readOnly, rows, ...props }, ref) => {
18016
+ const TextAreaBase = React.forwardRef(({ color, size, isRounded, isStatic, isHovered, isFocused, isLoading: _isLoading, isActive, hasFixedSize, className, disabled: disabledProp, readOnly, rows, ...props }, ref) => {
18017
+ const disabled = useFieldsetDisabled(disabledProp);
17508
18018
  const { bulmaHelperClasses, rest } = useBulmaClasses({
17509
18019
  color,
17510
18020
  ...props,
@@ -19051,7 +19561,7 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
19051
19561
  Calendar.displayName = 'Calendar';
19052
19562
 
19053
19563
  const isBrowser = typeof window !== 'undefined';
19054
- const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'bottom-left', appendToBody = false, className, trapFocus = true, closeOnClickOutside = true, closeOnEscape = true, ariaLabel, ariaLabelledBy, role = 'dialog', id, restoreFocusRef, initialFocusSelector, }) => {
19564
+ const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'bottom-left', appendToBody = false, className, trapFocus = true, closeOnClickOutside = true, closeOnEscape = true, ariaLabel, ariaLabelledBy, role = 'dialog', id, restoreFocusRef, initialFocusSelector, localeScope, }) => {
19055
19565
  const panelRef = React.useRef(null);
19056
19566
  const resolveContainer = usePortalContainer();
19057
19567
  // Read as the trap turns on, once the panel's content has rendered.
@@ -19149,7 +19659,8 @@ const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'botto
19149
19659
  e.preventDefault();
19150
19660
  }, children: children }));
19151
19661
  if (appendToBody && isBrowser) {
19152
- return reactDom.createPortal(panel, resolveContainer());
19662
+ const target = resolveContainer();
19663
+ return reactDom.createPortal(jsxRuntime.jsx(LocalePortalScope, { target: target, scope: localeScope, children: panel }), target);
19153
19664
  }
19154
19665
  return panel;
19155
19666
  };
@@ -19951,6 +20462,79 @@ function supportsInputType(type) {
19951
20462
  return supported;
19952
20463
  }
19953
20464
 
20465
+ /**
20466
+ * A picker's locale: its own `locale`, else the one a `LocaleProvider` around
20467
+ * it sets, else `undefined`, which leaves `Intl` to use the runtime's.
20468
+ */
20469
+ function usePickerLocale(own) {
20470
+ const scope = useLocaleScope();
20471
+ return own || scope?.locale;
20472
+ }
20473
+ const NO_ROOT_ATTRS = {};
20474
+ /**
20475
+ * A picker's language and direction inside a `LocaleProvider`, by the rule a
20476
+ * nested provider follows: its `lang` is its own `locale`, else the
20477
+ * provider's, and its `dir` is the `dir` passed to it, else its own locale's
20478
+ * direction when it has one, else the provider's. Outside a provider it
20479
+ * changes nothing. A `locale` `Intl` refuses counts as none here, since the
20480
+ * picker's own formatting reports it.
20481
+ */
20482
+ function usePickerLocaleScope(ownLocale, ownDir) {
20483
+ const scope = useLocaleScope();
20484
+ return React.useMemo(() => {
20485
+ if (!scope)
20486
+ return { rootAttrs: NO_ROOT_ATTRS };
20487
+ let own;
20488
+ try {
20489
+ own = canonicalLocale(ownLocale);
20490
+ }
20491
+ catch {
20492
+ own = undefined;
20493
+ }
20494
+ const dir = ownDir || (own ? localeDirection(own) : scope.dir);
20495
+ return {
20496
+ rootAttrs: own ? { lang: own, dir } : NO_ROOT_ATTRS,
20497
+ panel: { locale: own || scope.locale, dir },
20498
+ };
20499
+ }, [scope, ownLocale, ownDir]);
20500
+ }
20501
+ /**
20502
+ * Whether a picker's `dayNames` replace the calendar's own, which `Calendar`
20503
+ * does only for a full week of seven.
20504
+ */
20505
+ function hasOwnDayNames(dayNames) {
20506
+ return dayNames !== undefined && dayNames.length === 7;
20507
+ }
20508
+ /**
20509
+ * The day a picker's week starts on: its own `firstDayOfWeek`, else, inside a
20510
+ * `LocaleProvider`, the first day of the locale the picker uses, else Sunday.
20511
+ * Outside a provider it stays Sunday whatever the locale, as it always has,
20512
+ * and so does a picker inside one with no locale from either, since the
20513
+ * runtime's own differs between the server and the browser.
20514
+ *
20515
+ * It also stays Sunday for a picker that brings its own `dayNames`. The
20516
+ * calendar shows those exactly as given, in calendar order, and before the
20517
+ * provider an unset `firstDayOfWeek` was always Sunday, so names written
20518
+ * Sunday first would sit a day or more off their columns if the week moved
20519
+ * under them.
20520
+ */
20521
+ function usePickerFirstDayOfWeek(own, locale, hasDayNames) {
20522
+ const inProvider = useLocaleScope() !== null;
20523
+ return React.useMemo(() => {
20524
+ if (own !== undefined)
20525
+ return own;
20526
+ if (!inProvider || !locale || hasDayNames)
20527
+ return 0;
20528
+ try {
20529
+ return localeFirstDay(canonicalLocale(locale));
20530
+ }
20531
+ catch {
20532
+ // A tag Intl refuses: the picker's own formatting says so.
20533
+ return 0;
20534
+ }
20535
+ }, [own, inProvider, locale, hasDayNames]);
20536
+ }
20537
+
19954
20538
  const DEFAULT_FORMATS = {
19955
20539
  day: DEFAULT_DATE_FORMAT,
19956
20540
  month: DEFAULT_MONTH_FORMAT,
@@ -19971,7 +20555,15 @@ const SKIPPED_SEGMENTS = {
19971
20555
  * @returns {JSX.Element}
19972
20556
  */
19973
20557
  const DateInputBase = React.forwardRef((props, ref) => {
19974
- const { value: controlledValue, defaultValue, onChange, onOpen, onClose, min, max, disabled, readOnly, placeholder, granularity = 'day', format, parse, locale, inline = false, mobileNative = 'auto', editable = true, popover = true, openOnFocus = true, closeOnSelect = true, position = 'bottom-left', appendToBody = false, color, size, isRounded, shouldDisableDate, unselectableDates, firstDayOfWeek = 0, dayNames, monthNames, nearbyMonthDays = true, className, name, form, required, id: idProp, onFocus, onClick, onKeyDown, onBlur, iconLeftName: _iconLeftName, triggerIcon: triggerIconProp, triggerIconName = 'chevron-down', labels, ...rest } = props;
20558
+ const { value: controlledValue, defaultValue, onChange, onOpen, onClose, min, max, disabled: disabledProp, readOnly, placeholder, granularity = 'day', format, parse, locale: localeProp, inline = false, mobileNative = 'auto', editable = true, popover = true, openOnFocus = true, closeOnSelect = true, position = 'bottom-left', appendToBody = false, color, size, isRounded, shouldDisableDate, unselectableDates, firstDayOfWeek: firstDayOfWeekProp, dayNames, monthNames, nearbyMonthDays = true, className, name, form, required, id: idProp, onFocus, onClick, onKeyDown, onBlur, iconLeftName: _iconLeftName, triggerIcon: triggerIconProp, triggerIconName = 'chevron-down', labels, ...rest } = props;
20559
+ // A LocaleProvider around the picker sets its default locale and, through
20560
+ // that locale, the day its week starts on.
20561
+ const locale = usePickerLocale(localeProp);
20562
+ // Its own language and direction, which its root and a portaled panel
20563
+ // carry inside a provider.
20564
+ const localeScope = usePickerLocaleScope(localeProp, props.dir);
20565
+ const firstDayOfWeek = usePickerFirstDayOfWeek(firstDayOfWeekProp, locale, hasOwnDayNames(dayNames));
20566
+ const disabled = useFieldsetDisabled(disabledProp);
19975
20567
  // Inside a labeled Field the input takes the id the label points at
19976
20568
  // when the caller set none, as InputBase does, and the popover's ids
19977
20569
  // follow it. Inline there is no input to name, so nothing takes the
@@ -20171,7 +20763,7 @@ const DateInputBase = React.forwardRef((props, ref) => {
20171
20763
  // Native mobile path renders <input type="date"> (type="month" for a
20172
20764
  // month picker).
20173
20765
  if (useNative) {
20174
- return (jsxRuntime.jsx("input", { ...cleanRest, ref: combinedRef, type: isDayGranularity ? 'date' : 'month', className: classNames(inputClass, bulmaHelperClasses, className), value: value ? toIsoValue(value, granularity) : '', onChange: e => {
20766
+ return (jsxRuntime.jsx("input", { ...localeScope.rootAttrs, ...cleanRest, ref: combinedRef, type: isDayGranularity ? 'date' : 'month', className: classNames(inputClass, bulmaHelperClasses, className), value: value ? toIsoValue(value, granularity) : '', onChange: e => {
20175
20767
  const parsed = e.target.value
20176
20768
  ? fromIsoValue(e.target.value, granularity)
20177
20769
  : null;
@@ -20191,12 +20783,12 @@ const DateInputBase = React.forwardRef((props, ref) => {
20191
20783
  // keeps the id it released with.
20192
20784
  id: inline ? popoverId : `${popoverId}-cal`, autoFocusCell: open, labels: labels }, granularity));
20193
20785
  if (inline) {
20194
- return (jsxRuntime.jsxs("div", { ...cleanRest, ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), children: [calendar, name && (jsxRuntime.jsx("input", { type: "hidden", name: name, form: form, value: value ? toIsoValue(value, granularity) : '', required: required }))] }));
20786
+ return (jsxRuntime.jsxs("div", { ...localeScope.rootAttrs, ...cleanRest, ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), children: [calendar, name && (jsxRuntime.jsx("input", { type: "hidden", name: name, form: form, value: value ? toIsoValue(value, granularity) : '', required: required }))] }));
20195
20787
  }
20196
- return (jsxRuntime.jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...cleanRest, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", role: "combobox", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": popoverId, autoComplete: "off", className: inputClass, value: text, placeholder: placeholder, disabled: disabled, readOnly: inputReadOnlyAttr, name: name, form: form, required: required, id: id, ...inputHandlers }), popover && triggerIcon && (jsxRuntime.jsx("button", { type: "button", className: triggerClass, onClick: () => {
20788
+ return (jsxRuntime.jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...localeScope.rootAttrs, ...cleanRest, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", role: "combobox", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": popoverId, autoComplete: "off", className: inputClass, value: text, placeholder: placeholder, disabled: disabled, readOnly: inputReadOnlyAttr, name: name, form: form, required: required, id: id, ...inputHandlers }), popover && triggerIcon && (jsxRuntime.jsx("button", { type: "button", className: triggerClass, onClick: () => {
20197
20789
  if (canOpen)
20198
20790
  setOpen(!open);
20199
- }, disabled: !canOpen, "aria-label": chooseLabel, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: handlePopoverClose, anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: chooseLabel, id: popoverId, restoreFocusRef: inputRef, initialFocusSelector: CALENDAR_FOCUSED_CELL, children: calendar }))] }));
20791
+ }, disabled: !canOpen, "aria-label": chooseLabel, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { localeScope: localeScope.panel, isOpen: open, onClose: handlePopoverClose, anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: chooseLabel, id: popoverId, restoreFocusRef: inputRef, initialFocusSelector: CALENDAR_FOCUSED_CELL, children: calendar }))] }));
20200
20792
  });
20201
20793
  DateInputBase.displayName = 'DateInputBase';
20202
20794
 
@@ -21152,7 +21744,13 @@ const fromIsoTime = (s) => {
21152
21744
  * @returns {JSX.Element}
21153
21745
  */
21154
21746
  const TimeInputBase = React.forwardRef((props, ref) => {
21155
- const { value: controlledValue, defaultValue, onChange, onOpen, onClose, min, max, disabled, readOnly, placeholder, format, parse, locale, inline = false, mobileNative = 'auto', editable = true, popover = true, openOnFocus = true, closeOnSelect = false, position = 'bottom-left', appendToBody = false, color, size, isRounded, hourFormat = '24', enableSeconds = false, incrementHours = 1, incrementMinutes = 1, incrementSeconds = 1, unselectableTimes, className, name, form, required, id: idProp, onFocus, onClick, onKeyDown, onBlur, iconLeftName: _iconLeftName, triggerIcon: triggerIconProp, triggerIconName = 'chevron-down', labels, audioTick = false, haptics = false, ...rest } = props;
21747
+ const { value: controlledValue, defaultValue, onChange, onOpen, onClose, min, max, disabled: disabledProp, readOnly, placeholder, format, parse, locale: localeProp, inline = false, mobileNative = 'auto', editable = true, popover = true, openOnFocus = true, closeOnSelect = false, position = 'bottom-left', appendToBody = false, color, size, isRounded, hourFormat = '24', enableSeconds = false, incrementHours = 1, incrementMinutes = 1, incrementSeconds = 1, unselectableTimes, className, name, form, required, id: idProp, onFocus, onClick, onKeyDown, onBlur, iconLeftName: _iconLeftName, triggerIcon: triggerIconProp, triggerIconName = 'chevron-down', labels, audioTick = false, haptics = false, ...rest } = props;
21748
+ // A LocaleProvider around the picker sets its default locale.
21749
+ const locale = usePickerLocale(localeProp);
21750
+ // Its own language and direction, which its root and a portaled panel
21751
+ // carry inside a provider.
21752
+ const localeScope = usePickerLocaleScope(localeProp, props.dir);
21753
+ const disabled = useFieldsetDisabled(disabledProp);
21156
21754
  // Inside a labeled Field the input takes the id the label points at
21157
21755
  // when the caller set none, as InputBase does, and the popover's ids
21158
21756
  // follow it. Inline there is no input to name, so nothing takes the
@@ -21320,7 +21918,7 @@ const TimeInputBase = React.forwardRef((props, ref) => {
21320
21918
  const nativeStep = enableSeconds
21321
21919
  ? incrementSeconds
21322
21920
  : incrementMinutes * 60;
21323
- return (jsxRuntime.jsx("input", { ...cleanRest, ref: combinedRef, type: "time", step: nativeStep, className: classNames(inputClass, bulmaHelperClasses, className), value: value ? toIsoTime(value, enableSeconds) : '', onChange: e => {
21921
+ return (jsxRuntime.jsx("input", { ...localeScope.rootAttrs, ...cleanRest, ref: combinedRef, type: "time", step: nativeStep, className: classNames(inputClass, bulmaHelperClasses, className), value: value ? toIsoTime(value, enableSeconds) : '', onChange: e => {
21324
21922
  const parsed = e.target.value ? fromIsoTime(e.target.value) : null;
21325
21923
  commitValue(parsed);
21326
21924
  }, min: min ? toIsoTime(min, enableSeconds) : undefined, max: max ? toIsoTime(max, enableSeconds) : undefined, disabled: disabled, readOnly: readOnly, placeholder: placeholder, name: name, form: form, required: required, id: id }));
@@ -21350,12 +21948,12 @@ const TimeInputBase = React.forwardRef((props, ref) => {
21350
21948
  setOpen(false);
21351
21949
  }, children: t.reset }), jsxRuntime.jsx("button", { type: "button", className: mobileFooterDoneClass, "aria-label": t.done, onClick: () => setOpen(false), children: jsxRuntime.jsx("svg", { width: "22", height: "22", viewBox: "0 0 22 22", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M5 11l4 4 8-8", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }))] }));
21352
21950
  if (inline) {
21353
- return (jsxRuntime.jsxs("div", { ...cleanRest, ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), children: [panel, name && (jsxRuntime.jsx("input", { type: "hidden", name: name, form: form, value: value ? toIsoTime(value, enableSeconds) : '', required: required }))] }));
21951
+ return (jsxRuntime.jsxs("div", { ...localeScope.rootAttrs, ...cleanRest, ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), children: [panel, name && (jsxRuntime.jsx("input", { type: "hidden", name: name, form: form, value: value ? toIsoTime(value, enableSeconds) : '', required: required }))] }));
21354
21952
  }
21355
- return (jsxRuntime.jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...cleanRest, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", role: "combobox", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": popoverId, autoComplete: "off", className: inputClass, value: text, placeholder: placeholder, disabled: disabled, readOnly: inputReadOnlyAttr, name: name, form: form, required: required, id: id, ...inputHandlers }), popover && triggerIcon && (jsxRuntime.jsx("button", { type: "button", className: triggerClass, onClick: () => {
21953
+ return (jsxRuntime.jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...localeScope.rootAttrs, ...cleanRest, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", role: "combobox", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": popoverId, autoComplete: "off", className: inputClass, value: text, placeholder: placeholder, disabled: disabled, readOnly: inputReadOnlyAttr, name: name, form: form, required: required, id: id, ...inputHandlers }), popover && triggerIcon && (jsxRuntime.jsx("button", { type: "button", className: triggerClass, onClick: () => {
21356
21954
  if (canOpen)
21357
21955
  setOpen(!open);
21358
- }, disabled: !canOpen, "aria-label": t.chooseTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseTime, id: popoverId, restoreFocusRef: inputRef, children: panel }))] }));
21956
+ }, disabled: !canOpen, "aria-label": t.chooseTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { localeScope: localeScope.panel, isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseTime, id: popoverId, restoreFocusRef: inputRef, children: panel }))] }));
21359
21957
  });
21360
21958
  TimeInputBase.displayName = 'TimeInputBase';
21361
21959
 
@@ -21467,9 +22065,17 @@ const fromIsoDateTime = (s) => {
21467
22065
  * @returns {JSX.Element}
21468
22066
  */
21469
22067
  const DateTimeInputBase = React.forwardRef((props, ref) => {
21470
- const { value: controlledValue, defaultValue, onChange, onOpen, onClose, min, max, disabled, readOnly, placeholder, format, parse, locale, inline = false, mobileNative = 'auto', editable = true, popover = true, openOnFocus = true, closeOnSelect = false, position = 'bottom-left', appendToBody = false, color, size, isRounded, shouldDisableDate, unselectableDates, firstDayOfWeek = 0, dayNames, monthNames, nearbyMonthDays = true, hourFormat = '24', enableSeconds = false, incrementHours = 1,
22068
+ const { value: controlledValue, defaultValue, onChange, onOpen, onClose, min, max, disabled: disabledProp, readOnly, placeholder, format, parse, locale: localeProp, inline = false, mobileNative = 'auto', editable = true, popover = true, openOnFocus = true, closeOnSelect = false, position = 'bottom-left', appendToBody = false, color, size, isRounded, shouldDisableDate, unselectableDates, firstDayOfWeek: firstDayOfWeekProp, dayNames, monthNames, nearbyMonthDays = true, hourFormat = '24', enableSeconds = false, incrementHours = 1,
21471
22069
  // Step between visible wheel values; 1 gives the iOS-style every-minute wheel.
21472
22070
  incrementMinutes = 1, incrementSeconds = 1, unselectableTimes, className, name, form, required, id: idProp, onFocus, onClick, onKeyDown, onBlur, iconLeftName: _iconLeftName, triggerIcon: triggerIconProp, triggerIconName = 'chevron-down', audioTick = false, haptics = false, labels, ...rest } = props;
22071
+ // A LocaleProvider around the picker sets its default locale and, through
22072
+ // that locale, the day its week starts on.
22073
+ const locale = usePickerLocale(localeProp);
22074
+ // Its own language and direction, which its root and a portaled panel
22075
+ // carry inside a provider.
22076
+ const localeScope = usePickerLocaleScope(localeProp, props.dir);
22077
+ const firstDayOfWeek = usePickerFirstDayOfWeek(firstDayOfWeekProp, locale, hasOwnDayNames(dayNames));
22078
+ const disabled = useFieldsetDisabled(disabledProp);
21473
22079
  // Inside a labeled Field the input takes the id the label points at
21474
22080
  // when the caller set none, as InputBase does, and the popover's ids
21475
22081
  // follow it. Inline there is no input to name, so nothing takes the
@@ -21709,7 +22315,7 @@ const DateTimeInputBase = React.forwardRef((props, ref) => {
21709
22315
  }, [ref]);
21710
22316
  if (useNative) {
21711
22317
  const nativeStep = enableSeconds ? incrementSeconds : incrementMinutes * 60;
21712
- return (jsxRuntime.jsx("input", { ...cleanRest, ref: combinedRef, type: "datetime-local", step: nativeStep, className: classNames(inputClass, bulmaHelperClasses, className), value: value ? toIsoDateTime(value, enableSeconds) : '', onChange: e => {
22318
+ return (jsxRuntime.jsx("input", { ...localeScope.rootAttrs, ...cleanRest, ref: combinedRef, type: "datetime-local", step: nativeStep, className: classNames(inputClass, bulmaHelperClasses, className), value: value ? toIsoDateTime(value, enableSeconds) : '', onChange: e => {
21713
22319
  const parsed = e.target.value
21714
22320
  ? fromIsoDateTime(e.target.value)
21715
22321
  : null;
@@ -21740,12 +22346,12 @@ const DateTimeInputBase = React.forwardRef((props, ref) => {
21740
22346
  // is no popover, the wheels, as Escape does.
21741
22347
  onCommit: () => (inline ? closeTime() : setOpen(false)) }) }) }))] }), jsxRuntime.jsxs("div", { className: footerClass, children: [jsxRuntime.jsxs("button", { ref: timeButtonRef, type: "button", className: footerTimeClass, onClick: () => (timeOpen ? closeTime() : setTimeOpen(true)), "aria-expanded": timeOpen, "aria-controls": timeOpen ? timeWheelsId : undefined, disabled: disabled, children: [jsxRuntime.jsx("span", { children: t.time }), jsxRuntime.jsx("span", { className: footerTimePillClass, children: value ? formatTime(value, timeDisplayFormat, locale) : '—' })] }), jsxRuntime.jsxs("div", { className: footerActionsClass, children: [jsxRuntime.jsx("button", { type: "button", className: footerResetClass, onClick: () => commitValue(valueAtOpenRef.current), children: t.reset }), jsxRuntime.jsx("button", { type: "button", className: footerDoneClass, "aria-label": t.done, onClick: () => setOpen(false), children: jsxRuntime.jsx("svg", { width: "22", height: "22", viewBox: "0 0 22 22", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M5 11l4 4 8-8", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] })] }));
21742
22348
  if (inline) {
21743
- return (jsxRuntime.jsxs("div", { ...cleanRest, ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), children: [panel, name && (jsxRuntime.jsx("input", { type: "hidden", name: name, form: form, value: value ? toIsoDateTime(value, enableSeconds) : '', required: required }))] }));
22349
+ return (jsxRuntime.jsxs("div", { ...localeScope.rootAttrs, ...cleanRest, ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), children: [panel, name && (jsxRuntime.jsx("input", { type: "hidden", name: name, form: form, value: value ? toIsoDateTime(value, enableSeconds) : '', required: required }))] }));
21744
22350
  }
21745
- return (jsxRuntime.jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...cleanRest, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", role: "combobox", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": popoverId, autoComplete: "off", className: inputClass, value: text, placeholder: placeholder, disabled: disabled, readOnly: inputReadOnlyAttr, name: name, form: form, required: required, id: id, ...inputHandlers }), popover && triggerIcon && (jsxRuntime.jsx("button", { type: "button", className: triggerClass, onClick: () => {
22351
+ return (jsxRuntime.jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...localeScope.rootAttrs, ...cleanRest, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", role: "combobox", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": popoverId, autoComplete: "off", className: inputClass, value: text, placeholder: placeholder, disabled: disabled, readOnly: inputReadOnlyAttr, name: name, form: form, required: required, id: id, ...inputHandlers }), popover && triggerIcon && (jsxRuntime.jsx("button", { type: "button", className: triggerClass, onClick: () => {
21746
22352
  if (canOpen)
21747
22353
  setOpen(!open);
21748
- }, disabled: !canOpen, "aria-label": t.chooseDateTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseDateTime, id: popoverId, restoreFocusRef: inputRef, initialFocusSelector: CALENDAR_FOCUSED_CELL, children: panel }))] }));
22354
+ }, disabled: !canOpen, "aria-label": t.chooseDateTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { localeScope: localeScope.panel, isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseDateTime, id: popoverId, restoreFocusRef: inputRef, initialFocusSelector: CALENDAR_FOCUSED_CELL, children: panel }))] }));
21749
22355
  });
21750
22356
  DateTimeInputBase.displayName = 'DateTimeInputBase';
21751
22357
 
@@ -21844,7 +22450,15 @@ const today = () => startOfDay(new Date());
21844
22450
  * @returns {JSX.Element}
21845
22451
  */
21846
22452
  const DateRangeInputBase = React.forwardRef((props, ref) => {
21847
- const { value: controlledValue, defaultValue, onChange, onOpen, onClose, min, max, disabled, readOnly, placeholder, format, parse, locale, inline = false, mobileNative = 'auto', editable = true, popover = true, openOnFocus = true, closeOnSelect = true, position = 'bottom-left', appendToBody = false, color, size, isRounded, shouldDisableDate, unselectableDates, allowDisabledInRange = false, firstDayOfWeek = 0, dayNames, monthNames, nearbyMonthDays = true, iconLeftName: _iconLeftName, triggerIcon: triggerIconProp, triggerIconName = 'chevron-down', labels, name, startName, endName, form, required, id, className, onFocus, onFocusCapture, ...rest } = props;
22453
+ const { value: controlledValue, defaultValue, onChange, onOpen, onClose, min, max, disabled: disabledProp, readOnly, placeholder, format, parse, locale: localeProp, inline = false, mobileNative = 'auto', editable = true, popover = true, openOnFocus = true, closeOnSelect = true, position = 'bottom-left', appendToBody = false, color, size, isRounded, shouldDisableDate, unselectableDates, allowDisabledInRange = false, firstDayOfWeek: firstDayOfWeekProp, dayNames, monthNames, nearbyMonthDays = true, iconLeftName: _iconLeftName, triggerIcon: triggerIconProp, triggerIconName = 'chevron-down', labels, name, startName, endName, form, required, id, className, onFocus, onFocusCapture, ...rest } = props;
22454
+ // A LocaleProvider around the picker sets its default locale and, through
22455
+ // that locale, the day its week starts on.
22456
+ const locale = usePickerLocale(localeProp);
22457
+ // Its own language and direction, which its root and a portaled panel
22458
+ // carry inside a provider.
22459
+ const localeScope = usePickerLocaleScope(localeProp, props.dir);
22460
+ const firstDayOfWeek = usePickerFirstDayOfWeek(firstDayOfWeekProp, locale, hasOwnDayNames(dayNames));
22461
+ const disabled = useFieldsetDisabled(disabledProp);
21848
22462
  // The launcher gives way to the loading spinner of a Control this sits in.
21849
22463
  const controlLoading = useControlLoading();
21850
22464
  const triggerIcon = triggerIconProp ?? !controlLoading;
@@ -22075,14 +22689,14 @@ const DateRangeInputBase = React.forwardRef((props, ref) => {
22075
22689
  };
22076
22690
  const minIso = min ? isoDay(lowerBound) : undefined;
22077
22691
  const maxIso = max ? isoDay(max) : undefined;
22078
- return (jsxRuntime.jsxs("div", { "aria-labelledby": ariaLabelledBy, ...cleanRest, ref: containerRef, role: "group", className: classNames(containerClass, bulmaHelperClasses, className), onFocus: onFocus, onFocusCapture: onFocusCapture, children: [jsxRuntime.jsxs("div", { className: fieldClass, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "date", id: id, "aria-label": t.rangeStart, className: inputClass, value: isoDay(start), onChange: nativeChange(commitStart, isBlockedDay), min: minIso, max: maxIso, disabled: disabled, readOnly: readOnly, required: required }), separator, jsxRuntime.jsx("input", { ref: endRef, type: "date", id: id ? `${id}-end` : undefined, "aria-label": t.rangeEnd, className: inputClass, value: isoDay(end), onChange: nativeChange(commitEnd, isBlockedEnd), min: start ? isoDay(start) : minIso, max: maxIso, disabled: disabled, readOnly: readOnly, required: required })] }), hiddenInputs] }));
22692
+ return (jsxRuntime.jsxs("div", { "aria-labelledby": ariaLabelledBy, ...localeScope.rootAttrs, ...cleanRest, ref: containerRef, role: "group", className: classNames(containerClass, bulmaHelperClasses, className), onFocus: onFocus, onFocusCapture: onFocusCapture, children: [jsxRuntime.jsxs("div", { className: fieldClass, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "date", id: id, "aria-label": t.rangeStart, className: inputClass, value: isoDay(start), onChange: nativeChange(commitStart, isBlockedDay), min: minIso, max: maxIso, disabled: disabled, readOnly: readOnly, required: required }), separator, jsxRuntime.jsx("input", { ref: endRef, type: "date", id: id ? `${id}-end` : undefined, "aria-label": t.rangeEnd, className: inputClass, value: isoDay(end), onChange: nativeChange(commitEnd, isBlockedEnd), min: start ? isoDay(start) : minIso, max: maxIso, disabled: disabled, readOnly: readOnly, required: required })] }), hiddenInputs] }));
22079
22693
  }
22080
22694
  const calendar = (jsxRuntime.jsx(Calendar, { range: range, onRangeSelect: handleRangeSelect, allowDisabledInRange: allowDisabledInRange, focusedDate: focusedDate, onFocusedDateChange: setFocusedDate, min: min, max: max, shouldDisableDate: shouldDisableDate, unselectableDates: unselectableDates, firstDayOfWeek: firstDayOfWeek, locale: locale, dayNames: dayNames, monthNames: monthNames, nearbyMonthDays: nearbyMonthDays, color: color, size: size,
22081
22695
  // The popover panel takes `popoverId`, so the calendar inside it takes
22082
22696
  // one of its own. Inline there is no panel.
22083
22697
  id: inline ? popoverId : `${popoverId}-cal`, autoFocusCell: open, labels: labels }));
22084
22698
  if (inline) {
22085
- return (jsxRuntime.jsxs("div", { "aria-labelledby": ariaLabelledBy, ...cleanRest, ref: containerRef, role: "group", className: classNames(containerClass, bulmaHelperClasses, className), onFocus: onFocus, onFocusCapture: onFocusCapture, children: [calendar, hiddenInputs] }));
22699
+ return (jsxRuntime.jsxs("div", { "aria-labelledby": ariaLabelledBy, ...localeScope.rootAttrs, ...cleanRest, ref: containerRef, role: "group", className: classNames(containerClass, bulmaHelperClasses, className), onFocus: onFocus, onFocusCapture: onFocusCapture, children: [calendar, hiddenInputs] }));
22086
22700
  }
22087
22701
  const canOpen = !!popover && !disabled && !readOnly;
22088
22702
  const inputReadOnly = !!readOnly || !editable;
@@ -22117,9 +22731,9 @@ const DateRangeInputBase = React.forwardRef((props, ref) => {
22117
22731
  readOnly: inputReadOnly,
22118
22732
  required,
22119
22733
  };
22120
- return (jsxRuntime.jsxs("div", { "aria-labelledby": ariaLabelledBy, ...cleanRest, ref: containerRef, role: "group", className: classNames(containerClass, bulmaHelperClasses, className), onFocus: handleFocus, onFocusCapture: handleFocusCapture, children: [jsxRuntime.jsxs("div", { className: fieldClass, onMouseDown: handleFieldMouseDown, children: [jsxRuntime.jsx("input", { ...comboboxProps, ref: combinedRef, id: id, "aria-label": t.rangeStart, value: startText, ...startHandlers }), separator, jsxRuntime.jsx("input", { ...comboboxProps, ref: endRef, id: id ? `${id}-end` : undefined, "aria-label": t.rangeEnd, value: endText, ...endHandlers })] }), popover && triggerIcon && (jsxRuntime.jsx("button", { type: "button", className: triggerClass,
22734
+ return (jsxRuntime.jsxs("div", { "aria-labelledby": ariaLabelledBy, ...localeScope.rootAttrs, ...cleanRest, ref: containerRef, role: "group", className: classNames(containerClass, bulmaHelperClasses, className), onFocus: handleFocus, onFocusCapture: handleFocusCapture, children: [jsxRuntime.jsxs("div", { className: fieldClass, onMouseDown: handleFieldMouseDown, children: [jsxRuntime.jsx("input", { ...comboboxProps, ref: combinedRef, id: id, "aria-label": t.rangeStart, value: startText, ...startHandlers }), separator, jsxRuntime.jsx("input", { ...comboboxProps, ref: endRef, id: id ? `${id}-end` : undefined, "aria-label": t.rangeEnd, value: endText, ...endHandlers })] }), popover && triggerIcon && (jsxRuntime.jsx("button", { type: "button", className: triggerClass,
22121
22735
  // Disabled whenever the popover can't open, so a click can.
22122
- onClick: () => setOpen(!open), disabled: !canOpen, "aria-label": t.chooseDateRange, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: handlePopoverClose, anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseDateRange, id: popoverId, restoreFocusRef: restoreFocusRef, initialFocusSelector: CALENDAR_FOCUSED_CELL, children: calendar })), hiddenInputs] }));
22736
+ onClick: () => setOpen(!open), disabled: !canOpen, "aria-label": t.chooseDateRange, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { localeScope: localeScope.panel, isOpen: open, onClose: handlePopoverClose, anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseDateRange, id: popoverId, restoreFocusRef: restoreFocusRef, initialFocusSelector: CALENDAR_FOCUSED_CELL, children: calendar })), hiddenInputs] }));
22123
22737
  });
22124
22738
  DateRangeInputBase.displayName = 'DateRangeInputBase';
22125
22739
 
@@ -24369,6 +24983,7 @@ exports.EmptyStateTitle = EmptyStateTitle;
24369
24983
  exports.Field = Field;
24370
24984
  exports.FieldBody = FieldBody;
24371
24985
  exports.FieldLabel = FieldLabel;
24986
+ exports.Fieldset = Fieldset;
24372
24987
  exports.Figure = Figure;
24373
24988
  exports.File = File;
24374
24989
  exports.Footer = Footer;
@@ -24394,6 +25009,7 @@ exports.LinkButton = LinkButton;
24394
25009
  exports.ListItem = ListItem;
24395
25010
  exports.Loader = Loader;
24396
25011
  exports.Loading = Loading;
25012
+ exports.LocaleProvider = LocaleProvider;
24397
25013
  exports.Media = Media;
24398
25014
  exports.MediaContent = MediaContent;
24399
25015
  exports.MediaLeft = MediaLeft;
@@ -24524,6 +25140,7 @@ exports.useIconLibrary = useIconLibrary;
24524
25140
  exports.useInsideControl = useInsideControl;
24525
25141
  exports.useInsideField = useInsideField;
24526
25142
  exports.useIsHydrated = useIsHydrated;
25143
+ exports.useLocale = useLocale;
24527
25144
  exports.useOtherClasses = useOtherClasses;
24528
25145
  exports.usePrefixedClass = usePrefixedClass;
24529
25146
  exports.usePrefixedClassNames = usePrefixedClassNames;