@allxsmith/bestax-bulma 5.45.0 → 5.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/Modal.js +20 -7
- package/dist/esm/components/Modal.js.map +1 -1
- package/dist/esm/form/Checkbox.js.map +1 -1
- package/dist/esm/form/File.js.map +1 -1
- package/dist/esm/form/Numberinput.js.map +1 -1
- package/dist/esm/form/PinInput.js.map +1 -1
- package/dist/esm/form/Radio.js.map +1 -1
- package/dist/esm/form/SelectBase.js.map +1 -1
- package/dist/esm/form/Slider.js.map +1 -1
- package/dist/esm/form/Switch.js.map +1 -1
- package/dist/esm/helpers/Theme.js +191 -49
- package/dist/esm/helpers/Theme.js.map +1 -1
- package/dist/esm/helpers/useVisibilityClasses.js.map +1 -1
- package/dist/index.cjs +209 -55
- package/dist/index.cjs.map +1 -1
- package/dist/types/components/Modal.d.ts +10 -1
- package/dist/types/form/Checkbox.d.ts +3 -0
- package/dist/types/form/File.d.ts +3 -0
- package/dist/types/form/Numberinput.d.ts +2 -0
- package/dist/types/form/PinInput.d.ts +3 -0
- package/dist/types/form/Radio.d.ts +3 -0
- package/dist/types/form/SelectBase.d.ts +3 -0
- package/dist/types/form/Slider.d.ts +3 -0
- package/dist/types/form/Switch.d.ts +2 -0
- package/dist/types/helpers/Theme.d.ts +37 -10
- package/dist/types/helpers/useVisibilityClasses.d.ts +5 -1
- package/dist/types-cjs/components/Modal.d.ts +10 -1
- package/dist/types-cjs/form/Checkbox.d.ts +3 -0
- package/dist/types-cjs/form/File.d.ts +3 -0
- package/dist/types-cjs/form/Numberinput.d.ts +2 -0
- package/dist/types-cjs/form/PinInput.d.ts +3 -0
- package/dist/types-cjs/form/Radio.d.ts +3 -0
- package/dist/types-cjs/form/SelectBase.d.ts +3 -0
- package/dist/types-cjs/form/Slider.d.ts +3 -0
- package/dist/types-cjs/form/Switch.d.ts +2 -0
- package/dist/types-cjs/helpers/Theme.d.ts +37 -10
- package/dist/types-cjs/helpers/useVisibilityClasses.d.ts +5 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4595,8 +4595,12 @@ function useFocusTrap(containerRef, options = {}) {
|
|
|
4595
4595
|
});
|
|
4596
4596
|
}
|
|
4597
4597
|
|
|
4598
|
+
// The enclosing modal's `onClose`, for a `Modal.Close` written as a part, so
|
|
4599
|
+
// it closes the modal the way the button the props form renders does.
|
|
4600
|
+
const ModalCloseContext = React.createContext(undefined);
|
|
4598
4601
|
/**
|
|
4599
|
-
* Modal.Background - Renders the modal background overlay.
|
|
4602
|
+
* Modal.Background - Renders the modal background overlay. Pass it
|
|
4603
|
+
* `onClick={onClose}` for a click on it to close the modal.
|
|
4600
4604
|
*
|
|
4601
4605
|
* @function
|
|
4602
4606
|
* @param {ModalBackgroundProps} props - Component props.
|
|
@@ -4680,7 +4684,8 @@ const ModalCard = withSubComponents(ModalCardComponent, {
|
|
|
4680
4684
|
Foot: ModalCardFoot,
|
|
4681
4685
|
});
|
|
4682
4686
|
/**
|
|
4683
|
-
* Modal.Close - Renders modal close button with two variant styles.
|
|
4687
|
+
* Modal.Close - Renders modal close button with two variant styles. It calls
|
|
4688
|
+
* the modal's `onClose` unless given an `onClick` of its own.
|
|
4684
4689
|
*
|
|
4685
4690
|
* @function
|
|
4686
4691
|
* @param {ModalCloseProps} props - Component props.
|
|
@@ -4693,9 +4698,15 @@ const ModalCard = withSubComponents(ModalCardComponent, {
|
|
|
4693
4698
|
*
|
|
4694
4699
|
* The size prop only applies to the 'floating' variant.
|
|
4695
4700
|
*/
|
|
4696
|
-
const ModalClose = ({ className, size = 'large', variant = 'delete', ...props }) => {
|
|
4701
|
+
const ModalClose = ({ className, size = 'large', variant = 'delete', onClick, ...props }) => {
|
|
4702
|
+
const onClose = React.useContext(ModalCloseContext);
|
|
4697
4703
|
const classes = classNames(usePrefixedClassNames(variant === 'delete' ? 'delete' : 'modal-close', variant === 'floating' && size && { [`is-${size}`]: true }), className);
|
|
4698
|
-
return (jsxRuntime.jsx("button", { className: classes, ...props, "aria-label": props['aria-label'] || 'close', type: buttonType(props.type)
|
|
4704
|
+
return (jsxRuntime.jsx("button", { className: classes, ...props, "aria-label": props['aria-label'] || 'close', type: buttonType(props.type),
|
|
4705
|
+
// A caller's own `onClick` replaces the close rather than running
|
|
4706
|
+
// before it, unlike `Popover.Close`: this button used to close only
|
|
4707
|
+
// through that handler, so a caller already closing there, as with
|
|
4708
|
+
// `onClick={onClose}`, would otherwise close twice.
|
|
4709
|
+
onClick: onClick ?? (onClose && (() => onClose())) }));
|
|
4699
4710
|
};
|
|
4700
4711
|
/**
|
|
4701
4712
|
* The `Modal` component provides an empty, accessible overlay for arbitrary content — for a ready-made confirm or alert, reach for `Dialog` instead.
|
|
@@ -4712,12 +4723,12 @@ const ModalClose = ({ className, size = 'large', variant = 'delete', ...props })
|
|
|
4712
4723
|
*
|
|
4713
4724
|
* @example
|
|
4714
4725
|
* // Compound Component API
|
|
4715
|
-
* <Modal isActive={isOpen}>
|
|
4726
|
+
* <Modal isActive={isOpen} onClose={handleClose}>
|
|
4716
4727
|
* <Modal.Background onClick={handleClose} />
|
|
4717
4728
|
* <Modal.Card>
|
|
4718
4729
|
* <Modal.Card.Head>
|
|
4719
4730
|
* <Modal.Card.Title>Title</Modal.Card.Title>
|
|
4720
|
-
* <Modal.Close
|
|
4731
|
+
* <Modal.Close />
|
|
4721
4732
|
* </Modal.Card.Head>
|
|
4722
4733
|
* <Modal.Card.Body>Content</Modal.Card.Body>
|
|
4723
4734
|
* </Modal.Card>
|
|
@@ -4896,6 +4907,8 @@ const ModalRoot = React.forwardRef(function ModalRoot({ active, isActive, onClos
|
|
|
4896
4907
|
isModalCard = !!modalCardTitle || !!modalCardFoot;
|
|
4897
4908
|
modalElement = (jsxRuntime.jsxs("div", { className: modalClasses, ref: combinedRef, role: resolvedRole, "aria-modal": resolvedAriaModal, "aria-labelledby": titleId, tabIndex: -1, ...rest, "data-testid": "modal", children: [jsxRuntime.jsx("div", { className: prefixedClassNames(classPrefix, 'modal-background'), onClick: onClose, "data-testid": "modal-background" }), isModalCard ? (jsxRuntime.jsxs("div", { className: prefixedClassNames(classPrefix, 'modal-card'), children: [modalCardTitle && (jsxRuntime.jsxs("header", { className: prefixedClassNames(classPrefix, 'modal-card-head'), children: [jsxRuntime.jsx("p", { id: titleId, className: prefixedClassNames(classPrefix, 'modal-card-title'), children: modalCardTitle }), onClose && (jsxRuntime.jsx("button", { className: deleteClass, "aria-label": "close", onClick: onClose, type: "button", "data-testid": "modal-close" }))] })), jsxRuntime.jsx("section", { className: prefixedClassNames(classPrefix, 'modal-card-body'), "data-testid": "modal-body", children: children }), modalCardFoot && (jsxRuntime.jsx("footer", { className: prefixedClassNames(classPrefix, 'modal-card-foot'), children: modalCardFoot }))] })) : (jsxRuntime.jsx("div", { className: prefixedClassNames(classPrefix, 'modal-content'), "data-testid": "modal-content", children: children })), (!isModalCard || (!modalCardTitle && onClose)) && onClose && (jsxRuntime.jsx("button", { className: prefixedClassNames(classPrefix, 'modal-close', 'is-large'), "aria-label": "close", onClick: onClose, type: "button", "data-testid": "modal-close-float" }))] }));
|
|
4898
4909
|
}
|
|
4910
|
+
// In both forms, so a `Modal.Close` anywhere inside closes this modal.
|
|
4911
|
+
modalElement = (jsxRuntime.jsx(ModalCloseContext.Provider, { value: onClose, children: modalElement }));
|
|
4899
4912
|
if (isPortaled) {
|
|
4900
4913
|
const target = resolveContainer(typeof portal === 'boolean' ? undefined : portal);
|
|
4901
4914
|
return reactDom.createPortal(modalElement, target);
|
|
@@ -20941,6 +20954,21 @@ const bulmaGlobalVars = [
|
|
|
20941
20954
|
'--bulma-danger-h',
|
|
20942
20955
|
'--bulma-danger-s',
|
|
20943
20956
|
'--bulma-danger-l',
|
|
20957
|
+
// the lightness of each color's label on a solid surface, and of its text
|
|
20958
|
+
// on the page, which Bulma's Sass build picks for contrast with the color
|
|
20959
|
+
// it was built with, so a new trio does not move them
|
|
20960
|
+
'--bulma-primary-invert-l',
|
|
20961
|
+
'--bulma-primary-on-scheme-l',
|
|
20962
|
+
'--bulma-link-invert-l',
|
|
20963
|
+
'--bulma-link-on-scheme-l',
|
|
20964
|
+
'--bulma-info-invert-l',
|
|
20965
|
+
'--bulma-info-on-scheme-l',
|
|
20966
|
+
'--bulma-success-invert-l',
|
|
20967
|
+
'--bulma-success-on-scheme-l',
|
|
20968
|
+
'--bulma-warning-invert-l',
|
|
20969
|
+
'--bulma-warning-on-scheme-l',
|
|
20970
|
+
'--bulma-danger-invert-l',
|
|
20971
|
+
'--bulma-danger-on-scheme-l',
|
|
20944
20972
|
// shadow (the upstream token .box/.card/.dropdown/.panel derive their own
|
|
20945
20973
|
// shadow variables from; overriding it from an ancestor is the route that
|
|
20946
20974
|
// cascades, since those selectors re-declare their derived var on
|
|
@@ -21691,6 +21719,104 @@ const setRootThemeRules = (order, rules) => {
|
|
|
21691
21719
|
}
|
|
21692
21720
|
renderRootThemeRules();
|
|
21693
21721
|
};
|
|
21722
|
+
/** A value given per scheme, rather than as one string. */
|
|
21723
|
+
const isSchemeValues = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
21724
|
+
/**
|
|
21725
|
+
* The selector of one of Bulma's schemes, as the stylesheet Theme is used
|
|
21726
|
+
* with writes it: `[data-theme=dark], .theme-dark`, or with the class prefix
|
|
21727
|
+
* in both names (`[data-bestax-theme=dark], .bestax-theme-dark`) for a
|
|
21728
|
+
* prefixed build. A prefix that cannot be written into a selector as it
|
|
21729
|
+
* stands gets the plain names, which `colorMode` writes under any prefix.
|
|
21730
|
+
*/
|
|
21731
|
+
const schemeSelector = (classPrefix, scheme) => {
|
|
21732
|
+
const prefix = /^[A-Za-z_][\w-]*$/.test(classPrefix) ? classPrefix : '';
|
|
21733
|
+
return `[data-${prefix}theme=${scheme}], .${prefix}theme-${scheme}`;
|
|
21734
|
+
};
|
|
21735
|
+
/**
|
|
21736
|
+
* The `:root` rules for variables given a value per scheme, laid out the
|
|
21737
|
+
* way Bulma lays out its own schemes so each value applies exactly where
|
|
21738
|
+
* Bulma's would: under the visitor's OS preference, unless the page names
|
|
21739
|
+
* the other scheme, and wherever the page names this one, on `<html>` or on
|
|
21740
|
+
* an element inside. A scheme with no value gets no rules, which leaves the
|
|
21741
|
+
* stylesheet's own value there.
|
|
21742
|
+
*
|
|
21743
|
+
* Every selector is as specific as `:root` (the guard is in `:where()`), so
|
|
21744
|
+
* between Themes, and against a plain `:root` rule, the later one still
|
|
21745
|
+
* wins, as it does for every other variable.
|
|
21746
|
+
*/
|
|
21747
|
+
const schemeRules = (vars, classPrefix) => {
|
|
21748
|
+
const other = { light: 'dark', dark: 'light' };
|
|
21749
|
+
const body = (scheme) => vars
|
|
21750
|
+
.filter(([, values]) => values[scheme])
|
|
21751
|
+
.map(([key, values]) => `${key}: ${values[scheme]};`)
|
|
21752
|
+
.join(' ');
|
|
21753
|
+
const schemes = ['light', 'dark']
|
|
21754
|
+
.map(scheme => [scheme, body(scheme)])
|
|
21755
|
+
.filter(([, declarations]) => declarations);
|
|
21756
|
+
// Bulma's order: both preferences, then both names, the dark one last.
|
|
21757
|
+
return [
|
|
21758
|
+
...schemes.map(([scheme, declarations]) => `@media (prefers-color-scheme: ${scheme}) { :root:where(:not(` +
|
|
21759
|
+
`${schemeSelector(classPrefix, other[scheme])})) { ${declarations} } }`),
|
|
21760
|
+
...schemes.map(([scheme, declarations]) => `${schemeSelector(classPrefix, scheme)} { ${declarations} }`),
|
|
21761
|
+
];
|
|
21762
|
+
};
|
|
21763
|
+
const schemeAttributes = new Map();
|
|
21764
|
+
/** Set a theme attribute on `<html>`, or remove it for `null`. */
|
|
21765
|
+
const setSchemeAttribute = (name, value) => {
|
|
21766
|
+
const root = document.documentElement;
|
|
21767
|
+
if (value === null) {
|
|
21768
|
+
root.removeAttribute(name);
|
|
21769
|
+
}
|
|
21770
|
+
else {
|
|
21771
|
+
root.setAttribute(name, value);
|
|
21772
|
+
}
|
|
21773
|
+
};
|
|
21774
|
+
/**
|
|
21775
|
+
* Write one Theme's value for a theme attribute, `null` removing it, and
|
|
21776
|
+
* make that Theme the attribute's latest writer. Throws, recording nothing,
|
|
21777
|
+
* when `name` cannot be an attribute name.
|
|
21778
|
+
*
|
|
21779
|
+
* A Theme that writes the value it already holds keeps its place and leaves
|
|
21780
|
+
* the page alone. React runs a layout effect again when a `Suspense`
|
|
21781
|
+
* boundary shows its tree again, with nothing changed, and that must not
|
|
21782
|
+
* take the attribute back from a Theme that wrote after it.
|
|
21783
|
+
*/
|
|
21784
|
+
const writeSchemeAttribute = (order, name, value) => {
|
|
21785
|
+
const held = schemeAttributes.get(name);
|
|
21786
|
+
if (held?.writers.some(writer => writer.order === order && writer.value === value)) {
|
|
21787
|
+
return;
|
|
21788
|
+
}
|
|
21789
|
+
const entry = held ?? {
|
|
21790
|
+
original: document.documentElement.getAttribute(name),
|
|
21791
|
+
writers: [],
|
|
21792
|
+
};
|
|
21793
|
+
setSchemeAttribute(name, value);
|
|
21794
|
+
entry.writers = entry.writers.filter(writer => writer.order !== order);
|
|
21795
|
+
entry.writers.push({ order, value });
|
|
21796
|
+
schemeAttributes.set(name, entry);
|
|
21797
|
+
};
|
|
21798
|
+
/**
|
|
21799
|
+
* Take one Theme off every theme attribute it wrote, except those named in
|
|
21800
|
+
* `keep`. An attribute it was the latest writer of goes back to the value of
|
|
21801
|
+
* the writer before it, or to what it held before any of them.
|
|
21802
|
+
*/
|
|
21803
|
+
const releaseSchemeAttributes = (order, keep = []) => {
|
|
21804
|
+
for (const [name, entry] of schemeAttributes) {
|
|
21805
|
+
const index = entry.writers.findIndex(writer => writer.order === order);
|
|
21806
|
+
if (index === -1 || keep.includes(name)) {
|
|
21807
|
+
continue;
|
|
21808
|
+
}
|
|
21809
|
+
const latest = index === entry.writers.length - 1;
|
|
21810
|
+
entry.writers.splice(index, 1);
|
|
21811
|
+
if (entry.writers.length === 0) {
|
|
21812
|
+
schemeAttributes.delete(name);
|
|
21813
|
+
setSchemeAttribute(name, entry.original);
|
|
21814
|
+
}
|
|
21815
|
+
else if (latest) {
|
|
21816
|
+
setSchemeAttribute(name, entry.writers[entry.writers.length - 1].value);
|
|
21817
|
+
}
|
|
21818
|
+
}
|
|
21819
|
+
};
|
|
21694
21820
|
/**
|
|
21695
21821
|
* Theme component that injects Bulma CSS variables either globally or locally.
|
|
21696
21822
|
*
|
|
@@ -21777,7 +21903,9 @@ const Theme = ({ bulmaVars = {}, children, className, isRoot = false, colorMode,
|
|
|
21777
21903
|
});
|
|
21778
21904
|
// Merge bulmaVars and individual props, with props taking precedence
|
|
21779
21905
|
const mergedVars = React.useMemo(() => {
|
|
21780
|
-
const vars = {
|
|
21906
|
+
const vars = {
|
|
21907
|
+
...bulmaVars,
|
|
21908
|
+
};
|
|
21781
21909
|
for (const [propName, cssVar] of Object.entries(bulmaVarPropMap)) {
|
|
21782
21910
|
if (bulmaVarProps[propName] !== undefined) {
|
|
21783
21911
|
vars[cssVar] = bulmaVarProps[propName];
|
|
@@ -21791,61 +21919,99 @@ const Theme = ({ bulmaVars = {}, children, className, isRoot = false, colorMode,
|
|
|
21791
21919
|
}
|
|
21792
21920
|
return vars;
|
|
21793
21921
|
}, [bulmaVars, bulmaVarProps, radiusVar, columnGapVar]);
|
|
21922
|
+
// The variables Theme writes, split by form: a value per scheme, or one
|
|
21923
|
+
// value for every scheme. A key Theme does not take, or an empty value, is
|
|
21924
|
+
// left out. A plain value is written as given, so a number untyped code
|
|
21925
|
+
// passes still works.
|
|
21926
|
+
const { plainVars, perSchemeVars } = React.useMemo(() => {
|
|
21927
|
+
const plain = [];
|
|
21928
|
+
const perScheme = [];
|
|
21929
|
+
for (const [key, value] of Object.entries(mergedVars)) {
|
|
21930
|
+
if (!value || !bulmaCssVars.includes(key)) {
|
|
21931
|
+
continue;
|
|
21932
|
+
}
|
|
21933
|
+
if (isSchemeValues(value)) {
|
|
21934
|
+
perScheme.push([key, value]);
|
|
21935
|
+
}
|
|
21936
|
+
else {
|
|
21937
|
+
plain.push([key, value]);
|
|
21938
|
+
}
|
|
21939
|
+
}
|
|
21940
|
+
return { plainVars: plain, perSchemeVars: perScheme };
|
|
21941
|
+
}, [mergedVars]);
|
|
21794
21942
|
// From an effect rather than the render body, so rendering does none of
|
|
21795
21943
|
// this work, and a server render none at all. In production it returns
|
|
21796
21944
|
// at its development check before looking at the variables.
|
|
21797
21945
|
React.useEffect(() => {
|
|
21798
21946
|
warnComponentVars(mergedVars);
|
|
21799
21947
|
}, [mergedVars]);
|
|
21800
|
-
//
|
|
21948
|
+
// A scoped Theme writes its variables as an inline style, which has no way
|
|
21949
|
+
// to say which scheme a value is for, so it skips a value given per
|
|
21950
|
+
// scheme. Say so, since nothing on the page does.
|
|
21951
|
+
React.useEffect(() => {
|
|
21952
|
+
if (isRoot || perSchemeVars.length === 0 || !isDev()) {
|
|
21953
|
+
return;
|
|
21954
|
+
}
|
|
21955
|
+
const keys = perSchemeVars.map(([key]) => key).sort();
|
|
21956
|
+
warnOnce(`Theme:scoped-scheme-values:${keys.join(',')}`, `[bestax-bulma] <Theme>: a scoped Theme writes its variables as an ` +
|
|
21957
|
+
`inline style, which cannot hold a value per scheme, so ` +
|
|
21958
|
+
`${keys.join(', ')} ${keys.length === 1 ? 'is' : 'are'} not set. ` +
|
|
21959
|
+
'Give a single string, set the values on an isRoot Theme, or set ' +
|
|
21960
|
+
'them in your CSS.');
|
|
21961
|
+
}, [isRoot, perSchemeVars]);
|
|
21962
|
+
// This Theme's place among the Themes on the page; see `rootThemeRules`
|
|
21963
|
+
// and `schemeAttributes`.
|
|
21801
21964
|
const [rootOrder] = React.useState(() => nextRootOrder++);
|
|
21802
|
-
//
|
|
21965
|
+
// Bulma names its scheme attribute after the class prefix a stylesheet was
|
|
21966
|
+
// built with (`data-<prefix>theme`), so the prefixed builds read
|
|
21967
|
+
// `data-bestax-theme` and never `data-theme`. Its scheme classes take the
|
|
21968
|
+
// prefix too (`.bestax-theme-dark`).
|
|
21969
|
+
const classPrefix = useClassPrefix();
|
|
21970
|
+
// The `:root` rules this Theme contributes, or '' when it contributes none:
|
|
21971
|
+
// one block for the plain values, then the rules for each value given per
|
|
21972
|
+
// scheme.
|
|
21803
21973
|
const rootRules = React.useMemo(() => {
|
|
21804
21974
|
if (!isRoot) {
|
|
21805
21975
|
return '';
|
|
21806
21976
|
}
|
|
21807
|
-
const
|
|
21808
|
-
|
|
21809
|
-
.
|
|
21810
|
-
|
|
21811
|
-
|
|
21812
|
-
}, [
|
|
21977
|
+
const plain = plainVars.map(([key, value]) => `${key}: ${value};`);
|
|
21978
|
+
return [
|
|
21979
|
+
...(plain.length > 0 ? [`:root { ${plain.join(' ')} }`] : []),
|
|
21980
|
+
...schemeRules(perSchemeVars, classPrefix),
|
|
21981
|
+
].join('\n');
|
|
21982
|
+
}, [plainVars, perSchemeVars, classPrefix, isRoot]);
|
|
21813
21983
|
// Inject CSS variables globally at :root level, alongside any other root
|
|
21814
21984
|
// Themes. Clearing `isRoot` or every variable passes '', which withdraws
|
|
21815
|
-
// this Theme's rules.
|
|
21816
|
-
|
|
21985
|
+
// this Theme's rules. A layout effect, so they are in place before the
|
|
21986
|
+
// browser paints what this Theme rendered.
|
|
21987
|
+
useClientLayoutEffect(() => {
|
|
21817
21988
|
setRootThemeRules(rootOrder, rootRules);
|
|
21818
21989
|
}, [rootOrder, rootRules]);
|
|
21819
21990
|
// Withdraw them on unmount. Kept apart from the effect above so a change
|
|
21820
21991
|
// rewrites the shared element in place rather than removing and recreating
|
|
21821
|
-
// it between the cleanup and the next run
|
|
21992
|
+
// it between the cleanup and the next run, and passive, so a Theme that a
|
|
21993
|
+
// `Suspense` fallback hides keeps its variables meanwhile: React cleans up
|
|
21994
|
+
// a hidden tree's layout effects, but not its passive ones.
|
|
21822
21995
|
React.useEffect(() => () => setRootThemeRules(rootOrder, ''), [rootOrder]);
|
|
21823
|
-
// Bulma names its scheme attribute after the class prefix a stylesheet was
|
|
21824
|
-
// built with (`data-<prefix>theme`), so the prefixed builds read
|
|
21825
|
-
// `data-bestax-theme` and never `data-theme`.
|
|
21826
|
-
const classPrefix = useClassPrefix();
|
|
21827
21996
|
// Toggle Bulma's light/dark scheme by writing the theme attribute on the
|
|
21828
21997
|
// document root (<html>). This is always global, even on a scoped Theme.
|
|
21829
21998
|
// Under a class prefix the prefixed attribute is written as well as
|
|
21830
21999
|
// `data-theme`, so whichever build is loaded sees it; with no prefix only
|
|
21831
22000
|
// `data-theme` is. `'system'` removes them so Bulma follows the OS
|
|
21832
|
-
// preference.
|
|
21833
|
-
|
|
21834
|
-
|
|
21835
|
-
|
|
21836
|
-
|
|
21837
|
-
|
|
21838
|
-
|
|
21839
|
-
|
|
21840
|
-
|
|
21841
|
-
const
|
|
22001
|
+
// preference. Written before the browser paints, and handed back on
|
|
22002
|
+
// unmount, for the reasons the two effects above give; `schemeAttributes`
|
|
22003
|
+
// keeps the two in step.
|
|
22004
|
+
useClientLayoutEffect(() => {
|
|
22005
|
+
const names = colorMode === undefined
|
|
22006
|
+
? []
|
|
22007
|
+
: classPrefix
|
|
22008
|
+
? ['data-theme', `data-${classPrefix}theme`]
|
|
22009
|
+
: ['data-theme'];
|
|
22010
|
+
const value = colorMode === undefined || colorMode === 'system' ? null : colorMode;
|
|
22011
|
+
releaseSchemeAttributes(rootOrder, names);
|
|
21842
22012
|
for (const name of names) {
|
|
21843
|
-
if (colorMode === 'system') {
|
|
21844
|
-
root.removeAttribute(name);
|
|
21845
|
-
continue;
|
|
21846
|
-
}
|
|
21847
22013
|
try {
|
|
21848
|
-
|
|
22014
|
+
writeSchemeAttribute(rootOrder, name, value);
|
|
21849
22015
|
}
|
|
21850
22016
|
catch {
|
|
21851
22017
|
// A class prefix can hold characters an attribute name cannot.
|
|
@@ -21858,32 +22024,20 @@ const Theme = ({ bulmaVars = {}, children, className, isRoot = false, colorMode,
|
|
|
21858
22024
|
'with that prefix keeps its scheme.');
|
|
21859
22025
|
}
|
|
21860
22026
|
}
|
|
21861
|
-
|
|
21862
|
-
|
|
21863
|
-
|
|
21864
|
-
const value = previous[i];
|
|
21865
|
-
if (value === null) {
|
|
21866
|
-
root.removeAttribute(name);
|
|
21867
|
-
}
|
|
21868
|
-
else {
|
|
21869
|
-
root.setAttribute(name, value);
|
|
21870
|
-
}
|
|
21871
|
-
});
|
|
21872
|
-
};
|
|
21873
|
-
}, [colorMode, classPrefix]);
|
|
22027
|
+
}, [colorMode, classPrefix, rootOrder]);
|
|
22028
|
+
// Hand the attributes back on unmount.
|
|
22029
|
+
React.useEffect(() => () => releaseSchemeAttributes(rootOrder), [rootOrder]);
|
|
21874
22030
|
// For local injection (when isRoot is false), prepare style object for CSS vars
|
|
21875
22031
|
const style = React.useMemo(() => {
|
|
21876
22032
|
if (isRoot) {
|
|
21877
22033
|
return {};
|
|
21878
22034
|
}
|
|
21879
22035
|
const styleObj = {};
|
|
21880
|
-
for (const [key, value] of
|
|
21881
|
-
|
|
21882
|
-
styleObj[key] = value;
|
|
21883
|
-
}
|
|
22036
|
+
for (const [key, value] of plainVars) {
|
|
22037
|
+
styleObj[key] = value;
|
|
21884
22038
|
}
|
|
21885
22039
|
return styleObj;
|
|
21886
|
-
}, [
|
|
22040
|
+
}, [plainVars, isRoot]);
|
|
21887
22041
|
// Generate combined class names for the wrapper div
|
|
21888
22042
|
const combinedClassName = React.useMemo(() => {
|
|
21889
22043
|
if (isRoot) {
|