|
| 1 | +import type { CSSRuleObject, PluginAPI } from "tailwindcss/types/config"; |
| 2 | +import type { IOptions } from "../types"; |
| 3 | + |
| 4 | +interface IOpts { |
| 5 | + lineSize: number; |
| 6 | + spacing: number; |
| 7 | + offsetX: number; |
| 8 | + offsetY: number; |
| 9 | + isCrossHatch: boolean; |
| 10 | + isRightLeaning: boolean; |
| 11 | + lineColor: string; |
| 12 | +} |
| 13 | + |
| 14 | +export const generateHatchingClass = ( |
| 15 | + className: string, |
| 16 | + _opts?: Partial<IOpts>, |
| 17 | +): CSSRuleObject => { |
| 18 | + const opts: IOpts = { |
| 19 | + lineSize: 1, |
| 20 | + lineColor: "#ffffff", |
| 21 | + spacing: 12, |
| 22 | + offsetX: 0, |
| 23 | + offsetY: 0, |
| 24 | + isCrossHatch: false, |
| 25 | + isRightLeaning: false, |
| 26 | + ..._opts, |
| 27 | + }; |
| 28 | + |
| 29 | + let bgImageCode = `linear-gradient( |
| 30 | + var(--tw-hatching-angle), |
| 31 | + transparent var(--tw-1st-start-stop), |
| 32 | + var(--tw-line-color) var(--tw-1st-start-stop), |
| 33 | + var(--tw-line-color) var(--tw-1st-end-stop), |
| 34 | + transparent var(--tw-1st-end-stop), |
| 35 | + transparent 100% |
| 36 | + ), |
| 37 | + linear-gradient( |
| 38 | + var(--tw-hatching-angle), |
| 39 | + transparent var(--tw-2ed-start-stop), |
| 40 | + var(--tw-line-color) var(--tw-2ed-start-stop), |
| 41 | + var(--tw-line-color) var(--tw-2ed-end-stop), |
| 42 | + transparent var(--tw-2ed-end-stop), |
| 43 | + transparent 100% |
| 44 | + ) |
| 45 | + `; |
| 46 | + |
| 47 | + if (opts.isCrossHatch) { |
| 48 | + bgImageCode += `, linear-gradient( |
| 49 | + calc(var(--tw-hatching-angle) * -1), |
| 50 | + transparent var(--tw-1st-start-stop), |
| 51 | + var(--tw-line-color) var(--tw-1st-start-stop), |
| 52 | + var(--tw-line-color) var(--tw-1st-end-stop), |
| 53 | + transparent var(--tw-1st-end-stop), |
| 54 | + transparent 100% |
| 55 | + ), |
| 56 | + linear-gradient( |
| 57 | + calc(var(--tw-hatching-angle) * -1), |
| 58 | + transparent var(--tw-2ed-start-stop), |
| 59 | + var(--tw-line-color) var(--tw-2ed-start-stop), |
| 60 | + var(--tw-line-color) var(--tw-2ed-end-stop), |
| 61 | + transparent var(--tw-2ed-end-stop), |
| 62 | + transparent 100% |
| 63 | + )`; |
| 64 | + } |
| 65 | + |
| 66 | + return { |
| 67 | + [`.${className}`]: { |
| 68 | + "--tw-line-size": opts.lineSize.toString(), |
| 69 | + "--tw-spacing": opts.spacing.toString(), |
| 70 | + "--tw-offset-x": `${opts.offsetX * -1}px`, |
| 71 | + "--tw-offset-y": `${opts.offsetY * -1}px`, |
| 72 | + "--tw-hatching-angle": `${opts.isRightLeaning ? -45 : 45}deg`, |
| 73 | + "--tw-line-color": opts.lineColor, |
| 74 | + |
| 75 | + "--tw-unit": "calc((var(--tw-line-size) + var(--tw-spacing)) * 2)", |
| 76 | + "--tw-line-stop": |
| 77 | + "calc((var(--tw-line-size) / var(--tw-unit) * 100%) / 2)", |
| 78 | + "--tw-1st-start-stop": "calc(75% - var(--tw-line-stop))", |
| 79 | + "--tw-1st-end-stop": "calc(75% + var(--tw-line-stop))", |
| 80 | + "--tw-2ed-start-stop": "calc(25% - var(--tw-line-stop))", |
| 81 | + "--tw-2ed-end-stop": "calc(25% + var(--tw-line-stop))", |
| 82 | + backgroundImage: bgImageCode, |
| 83 | + backgroundSize: "calc(var(--tw-unit) * 1px) calc(var(--tw-unit) * 1px)", |
| 84 | + backgroundPosition: |
| 85 | + "calc(var(--tw-spacing) * -0.5px + var(--tw-offset-x)) var(--tw-offset-y)", |
| 86 | + }, |
| 87 | + }; |
| 88 | +}; |
| 89 | + |
| 90 | +export const genreateHatchingDirection = ( |
| 91 | + api: PluginAPI, |
| 92 | + opts: IOptions, |
| 93 | +): CSSRuleObject => { |
| 94 | + return { |
| 95 | + [`.${api.e(`${opts.prefix}pattern-hatching-left-to-right`)}`]: { |
| 96 | + "--tw-hatching-angle": "45deg", |
| 97 | + }, |
| 98 | + [`.${api.e(`${opts.prefix}pattern-hatching-right-to-left`)}`]: { |
| 99 | + "--tw-hatching-angle": "-45deg", |
| 100 | + }, |
| 101 | + } as unknown as CSSRuleObject; |
| 102 | +}; |
0 commit comments