diff --git a/package.json b/package.json index fe6e369..ea8d5e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@aet/tailwind", - "version": "1.0.7", + "version": "1.0.9", "license": "MIT", "scripts": { "build": "./scripts/index.ts", @@ -17,8 +17,12 @@ "./ยต": { "types": "./dist/macro.d.ts" }, - "./plugin/react-aria-components": "./dist/vendor/react-aria-components.js", "./plugin/animate": "./dist/vendor/animate.js", + "./plugin/aspect-ratio": "./dist/vendor/aspect-ratio.js", + "./plugin/container-queries": "./dist/vendor/container-queries.js", + "./plugin/forms": "./dist/vendor/forms.js", + "./plugin/react-aria-components": "./dist/vendor/react-aria-components.js", + "./plugin/typography": "./dist/vendor/typography.js", "./macro": { "types": "./dist/macro.d.ts" } diff --git a/scripts/index.ts b/scripts/index.ts index 34fa658..52d6f5b 100755 --- a/scripts/index.ts +++ b/scripts/index.ts @@ -30,18 +30,20 @@ await Promise.all([ entry: ["src/index.ts"], external: ["postcss-selector-parser", "postcss", "stylis"], }), - ...["animate", "aspect-ratio", "forms", "react-aria-components", "typography"].map( - name => - build({ - ...tsupConfig, - entry: [`./src/vendor/${name}.ts`], - outDir: "dist/vendor", - external: [ - "tailwindcss/plugin", - "tailwindcss/colors", - "tailwindcss/defaultTheme", - ], - }) + ...[ + "animate", + "aspect-ratio", + "container-queries", + "forms", + "react-aria-components", + "typography", + ].map(name => + build({ + ...tsupConfig, + entry: [`./src/vendor/${name}.ts`], + outDir: "dist/vendor", + external: ["tailwindcss/plugin", "tailwindcss/colors", "tailwindcss/defaultTheme"], + }) ), Bun.write( "dist/package.json", diff --git a/src/vendor/container-queries.ts b/src/vendor/container-queries.ts new file mode 100644 index 0000000..e60d33c --- /dev/null +++ b/src/vendor/container-queries.ts @@ -0,0 +1,86 @@ +// https://github.com/tailwindlabs/tailwindcss-container-queries/commit/f8d4307afdd3d913c3ddd406334c1a07f427c5b3 +import plugin from "tailwindcss/plugin"; + +function parseValue(value: string) { + const numericValue = value.match(/^(\d+\.\d+|\d+|\.\d+)\D+/)?.[1] ?? null; + if (numericValue === null) return null; + + return parseFloat(value); +} + +export default plugin( + ({ matchUtilities, matchVariant, theme }) => { + const values: Record = theme("containers") ?? {}; + + matchUtilities( + { + "@container": (value, { modifier }) => ({ + "container-type": value, + "container-name": modifier, + }), + }, + { + values: { + DEFAULT: "inline-size", + normal: "normal", + }, + modifiers: "any", + } + ); + + matchVariant( + "@", + (value = "", { modifier }) => { + const parsed = parseValue(value); + + return parsed !== null + ? `@container ${modifier ?? ""} (min-width: ${value})` + : []; + }, + { + values, + sort(aVariant, zVariant) { + const a = parseFloat(aVariant.value); + const z = parseFloat(zVariant.value); + + if (a === null || z === null) return 0; + + // Sort values themselves regardless of unit + if (a - z !== 0) return a - z; + + const aLabel = aVariant.modifier ?? ""; + const zLabel = zVariant.modifier ?? ""; + + // Explicitly move empty labels to the end + if (aLabel === "" && zLabel !== "") { + return 1; + } else if (aLabel !== "" && zLabel === "") { + return -1; + } + + // Sort labels alphabetically in the English locale + // We are intentionally overriding the locale because we do not want the sort to + // be affected by the machine's locale (be it a developer or CI environment) + return aLabel.localeCompare(zLabel, "en", { numeric: true }); + }, + } + ); + }, + { + theme: { + containers: { + xs: "20rem", + sm: "24rem", + md: "28rem", + lg: "32rem", + xl: "36rem", + "2xl": "42rem", + "3xl": "48rem", + "4xl": "56rem", + "5xl": "64rem", + "6xl": "72rem", + "7xl": "80rem", + }, + }, + } +);