css-calipers 0.7.0 → 0.8.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/README.md +7 -0
- package/dist/cjs/mediaQueries/helpers.js +97 -0
- package/dist/cjs/mediaQueries/index.js +20 -0
- package/dist/cjs/mediaQueries/linting/core.js +19 -0
- package/dist/cjs/mediaQueries/linting/resolution.js +11 -0
- package/dist/cjs/mediaQueries/linting.js +24 -0
- package/dist/cjs/mediaQueries/mediaQueries.js +50 -0
- package/dist/cjs/mediaQueries/mediaQueryFactory.js +120 -0
- package/dist/cjs/mediaQueries/modules/custom.js +26 -0
- package/dist/cjs/mediaQueries/modules/dimensions.js +59 -0
- package/dist/cjs/mediaQueries/modules/display.js +20 -0
- package/dist/cjs/mediaQueries/modules/environment.js +20 -0
- package/dist/cjs/mediaQueries/modules/index.js +23 -0
- package/dist/cjs/mediaQueries/modules/interaction.js +26 -0
- package/dist/cjs/mediaQueries/modules/preferences.js +26 -0
- package/dist/cjs/mediaQueries/modules/resolution.js +29 -0
- package/dist/cjs/mediaQueries/types.js +2 -0
- package/dist/cjs/mediaQueries/validation.js +133 -0
- package/dist/esm/mediaQueries/helpers.d.ts +40 -0
- package/dist/esm/mediaQueries/helpers.d.ts.map +1 -0
- package/dist/esm/mediaQueries/helpers.js +87 -0
- package/dist/esm/mediaQueries/index.d.ts +5 -0
- package/dist/esm/mediaQueries/index.d.ts.map +1 -0
- package/dist/esm/mediaQueries/index.js +4 -0
- package/dist/esm/mediaQueries/linting/core.d.ts +5 -0
- package/dist/esm/mediaQueries/linting/core.d.ts.map +1 -0
- package/dist/esm/mediaQueries/linting/core.js +14 -0
- package/dist/esm/mediaQueries/linting/resolution.d.ts +3 -0
- package/dist/esm/mediaQueries/linting/resolution.d.ts.map +1 -0
- package/dist/esm/mediaQueries/linting/resolution.js +7 -0
- package/dist/esm/mediaQueries/linting.d.ts +4 -0
- package/dist/esm/mediaQueries/linting.d.ts.map +1 -0
- package/dist/esm/mediaQueries/linting.js +20 -0
- package/dist/esm/mediaQueries/mediaQueries.d.ts +19 -0
- package/dist/esm/mediaQueries/mediaQueries.d.ts.map +1 -0
- package/dist/esm/mediaQueries/mediaQueries.js +46 -0
- package/dist/esm/mediaQueries/modules/custom.d.ts +10 -0
- package/dist/esm/mediaQueries/modules/custom.d.ts.map +1 -0
- package/dist/esm/mediaQueries/modules/custom.js +22 -0
- package/dist/esm/mediaQueries/modules/dimensions.d.ts +17 -0
- package/dist/esm/mediaQueries/modules/dimensions.d.ts.map +1 -0
- package/dist/esm/mediaQueries/modules/dimensions.js +55 -0
- package/dist/esm/mediaQueries/modules/display.d.ts +9 -0
- package/dist/esm/mediaQueries/modules/display.d.ts.map +1 -0
- package/dist/esm/mediaQueries/modules/display.js +16 -0
- package/dist/esm/mediaQueries/modules/environment.d.ts +9 -0
- package/dist/esm/mediaQueries/modules/environment.d.ts.map +1 -0
- package/dist/esm/mediaQueries/modules/environment.js +16 -0
- package/dist/esm/mediaQueries/modules/index.d.ts +8 -0
- package/dist/esm/mediaQueries/modules/index.d.ts.map +1 -0
- package/dist/esm/mediaQueries/modules/index.js +7 -0
- package/dist/esm/mediaQueries/modules/interaction.d.ts +11 -0
- package/dist/esm/mediaQueries/modules/interaction.d.ts.map +1 -0
- package/dist/esm/mediaQueries/modules/interaction.js +22 -0
- package/dist/esm/mediaQueries/modules/preferences.d.ts +11 -0
- package/dist/esm/mediaQueries/modules/preferences.d.ts.map +1 -0
- package/dist/esm/mediaQueries/modules/preferences.js +22 -0
- package/dist/esm/mediaQueries/modules/resolution.d.ts +10 -0
- package/dist/esm/mediaQueries/modules/resolution.d.ts.map +1 -0
- package/dist/esm/mediaQueries/modules/resolution.js +25 -0
- package/dist/esm/mediaQueries/types.d.ts +117 -0
- package/dist/esm/mediaQueries/types.d.ts.map +1 -0
- package/dist/esm/mediaQueries/types.js +1 -0
- package/dist/esm/mediaQueries/validation.d.ts +14 -0
- package/dist/esm/mediaQueries/validation.d.ts.map +1 -0
- package/dist/esm/mediaQueries/validation.js +122 -0
- package/package.json +20 -9
package/README.md
CHANGED
|
@@ -7,6 +7,13 @@ CSS-Calipers is a tiny layer for typed CSS measurements. Stop parsing CSS
|
|
|
7
7
|
strings and concatenating units. Do your math on real numbers, get
|
|
8
8
|
compile-time unit safety, and output CSS only at the edges.
|
|
9
9
|
|
|
10
|
+
This README is a general overview. Deeper module guides live in their own files.
|
|
11
|
+
|
|
12
|
+
Module guides:
|
|
13
|
+
|
|
14
|
+
- Measurements core: README_MEASUREMENT.md
|
|
15
|
+
- Media queries: README_MEDIAQUERIES.md
|
|
16
|
+
|
|
10
17
|
At a glance:
|
|
11
18
|
|
|
12
19
|
- Create measurements with `m` from a number and a unit; if you omit the unit, it defaults to `px` and is typed as the px measurement type.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildMediaQueryFromFeatures = exports.applyMediaQueryValidation = exports.createMediaQueryBuilder = exports.createMediaQueryFeatureEmitterWithTracking = exports.createMediaQueryFeatureEmitter = exports.buildMediaQueryStringFromParts = exports.formatMediaQueryValue = void 0;
|
|
4
|
+
const core_1 = require("../core");
|
|
5
|
+
const formatMediaQueryValue = (value) => ((0, core_1.hasCssMethod)(value) ? value.css() : String(value));
|
|
6
|
+
exports.formatMediaQueryValue = formatMediaQueryValue;
|
|
7
|
+
const buildMediaQueryStringFromParts = (mediaType, parts) => (parts.length ? `${mediaType} and ${parts.join(' and ')}` : mediaType);
|
|
8
|
+
exports.buildMediaQueryStringFromParts = buildMediaQueryStringFromParts;
|
|
9
|
+
const createMediaQueryFeatureEmitter = (parts) => (name, value) => {
|
|
10
|
+
parts.push(`(${name}: ${(0, exports.formatMediaQueryValue)(value)})`);
|
|
11
|
+
};
|
|
12
|
+
exports.createMediaQueryFeatureEmitter = createMediaQueryFeatureEmitter;
|
|
13
|
+
const createMediaQueryFeatureEmitterWithTracking = (parts, options = {}) => {
|
|
14
|
+
const { emitted, lintingMode = 'throw' } = options;
|
|
15
|
+
return (name, value) => {
|
|
16
|
+
if (emitted === null || emitted === void 0 ? void 0 : emitted.has(name)) {
|
|
17
|
+
if (lintingMode === 'throw') {
|
|
18
|
+
throw new Error(`Media query feature "${name}" was emitted more than once.`);
|
|
19
|
+
}
|
|
20
|
+
if (lintingMode === 'log') {
|
|
21
|
+
console.warn(`Media query feature "${name}" was emitted more than once; using the latest value.`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
emitted === null || emitted === void 0 ? void 0 : emitted.add(name);
|
|
25
|
+
parts.push(`(${name}: ${(0, exports.formatMediaQueryValue)(value)})`);
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
exports.createMediaQueryFeatureEmitterWithTracking = createMediaQueryFeatureEmitterWithTracking;
|
|
29
|
+
const createMediaQueryBuilder = (options) => {
|
|
30
|
+
return (config) => {
|
|
31
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
32
|
+
const parts = [];
|
|
33
|
+
const emittedFeatures = new Set();
|
|
34
|
+
const helpers = {
|
|
35
|
+
addFeature: (0, exports.createMediaQueryFeatureEmitterWithTracking)(parts, {
|
|
36
|
+
emitted: emittedFeatures,
|
|
37
|
+
lintingMode: (_c = (_b = (_a = options.config) === null || _a === void 0 ? void 0 : _a.errorHandling) === null || _b === void 0 ? void 0 : _b.lintingMode) !== null && _c !== void 0 ? _c : 'throw',
|
|
38
|
+
}),
|
|
39
|
+
config: (_d = options.config) !== null && _d !== void 0 ? _d : {},
|
|
40
|
+
};
|
|
41
|
+
options.emitBase(config, helpers);
|
|
42
|
+
(_e = options.emitExtensions) === null || _e === void 0 ? void 0 : _e.call(options, config, helpers);
|
|
43
|
+
const mediaType = (_g = (_f = options.resolveType) === null || _f === void 0 ? void 0 : _f.call(options, config)) !== null && _g !== void 0 ? _g : 'screen';
|
|
44
|
+
return (0, exports.buildMediaQueryStringFromParts)(mediaType, parts);
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
exports.createMediaQueryBuilder = createMediaQueryBuilder;
|
|
48
|
+
const normalizeValidationResult = (result) => {
|
|
49
|
+
if (result === undefined || result === null)
|
|
50
|
+
return { valid: true };
|
|
51
|
+
if (typeof result === 'boolean')
|
|
52
|
+
return { valid: result };
|
|
53
|
+
if (typeof result === 'string') {
|
|
54
|
+
return result ? { valid: false, message: result } : { valid: true };
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
};
|
|
58
|
+
const applyMediaQueryValidation = (config, helpers, validator, context) => {
|
|
59
|
+
var _a, _b;
|
|
60
|
+
if (!validator)
|
|
61
|
+
return true;
|
|
62
|
+
const normalized = normalizeValidationResult(validator(config));
|
|
63
|
+
if (normalized.valid)
|
|
64
|
+
return true;
|
|
65
|
+
const mode = (_b = (_a = helpers.config.errorHandling) === null || _a === void 0 ? void 0 : _a.invalidValueMode) !== null && _b !== void 0 ? _b : 'throw';
|
|
66
|
+
if (mode === 'log') {
|
|
67
|
+
const suffix = normalized.message ? `: ${normalized.message}` : '';
|
|
68
|
+
const prefix = context
|
|
69
|
+
? `Media query ${context} validation failed`
|
|
70
|
+
: 'Media query validation failed';
|
|
71
|
+
console.warn(`${prefix}${suffix}`);
|
|
72
|
+
}
|
|
73
|
+
if (mode === 'allow')
|
|
74
|
+
return true;
|
|
75
|
+
if (mode === 'log')
|
|
76
|
+
return true;
|
|
77
|
+
const suffix = normalized.message ? `: ${normalized.message}` : '';
|
|
78
|
+
const prefix = context
|
|
79
|
+
? `Media query ${context} validation failed`
|
|
80
|
+
: 'Media query validation failed';
|
|
81
|
+
throw new Error(`${prefix}${suffix}`);
|
|
82
|
+
};
|
|
83
|
+
exports.applyMediaQueryValidation = applyMediaQueryValidation;
|
|
84
|
+
const buildMediaQueryFromFeatures = (features, mediaType = 'screen') => {
|
|
85
|
+
const parts = [];
|
|
86
|
+
const addFeature = (0, exports.createMediaQueryFeatureEmitterWithTracking)(parts, {
|
|
87
|
+
emitted: new Set(),
|
|
88
|
+
lintingMode: 'throw',
|
|
89
|
+
});
|
|
90
|
+
Object.entries(features).forEach(([name, value]) => {
|
|
91
|
+
if (value === undefined || value === null)
|
|
92
|
+
return;
|
|
93
|
+
addFeature(name, value);
|
|
94
|
+
});
|
|
95
|
+
return (0, exports.buildMediaQueryStringFromParts)(mediaType, parts);
|
|
96
|
+
};
|
|
97
|
+
exports.buildMediaQueryFromFeatures = buildMediaQueryFromFeatures;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./helpers"), exports);
|
|
19
|
+
__exportStar(require("./mediaQueries"), exports);
|
|
20
|
+
__exportStar(require("./modules"), exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.lintHeightRedundancy = exports.lintWidthRedundancy = void 0;
|
|
4
|
+
const lintWidthRedundancy = (props) => {
|
|
5
|
+
if (!props.width)
|
|
6
|
+
return;
|
|
7
|
+
if (props.minWidth || props.maxWidth) {
|
|
8
|
+
throw new Error('width should not be combined with minWidth or maxWidth');
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
exports.lintWidthRedundancy = lintWidthRedundancy;
|
|
12
|
+
const lintHeightRedundancy = (props) => {
|
|
13
|
+
if (!props.height)
|
|
14
|
+
return;
|
|
15
|
+
if (props.minHeight || props.maxHeight) {
|
|
16
|
+
throw new Error('height should not be combined with minHeight or maxHeight');
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
exports.lintHeightRedundancy = lintHeightRedundancy;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.lintResolutionRedundancy = void 0;
|
|
4
|
+
const lintResolutionRedundancy = (props) => {
|
|
5
|
+
if (!props.resolutionValue)
|
|
6
|
+
return;
|
|
7
|
+
if (props.minResolution || props.maxResolution) {
|
|
8
|
+
throw new Error('resolution should not be combined with minResolution or maxResolution');
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
exports.lintResolutionRedundancy = lintResolutionRedundancy;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runMediaQueryLint = void 0;
|
|
4
|
+
const runMediaQueryLint = (config, helpers, check, message = 'Media query lint failed') => {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
if (!check)
|
|
7
|
+
return true;
|
|
8
|
+
const mode = (_b = (_a = helpers.config.errorHandling) === null || _a === void 0 ? void 0 : _a.lintingMode) !== null && _b !== void 0 ? _b : 'allow';
|
|
9
|
+
if (mode === 'allow')
|
|
10
|
+
return true;
|
|
11
|
+
if (mode === 'log') {
|
|
12
|
+
try {
|
|
13
|
+
check(config);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
console.warn(message);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
check(config);
|
|
22
|
+
return true;
|
|
23
|
+
};
|
|
24
|
+
exports.runMediaQueryLint = runMediaQueryLint;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeMediaQueryStyle = exports.buildMediaQueryString = void 0;
|
|
4
|
+
const helpers_1 = require("./helpers");
|
|
5
|
+
const validation_1 = require("./validation");
|
|
6
|
+
const modules_1 = require("./modules");
|
|
7
|
+
const emitCoreFeatures = (props, helpers) => {
|
|
8
|
+
if (!(0, validation_1.runMediaQueryValidation)(props, helpers, validation_1.validateMinMaxWidth, "core", "minWidth must be less than or equal to maxWidth")) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (!(0, validation_1.runMediaQueryValidation)(props, helpers, validation_1.validateWidthValuesPositive, "core", "width values must be greater than 0")) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const { addFeature } = helpers;
|
|
15
|
+
if (props.minWidth) {
|
|
16
|
+
addFeature("min-width", props.minWidth);
|
|
17
|
+
}
|
|
18
|
+
if (props.maxWidth) {
|
|
19
|
+
addFeature("max-width", props.maxWidth);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const emitBaseFeatures = (props, helpers) => {
|
|
23
|
+
emitCoreFeatures(props, helpers);
|
|
24
|
+
(0, modules_1.emitDimensionsFeatures)(props, helpers);
|
|
25
|
+
(0, modules_1.emitResolutionFeatures)(props, helpers);
|
|
26
|
+
(0, modules_1.emitInteractionFeatures)(props, helpers);
|
|
27
|
+
(0, modules_1.emitPreferencesFeatures)(props, helpers);
|
|
28
|
+
(0, modules_1.emitDisplayFeatures)(props, helpers);
|
|
29
|
+
(0, modules_1.emitEnvironmentFeatures)(props, helpers);
|
|
30
|
+
(0, modules_1.emitCustomFeatures)(props, helpers);
|
|
31
|
+
};
|
|
32
|
+
exports.buildMediaQueryString = (0, helpers_1.createMediaQueryBuilder)({
|
|
33
|
+
emitBase: emitBaseFeatures,
|
|
34
|
+
resolveType: (props) => props.type,
|
|
35
|
+
});
|
|
36
|
+
const makeMediaQueryStyle = (queries) => (stylesByQuery) => {
|
|
37
|
+
const result = {};
|
|
38
|
+
Object.keys(stylesByQuery).forEach((key) => {
|
|
39
|
+
const styles = stylesByQuery[key];
|
|
40
|
+
const props = queries[key];
|
|
41
|
+
if (!styles || !props)
|
|
42
|
+
return;
|
|
43
|
+
result[(0, exports.buildMediaQueryString)(props)] = styles;
|
|
44
|
+
});
|
|
45
|
+
const mediaQuery = {
|
|
46
|
+
"@media": result,
|
|
47
|
+
};
|
|
48
|
+
return mediaQuery;
|
|
49
|
+
};
|
|
50
|
+
exports.makeMediaQueryStyle = makeMediaQueryStyle;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.queriesToStrings = queriesToStrings;
|
|
4
|
+
exports.useMediaQuery = useMediaQuery;
|
|
5
|
+
exports.useMediaFromMap = useMediaFromMap;
|
|
6
|
+
exports.makeClientFns = makeClientFns;
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const mediaQueries_1 = require("./mediaQueries");
|
|
9
|
+
function toQueryString(q) {
|
|
10
|
+
return (0, mediaQueries_1.buildMediaQueryString)(q);
|
|
11
|
+
}
|
|
12
|
+
function queriesToStrings(queries) {
|
|
13
|
+
return Object.fromEntries(Object.entries(queries).map(([k, v,]) => [
|
|
14
|
+
k,
|
|
15
|
+
typeof v === 'string' ? v : toQueryString(v),
|
|
16
|
+
]));
|
|
17
|
+
}
|
|
18
|
+
// ---------- Core hooks ----------
|
|
19
|
+
/**
|
|
20
|
+
* SSR-safe: undefined on server, boolean on client; subscribes to
|
|
21
|
+
* changes.
|
|
22
|
+
*/
|
|
23
|
+
function useMediaQuery(queryString) {
|
|
24
|
+
const [matches, setMatches,] = (0, react_1.useState)(undefined);
|
|
25
|
+
(0, react_1.useEffect)(() => {
|
|
26
|
+
var _a;
|
|
27
|
+
if (typeof window === 'undefined')
|
|
28
|
+
return;
|
|
29
|
+
const mql = window.matchMedia(queryString);
|
|
30
|
+
const onChange = () => setMatches(mql.matches);
|
|
31
|
+
const frameId = requestAnimationFrame(() => {
|
|
32
|
+
setMatches(mql.matches);
|
|
33
|
+
});
|
|
34
|
+
(_a = mql.addEventListener) === null || _a === void 0 ? void 0 : _a.call(mql, 'change', onChange);
|
|
35
|
+
return () => {
|
|
36
|
+
var _a;
|
|
37
|
+
(_a = mql.removeEventListener) === null || _a === void 0 ? void 0 : _a.call(mql, 'change', onChange);
|
|
38
|
+
cancelAnimationFrame(frameId);
|
|
39
|
+
};
|
|
40
|
+
}, [
|
|
41
|
+
queryString,
|
|
42
|
+
]);
|
|
43
|
+
return matches;
|
|
44
|
+
}
|
|
45
|
+
// Aggregate hook with guarded updates to avoid loops
|
|
46
|
+
function useMediaFromMap(strings) {
|
|
47
|
+
const shallowEqual = (0, react_1.useCallback)((a, b) => {
|
|
48
|
+
const ak = Object.keys(a);
|
|
49
|
+
const bk = Object.keys(b);
|
|
50
|
+
if (ak.length !== bk.length)
|
|
51
|
+
return false;
|
|
52
|
+
for (const k of ak)
|
|
53
|
+
if (a[k] !== b[k])
|
|
54
|
+
return false;
|
|
55
|
+
return true;
|
|
56
|
+
}, []);
|
|
57
|
+
// Stable, sorted list of [key, queryString]
|
|
58
|
+
const entries = (0, react_1.useMemo)(() => {
|
|
59
|
+
const e = Object.entries(strings);
|
|
60
|
+
e.sort((a, b) => a[0].localeCompare(b[0]));
|
|
61
|
+
return e;
|
|
62
|
+
}, [
|
|
63
|
+
strings,
|
|
64
|
+
]);
|
|
65
|
+
const [matches, setMatches,] = (0, react_1.useState)(() => Object.create(null));
|
|
66
|
+
(0, react_1.useEffect)(() => {
|
|
67
|
+
if (typeof window === 'undefined')
|
|
68
|
+
return;
|
|
69
|
+
const mqls = entries.map(([k, qs,]) => [
|
|
70
|
+
k,
|
|
71
|
+
window.matchMedia(qs),
|
|
72
|
+
]);
|
|
73
|
+
// Initial snapshot — only set if changed
|
|
74
|
+
const initial = Object.fromEntries(mqls.map(([k, mql,]) => [
|
|
75
|
+
k,
|
|
76
|
+
mql.matches,
|
|
77
|
+
]));
|
|
78
|
+
const frameId = requestAnimationFrame(() => {
|
|
79
|
+
setMatches((prev) => shallowEqual(prev, initial) ? prev : initial);
|
|
80
|
+
});
|
|
81
|
+
// Subscribe with guarded setState
|
|
82
|
+
const handlers = mqls.map(([k, mql,]) => {
|
|
83
|
+
var _a;
|
|
84
|
+
const onChange = () => setMatches((prev) => {
|
|
85
|
+
const next = {
|
|
86
|
+
...prev,
|
|
87
|
+
[k]: mql.matches,
|
|
88
|
+
};
|
|
89
|
+
return shallowEqual(prev, next) ? prev : next;
|
|
90
|
+
});
|
|
91
|
+
(_a = mql.addEventListener) === null || _a === void 0 ? void 0 : _a.call(mql, 'change', onChange);
|
|
92
|
+
return [
|
|
93
|
+
mql,
|
|
94
|
+
onChange,
|
|
95
|
+
];
|
|
96
|
+
});
|
|
97
|
+
return () => {
|
|
98
|
+
var _a;
|
|
99
|
+
cancelAnimationFrame(frameId);
|
|
100
|
+
for (const [mql, onChange,] of handlers) {
|
|
101
|
+
(_a = mql.removeEventListener) === null || _a === void 0 ? void 0 : _a.call(mql, 'change', onChange);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}, [
|
|
105
|
+
entries,
|
|
106
|
+
shallowEqual,
|
|
107
|
+
]);
|
|
108
|
+
return matches;
|
|
109
|
+
}
|
|
110
|
+
// ---------- Client-only predicates ----------
|
|
111
|
+
/** For event handlers/effects only; don't call in SSR render paths. */
|
|
112
|
+
function makeClientFns(strings) {
|
|
113
|
+
const out = {};
|
|
114
|
+
Object.keys(strings).forEach((k) => {
|
|
115
|
+
out[k] = () => typeof window !== 'undefined'
|
|
116
|
+
? window.matchMedia(strings[k]).matches
|
|
117
|
+
: false;
|
|
118
|
+
});
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitCustomFeatures = void 0;
|
|
4
|
+
const core_1 = require("../../core");
|
|
5
|
+
const helpers_1 = require("../helpers");
|
|
6
|
+
const emitCustomFeatures = (props, helpers, validate) => {
|
|
7
|
+
if (!(0, helpers_1.applyMediaQueryValidation)(props, helpers, validate, 'custom')) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const { addFeature } = helpers;
|
|
11
|
+
if (!props.customFeatures)
|
|
12
|
+
return;
|
|
13
|
+
Object.entries(props.customFeatures).forEach(([name, value]) => {
|
|
14
|
+
if (value === undefined || value === null)
|
|
15
|
+
return;
|
|
16
|
+
const trimmedName = name.trim();
|
|
17
|
+
if (!trimmedName) {
|
|
18
|
+
throw new Error('Custom feature name must be non-empty.');
|
|
19
|
+
}
|
|
20
|
+
if (typeof value === 'object' && !(0, core_1.hasCssMethod)(value)) {
|
|
21
|
+
throw new Error(`Custom feature "${trimmedName}" must be a primitive or a measurement.`);
|
|
22
|
+
}
|
|
23
|
+
addFeature(trimmedName, value);
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
exports.emitCustomFeatures = emitCustomFeatures;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitDimensionsFeatures = void 0;
|
|
4
|
+
const helpers_1 = require("../helpers");
|
|
5
|
+
const validation_1 = require("../validation");
|
|
6
|
+
const linting_1 = require("../linting");
|
|
7
|
+
const core_1 = require("../linting/core");
|
|
8
|
+
const emitDimensionsFeatures = (props, helpers, validate) => {
|
|
9
|
+
if (!(0, validation_1.runMediaQueryValidation)(props, helpers, validation_1.validateMinMaxHeight, 'dimensions', 'minHeight must be less than or equal to maxHeight')) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (!(0, validation_1.runMediaQueryValidation)(props, helpers, validation_1.validateHeightValuesPositive, 'dimensions', 'height values must be greater than 0')) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!(0, linting_1.runMediaQueryLint)(props, helpers, core_1.lintWidthRedundancy, 'width should not be combined with minWidth or maxWidth')) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (!(0, linting_1.runMediaQueryLint)(props, helpers, core_1.lintHeightRedundancy, 'height should not be combined with minHeight or maxHeight')) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!(0, validation_1.runMediaQueryValidation)(props, helpers, validation_1.validateWidthValuesPositive, 'dimensions', 'width values must be greater than 0')) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (!(0, validation_1.runMediaQueryValidation)(props, helpers, validation_1.validateMinMaxAspectRatio, 'dimensions', 'minAspectRatio must be less than or equal to maxAspectRatio')) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!(0, validation_1.runMediaQueryValidation)(props, helpers, validation_1.validateAspectRatioValuesPositive, 'dimensions', 'aspect ratio values must be greater than 0')) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!(0, helpers_1.applyMediaQueryValidation)(props, helpers, validate, 'dimensions')) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const { addFeature } = helpers;
|
|
34
|
+
if (props.width) {
|
|
35
|
+
addFeature('width', props.width);
|
|
36
|
+
}
|
|
37
|
+
if (props.height) {
|
|
38
|
+
addFeature('height', props.height);
|
|
39
|
+
}
|
|
40
|
+
if (props.minHeight) {
|
|
41
|
+
addFeature('min-height', props.minHeight);
|
|
42
|
+
}
|
|
43
|
+
if (props.maxHeight) {
|
|
44
|
+
addFeature('max-height', props.maxHeight);
|
|
45
|
+
}
|
|
46
|
+
if (props.aspectRatio) {
|
|
47
|
+
addFeature('aspect-ratio', props.aspectRatio);
|
|
48
|
+
}
|
|
49
|
+
if (props.minAspectRatio) {
|
|
50
|
+
addFeature('min-aspect-ratio', props.minAspectRatio);
|
|
51
|
+
}
|
|
52
|
+
if (props.maxAspectRatio) {
|
|
53
|
+
addFeature('max-aspect-ratio', props.maxAspectRatio);
|
|
54
|
+
}
|
|
55
|
+
if (props.orientation) {
|
|
56
|
+
addFeature('orientation', props.orientation);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
exports.emitDimensionsFeatures = emitDimensionsFeatures;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitDisplayFeatures = void 0;
|
|
4
|
+
const helpers_1 = require("../helpers");
|
|
5
|
+
const emitDisplayFeatures = (props, helpers, validate) => {
|
|
6
|
+
if (!(0, helpers_1.applyMediaQueryValidation)(props, helpers, validate, 'display')) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const { addFeature } = helpers;
|
|
10
|
+
if (props.colorGamut) {
|
|
11
|
+
addFeature('color-gamut', props.colorGamut);
|
|
12
|
+
}
|
|
13
|
+
if (props.dynamicRange) {
|
|
14
|
+
addFeature('dynamic-range', props.dynamicRange);
|
|
15
|
+
}
|
|
16
|
+
if (props.invertedColors) {
|
|
17
|
+
addFeature('inverted-colors', props.invertedColors);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
exports.emitDisplayFeatures = emitDisplayFeatures;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitEnvironmentFeatures = void 0;
|
|
4
|
+
const helpers_1 = require("../helpers");
|
|
5
|
+
const emitEnvironmentFeatures = (props, helpers, validate) => {
|
|
6
|
+
if (!(0, helpers_1.applyMediaQueryValidation)(props, helpers, validate, 'environment')) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const { addFeature } = helpers;
|
|
10
|
+
if (props.scripting) {
|
|
11
|
+
addFeature('scripting', props.scripting);
|
|
12
|
+
}
|
|
13
|
+
if (props.overflowBlock) {
|
|
14
|
+
addFeature('overflow-block', props.overflowBlock);
|
|
15
|
+
}
|
|
16
|
+
if (props.overflowInline) {
|
|
17
|
+
addFeature('overflow-inline', props.overflowInline);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
exports.emitEnvironmentFeatures = emitEnvironmentFeatures;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./custom"), exports);
|
|
18
|
+
__exportStar(require("./dimensions"), exports);
|
|
19
|
+
__exportStar(require("./display"), exports);
|
|
20
|
+
__exportStar(require("./environment"), exports);
|
|
21
|
+
__exportStar(require("./interaction"), exports);
|
|
22
|
+
__exportStar(require("./preferences"), exports);
|
|
23
|
+
__exportStar(require("./resolution"), exports);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitInteractionFeatures = void 0;
|
|
4
|
+
const helpers_1 = require("../helpers");
|
|
5
|
+
const emitInteractionFeatures = (props, helpers, validate) => {
|
|
6
|
+
if (!(0, helpers_1.applyMediaQueryValidation)(props, helpers, validate, 'interaction')) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const { addFeature } = helpers;
|
|
10
|
+
if (props.hover) {
|
|
11
|
+
addFeature('hover', props.hover);
|
|
12
|
+
}
|
|
13
|
+
if (props.anyHover) {
|
|
14
|
+
addFeature('any-hover', props.anyHover);
|
|
15
|
+
}
|
|
16
|
+
if (props.pointer) {
|
|
17
|
+
addFeature('pointer', props.pointer);
|
|
18
|
+
}
|
|
19
|
+
if (props.anyPointer) {
|
|
20
|
+
addFeature('any-pointer', props.anyPointer);
|
|
21
|
+
}
|
|
22
|
+
if (props.update) {
|
|
23
|
+
addFeature('update', props.update);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.emitInteractionFeatures = emitInteractionFeatures;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitPreferencesFeatures = void 0;
|
|
4
|
+
const helpers_1 = require("../helpers");
|
|
5
|
+
const emitPreferencesFeatures = (props, helpers, validate) => {
|
|
6
|
+
if (!(0, helpers_1.applyMediaQueryValidation)(props, helpers, validate, 'preferences')) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const { addFeature } = helpers;
|
|
10
|
+
if (props.colorScheme) {
|
|
11
|
+
addFeature('prefers-color-scheme', props.colorScheme);
|
|
12
|
+
}
|
|
13
|
+
if (props.reducedMotion) {
|
|
14
|
+
addFeature('prefers-reduced-motion', props.reducedMotion);
|
|
15
|
+
}
|
|
16
|
+
if (props.reducedData) {
|
|
17
|
+
addFeature('prefers-reduced-data', props.reducedData);
|
|
18
|
+
}
|
|
19
|
+
if (props.contrast) {
|
|
20
|
+
addFeature('prefers-contrast', props.contrast);
|
|
21
|
+
}
|
|
22
|
+
if (props.forcedColors) {
|
|
23
|
+
addFeature('forced-colors', props.forcedColors);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.emitPreferencesFeatures = emitPreferencesFeatures;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitResolutionFeatures = void 0;
|
|
4
|
+
const helpers_1 = require("../helpers");
|
|
5
|
+
const validation_1 = require("../validation");
|
|
6
|
+
const linting_1 = require("../linting");
|
|
7
|
+
const resolution_1 = require("../linting/resolution");
|
|
8
|
+
const emitResolutionFeatures = (props, helpers, validate) => {
|
|
9
|
+
if (!(0, validation_1.runMediaQueryValidation)(props, helpers, validation_1.validateResolutionValues, 'resolution', 'resolution values must be greater than 0')) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (!(0, linting_1.runMediaQueryLint)(props, helpers, resolution_1.lintResolutionRedundancy, 'resolution should not be combined with minResolution or maxResolution')) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!(0, helpers_1.applyMediaQueryValidation)(props, helpers, validate, 'resolution')) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const { addFeature } = helpers;
|
|
19
|
+
if (props.resolutionValue) {
|
|
20
|
+
addFeature('resolution', props.resolutionValue);
|
|
21
|
+
}
|
|
22
|
+
if (props.minResolution) {
|
|
23
|
+
addFeature('min-resolution', props.minResolution);
|
|
24
|
+
}
|
|
25
|
+
if (props.maxResolution) {
|
|
26
|
+
addFeature('max-resolution', props.maxResolution);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.emitResolutionFeatures = emitResolutionFeatures;
|