UNPKG

@zeecoder/postcss-container-query

Version:

PostCSS processing for container queries, using a media query like syntax.

2 lines (1 loc) 3.75 kB
"use strict";function _interopDefault(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var postcss=_interopDefault(require("postcss")),MetaBuilder=_interopDefault(require("@zeecoder/container-query-meta-builder"));function hasContainerDefinition(e,t=!0){if(!e.nodes)return!1;const r=e.nodes.length;let n=0;for(;n<r;n++)if("atrule"===e.nodes[n].type&&"define-container"===e.nodes[n].name)return t&&e.nodes.splice(n,1),!0;return!1}function isValueUsingContainerUnits(e){if("string"!=typeof e)return!1;const t=e.toLowerCase().match(/(\d+(\.\d+)?)([rwhminax]+)/i);if(!Array.isArray(t)||"string"!=typeof t[3])return!1;const r=t[3];return"rh"===r||"rw"===r||"rmin"===r||"rmax"===r}function extractPropsFromNode(e,t={isContainer:!1,onlyContainerUnits:!1,stripContainerUnits:!1}){if("rule"!==e.type)throw new Error('`ruleNode` must be of type "rule".');if(!1===Array.isArray(e.nodes))return{};const r={styles:{},values:{}};let n=e.nodes.length;for(let o=0;o<n;o++){const i=e.nodes[o],s=isValueUsingContainerUnits(i.value);if("decl"===i.type&&(!t.onlyContainerUnits||s)){if(t.isContainer&&s){if(!("width"!==i.prop&&"height"!==i.prop||-1===i.value.indexOf("rmin")&&-1===i.value.indexOf("rmax")))throw i.error("Width and height properties on containers cannot use rmin or rmax units.");if("width"===i.prop&&-1!==i.value.indexOf("rw"))throw i.error("Containers cannot use rw for the width property.");if("height"===i.prop&&-1!==i.value.indexOf("rh"))throw i.error("Containers cannot use rh for the height property.")}s?r.values[i.prop]=i.value:r.styles[i.prop]=i.value,t.stripContainerUnits&&s&&(e.nodes.splice(o,1),o--,n--)}}return 0===Object.keys(r.styles).length&&delete r.styles,0===Object.keys(r.values).length&&delete r.values,r}const plugin="postcss-container-query",isContainerQuery=e=>"atrule"===e.type&&"container"===e.name,walkRules=(e,t,r)=>{const n=[],o=e=>-1!==n.indexOf(e),i=(e,i)=>{const s=hasContainerDefinition(e),a=s||o(e.selector)||":self"===e.selector||t.singleContainer&&0===n.length,l={rule:e,isContainer:a,definedContainer:s};a&&!o(e.selector)&&n.push(e.selector),i&&(l.parentCQAtRule=i),r(l)};e.walk(e=>{if("rule"===e.type)i(e);else if("atrule"===e.type){if(!isContainerQuery(e))return;e.nodes.forEach(t=>{"rule"===t.type&&i(t,e)}),e.remove()}})},getExportedMeta=(e,t)=>{let r=null;return e.each(e=>{":export"===e.selector&&e.nodes.forEach(e=>{if("decl"===e.type&&e.prop===t)try{r=JSON.parse(e.value.slice(1,-1))}catch(e){}})}),r};function containerQuery(e={}){const t=!1!==e.singleContainer,r=void 0!==e.exportMetaInCss?e.exportMetaInCss:"meta";return function(e,n){let o=getExportedMeta(e,r);if(!o){const n={};let i=null,s=0;walkRules(e,{singleContainer:t},({rule:e,isContainer:r,definedContainer:o,parentCQAtRule:a})=>{if(r&&":self"!==e.selector&&!n[e.selector]){o&&s++;const r=e.selector;if(s>1&&t&&i)throw e.error("More than one @define-container declaration was detected in singleContainer mode. "+`Tried to override "${i}" with "${r}".`);i=r,n[r]=new MetaBuilder(r)}const l=extractPropsFromNode(e,{isContainer:r,stripContainerUnits:!0});if(!(l.values||a&&l.styles))return;if(!i)throw e.error("Missing @define-container declaration before the processed node.");const u=n[i];if(u.resetQuery().resetDescendant(),a&&u.setQuery(a.params),r||u.setDescendant(e.selector),l.values)for(let e in l.values){const t=l.values[e];u.addStyle({prop:e,value:t})}if(a&&l.styles)for(let e in l.styles){const t=l.styles[e];u.addStyle({prop:e,value:t})}});for(let e in n)n[e]=n[e].build();o=t?i?n[i]:{}:n,r&&e.append(`\n:export { ${r}: '${JSON.stringify(o)}' }`)}n.messages.push({type:"metadata",plugin:plugin,meta:o,filepath:e.source.input.file})}}var containerQuery$1=postcss.plugin(plugin,containerQuery);module.exports=containerQuery$1;