@allxsmith/bestax-bulma 5.45.1 → 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/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 +190 -49
- package/dist/index.cjs.map +1 -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/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
|
@@ -20954,6 +20954,21 @@ const bulmaGlobalVars = [
|
|
|
20954
20954
|
'--bulma-danger-h',
|
|
20955
20955
|
'--bulma-danger-s',
|
|
20956
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',
|
|
20957
20972
|
// shadow (the upstream token .box/.card/.dropdown/.panel derive their own
|
|
20958
20973
|
// shadow variables from; overriding it from an ancestor is the route that
|
|
20959
20974
|
// cascades, since those selectors re-declare their derived var on
|
|
@@ -21704,6 +21719,104 @@ const setRootThemeRules = (order, rules) => {
|
|
|
21704
21719
|
}
|
|
21705
21720
|
renderRootThemeRules();
|
|
21706
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
|
+
};
|
|
21707
21820
|
/**
|
|
21708
21821
|
* Theme component that injects Bulma CSS variables either globally or locally.
|
|
21709
21822
|
*
|
|
@@ -21790,7 +21903,9 @@ const Theme = ({ bulmaVars = {}, children, className, isRoot = false, colorMode,
|
|
|
21790
21903
|
});
|
|
21791
21904
|
// Merge bulmaVars and individual props, with props taking precedence
|
|
21792
21905
|
const mergedVars = React.useMemo(() => {
|
|
21793
|
-
const vars = {
|
|
21906
|
+
const vars = {
|
|
21907
|
+
...bulmaVars,
|
|
21908
|
+
};
|
|
21794
21909
|
for (const [propName, cssVar] of Object.entries(bulmaVarPropMap)) {
|
|
21795
21910
|
if (bulmaVarProps[propName] !== undefined) {
|
|
21796
21911
|
vars[cssVar] = bulmaVarProps[propName];
|
|
@@ -21804,61 +21919,99 @@ const Theme = ({ bulmaVars = {}, children, className, isRoot = false, colorMode,
|
|
|
21804
21919
|
}
|
|
21805
21920
|
return vars;
|
|
21806
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]);
|
|
21807
21942
|
// From an effect rather than the render body, so rendering does none of
|
|
21808
21943
|
// this work, and a server render none at all. In production it returns
|
|
21809
21944
|
// at its development check before looking at the variables.
|
|
21810
21945
|
React.useEffect(() => {
|
|
21811
21946
|
warnComponentVars(mergedVars);
|
|
21812
21947
|
}, [mergedVars]);
|
|
21813
|
-
//
|
|
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`.
|
|
21814
21964
|
const [rootOrder] = React.useState(() => nextRootOrder++);
|
|
21815
|
-
//
|
|
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.
|
|
21816
21973
|
const rootRules = React.useMemo(() => {
|
|
21817
21974
|
if (!isRoot) {
|
|
21818
21975
|
return '';
|
|
21819
21976
|
}
|
|
21820
|
-
const
|
|
21821
|
-
|
|
21822
|
-
.
|
|
21823
|
-
|
|
21824
|
-
|
|
21825
|
-
}, [
|
|
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]);
|
|
21826
21983
|
// Inject CSS variables globally at :root level, alongside any other root
|
|
21827
21984
|
// Themes. Clearing `isRoot` or every variable passes '', which withdraws
|
|
21828
|
-
// this Theme's rules.
|
|
21829
|
-
|
|
21985
|
+
// this Theme's rules. A layout effect, so they are in place before the
|
|
21986
|
+
// browser paints what this Theme rendered.
|
|
21987
|
+
useClientLayoutEffect(() => {
|
|
21830
21988
|
setRootThemeRules(rootOrder, rootRules);
|
|
21831
21989
|
}, [rootOrder, rootRules]);
|
|
21832
21990
|
// Withdraw them on unmount. Kept apart from the effect above so a change
|
|
21833
21991
|
// rewrites the shared element in place rather than removing and recreating
|
|
21834
|
-
// 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.
|
|
21835
21995
|
React.useEffect(() => () => setRootThemeRules(rootOrder, ''), [rootOrder]);
|
|
21836
|
-
// Bulma names its scheme attribute after the class prefix a stylesheet was
|
|
21837
|
-
// built with (`data-<prefix>theme`), so the prefixed builds read
|
|
21838
|
-
// `data-bestax-theme` and never `data-theme`.
|
|
21839
|
-
const classPrefix = useClassPrefix();
|
|
21840
21996
|
// Toggle Bulma's light/dark scheme by writing the theme attribute on the
|
|
21841
21997
|
// document root (<html>). This is always global, even on a scoped Theme.
|
|
21842
21998
|
// Under a class prefix the prefixed attribute is written as well as
|
|
21843
21999
|
// `data-theme`, so whichever build is loaded sees it; with no prefix only
|
|
21844
22000
|
// `data-theme` is. `'system'` removes them so Bulma follows the OS
|
|
21845
|
-
// preference.
|
|
21846
|
-
|
|
21847
|
-
|
|
21848
|
-
|
|
21849
|
-
|
|
21850
|
-
|
|
21851
|
-
|
|
21852
|
-
|
|
21853
|
-
|
|
21854
|
-
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);
|
|
21855
22012
|
for (const name of names) {
|
|
21856
|
-
if (colorMode === 'system') {
|
|
21857
|
-
root.removeAttribute(name);
|
|
21858
|
-
continue;
|
|
21859
|
-
}
|
|
21860
22013
|
try {
|
|
21861
|
-
|
|
22014
|
+
writeSchemeAttribute(rootOrder, name, value);
|
|
21862
22015
|
}
|
|
21863
22016
|
catch {
|
|
21864
22017
|
// A class prefix can hold characters an attribute name cannot.
|
|
@@ -21871,32 +22024,20 @@ const Theme = ({ bulmaVars = {}, children, className, isRoot = false, colorMode,
|
|
|
21871
22024
|
'with that prefix keeps its scheme.');
|
|
21872
22025
|
}
|
|
21873
22026
|
}
|
|
21874
|
-
|
|
21875
|
-
|
|
21876
|
-
|
|
21877
|
-
const value = previous[i];
|
|
21878
|
-
if (value === null) {
|
|
21879
|
-
root.removeAttribute(name);
|
|
21880
|
-
}
|
|
21881
|
-
else {
|
|
21882
|
-
root.setAttribute(name, value);
|
|
21883
|
-
}
|
|
21884
|
-
});
|
|
21885
|
-
};
|
|
21886
|
-
}, [colorMode, classPrefix]);
|
|
22027
|
+
}, [colorMode, classPrefix, rootOrder]);
|
|
22028
|
+
// Hand the attributes back on unmount.
|
|
22029
|
+
React.useEffect(() => () => releaseSchemeAttributes(rootOrder), [rootOrder]);
|
|
21887
22030
|
// For local injection (when isRoot is false), prepare style object for CSS vars
|
|
21888
22031
|
const style = React.useMemo(() => {
|
|
21889
22032
|
if (isRoot) {
|
|
21890
22033
|
return {};
|
|
21891
22034
|
}
|
|
21892
22035
|
const styleObj = {};
|
|
21893
|
-
for (const [key, value] of
|
|
21894
|
-
|
|
21895
|
-
styleObj[key] = value;
|
|
21896
|
-
}
|
|
22036
|
+
for (const [key, value] of plainVars) {
|
|
22037
|
+
styleObj[key] = value;
|
|
21897
22038
|
}
|
|
21898
22039
|
return styleObj;
|
|
21899
|
-
}, [
|
|
22040
|
+
}, [plainVars, isRoot]);
|
|
21900
22041
|
// Generate combined class names for the wrapper div
|
|
21901
22042
|
const combinedClassName = React.useMemo(() => {
|
|
21902
22043
|
if (isRoot) {
|