├── .gitignore ├── src ├── index.d.ts ├── index.js └── index.test.js ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── 1.bug_report.yml └── workflows │ ├── nodejs.yml │ └── release-insiders.yml ├── package.json ├── LICENSE ├── CHANGELOG.md ├── README.md └── jest └── customMatchers.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /src/index.d.ts: -------------------------------------------------------------------------------- 1 | declare const plugin: { handler: () => void } 2 | export = plugin 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Feature Request 4 | url: https://github.com/tailwindlabs/tailwindcss/discussions/new?category=ideas 5 | about: 'Suggest any ideas you have using our discussion forums.' 6 | - name: Help 7 | url: https://github.com/tailwindlabs/tailwindcss/discussions/new?category=help 8 | about: 'If you have a question or need help, ask a question on the discussion forums.' 9 | - name: Kind Words 10 | url: https://github.com/tailwindlabs/tailwindcss/discussions/new?category=kind-words 11 | about: "Have something nice to say about @tailwindcss/line-clamp or Tailwind CSS in general? We'd love to hear it!" 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tailwindcss/line-clamp", 3 | "version": "0.4.4", 4 | "main": "src/index.js", 5 | "types": "src/index.d.ts", 6 | "license": "MIT", 7 | "repository": "https://github.com/tailwindlabs/tailwindcss-line-clamp", 8 | "publishConfig": { 9 | "access": "public" 10 | }, 11 | "prettier": { 12 | "printWidth": 100, 13 | "semi": false, 14 | "singleQuote": true, 15 | "trailingComma": "es5" 16 | }, 17 | "scripts": { 18 | "test": "jest" 19 | }, 20 | "devDependencies": { 21 | "jest": "^27.4.4", 22 | "postcss": "^8.2.2", 23 | "prettier": "^2.5.1", 24 | "tailwindcss": "^3.0.23" 25 | }, 26 | "peerDependencies": { 27 | "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1" 28 | }, 29 | "jest": { 30 | "setupFilesAfterEnv": [ 31 | "/jest/customMatchers.js" 32 | ] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const plugin = require('tailwindcss/plugin') 2 | 3 | const baseStyles = { 4 | overflow: 'hidden', 5 | display: '-webkit-box', 6 | '-webkit-box-orient': 'vertical', 7 | } 8 | 9 | const lineClamp = plugin( 10 | function ({ matchUtilities, addUtilities, theme, variants }) { 11 | const values = theme('lineClamp') 12 | 13 | matchUtilities( 14 | { 15 | 'line-clamp': (value) => ({ 16 | ...baseStyles, 17 | '-webkit-line-clamp': `${value}`, 18 | }), 19 | }, 20 | { values } 21 | ) 22 | 23 | addUtilities( 24 | [ 25 | { 26 | '.line-clamp-none': { 27 | '-webkit-line-clamp': 'unset', 28 | }, 29 | }, 30 | ], 31 | variants('lineClamp') 32 | ) 33 | }, 34 | { 35 | theme: { 36 | lineClamp: { 37 | 1: '1', 38 | 2: '2', 39 | 3: '3', 40 | 4: '4', 41 | 5: '5', 42 | 6: '6', 43 | }, 44 | }, 45 | variants: { 46 | lineClamp: ['responsive'], 47 | }, 48 | } 49 | ) 50 | 51 | module.exports = lineClamp 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Tailwind Labs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [master] 9 | pull_request: 10 | branches: [master] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [12, 14, 16] 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Use Node.js ${{ matrix.node-version }} 23 | uses: actions/setup-node@v2 24 | with: 25 | node-version: ${{ matrix.node-version }} 26 | - name: Use cached node_modules 27 | id: cache 28 | uses: actions/cache@v2 29 | with: 30 | path: node_modules 31 | key: nodeModules-${{ hashFiles('**/package-lock.json') }}-${{ matrix.node-version }} 32 | restore-keys: | 33 | nodeModules- 34 | - name: Install dependencies 35 | if: steps.cache.outputs.cache-hit != 'true' 36 | run: npm install 37 | env: 38 | CI: true 39 | - run: npm test 40 | env: 41 | CI: true 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1.bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a bug report for @tailwindcss/line-clamp. 3 | labels: [] 4 | body: 5 | - type: input 6 | attributes: 7 | label: What version of @tailwindcss/line-clamp are you using? 8 | description: 'For example: v0.2.0' 9 | validations: 10 | required: true 11 | - type: input 12 | attributes: 13 | label: What version of Node.js are you using? 14 | description: 'For example: v12.0.0' 15 | validations: 16 | required: true 17 | - type: input 18 | attributes: 19 | label: What browser are you using? 20 | description: 'For example: Chrome, Safari, or N/A' 21 | validations: 22 | required: true 23 | - type: input 24 | attributes: 25 | label: What operating system are you using? 26 | description: 'For example: macOS, Windows' 27 | validations: 28 | required: true 29 | - type: input 30 | attributes: 31 | label: Reproduction repository 32 | description: A public GitHub repo that includes a minimal reproduction of the bug. Unfortunately we can't provide support without a reproduction, and your issue will be closed and locked with no comment if this is not provided. 33 | validations: 34 | required: true 35 | - type: textarea 36 | attributes: 37 | label: Describe your issue 38 | description: Describe the problem you're seeing, any important steps to reproduce and what behavior you expect instead 39 | -------------------------------------------------------------------------------- /.github/workflows/release-insiders.yml: -------------------------------------------------------------------------------- 1 | name: Release Insiders 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | permissions: 8 | contents: read 9 | id-token: write 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | strategy: 16 | matrix: 17 | node-version: [12] 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | 22 | - name: Use Node.js ${{ matrix.node-version }} 23 | uses: actions/setup-node@v2 24 | with: 25 | node-version: ${{ matrix.node-version }} 26 | registry-url: 'https://registry.npmjs.org' 27 | 28 | - name: Use cached node_modules 29 | id: cache 30 | uses: actions/cache@v2 31 | with: 32 | path: node_modules 33 | key: nodeModules-${{ hashFiles('**/package-lock.json') }}-${{ matrix.node-version }} 34 | restore-keys: | 35 | nodeModules- 36 | 37 | - name: Install dependencies 38 | if: steps.cache.outputs.cache-hit != 'true' 39 | run: npm install 40 | env: 41 | CI: true 42 | 43 | - name: Resolve version 44 | id: vars 45 | run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" 46 | 47 | - name: "Version based on commit: 0.0.0-insiders.${{ steps.vars.outputs.sha_short }}" 48 | run: npm version 0.0.0-insiders.${{ steps.vars.outputs.sha_short }} --force --no-git-tag-version 49 | 50 | - name: Publish 51 | run: npm publish --provenance --tag insiders 52 | env: 53 | CI: true 54 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 55 | -------------------------------------------------------------------------------- /src/index.test.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const postcss = require('postcss') 3 | const tailwindcss = require('tailwindcss') 4 | const lineClampPlugin = require('.') 5 | 6 | function run(config, plugin = tailwindcss) { 7 | let { currentTestName } = expect.getState() 8 | config = { 9 | ...{ plugins: [lineClampPlugin], corePlugins: { preflight: false } }, 10 | ...config, 11 | } 12 | 13 | return postcss(plugin(config)).process('@tailwind utilities', { 14 | from: `${path.resolve(__filename)}?test=${currentTestName}`, 15 | }) 16 | } 17 | 18 | it('should add the `line-clamp-{n}` components', () => { 19 | const config = { 20 | content: [ 21 | { 22 | raw: String.raw`
`, 23 | }, 24 | ], 25 | } 26 | 27 | return run(config).then((result) => { 28 | expect(result.css).toMatchCss(String.raw` 29 | .line-clamp-2 { 30 | overflow: hidden; 31 | display: -webkit-box; 32 | -webkit-box-orient: vertical; 33 | -webkit-line-clamp: 2; 34 | } 35 | 36 | .line-clamp-\[33\] { 37 | overflow: hidden; 38 | display: -webkit-box; 39 | -webkit-box-orient: vertical; 40 | -webkit-line-clamp: 33; 41 | } 42 | 43 | .line-clamp-\[var\(--line-clamp-variable\)\] { 44 | overflow: hidden; 45 | display: -webkit-box; 46 | -webkit-box-orient: vertical; 47 | -webkit-line-clamp: var(--line-clamp-variable); 48 | } 49 | `) 50 | }) 51 | }) 52 | 53 | it('should add the `line-clamp-none` utility', () => { 54 | const config = { 55 | content: [{ raw: String.raw`
` }], 56 | } 57 | 58 | return run(config).then((result) => { 59 | expect(result.css).toMatchCss(String.raw` 60 | .line-clamp-none { 61 | -webkit-line-clamp: unset; 62 | } 63 | `) 64 | }) 65 | }) 66 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | - Nothing yet! 11 | 12 | ## [0.4.4] - 2023-03-30 13 | 14 | ### Changed 15 | 16 | - Remove Tailwind CSS v3.3 warning ([#28](https://github.com/tailwindlabs/tailwindcss-line-clamp/pull/28)) 17 | 18 | ## [0.4.3] - 2023-03-30 19 | 20 | ### Changed 21 | 22 | - Warn when used in Tailwind CSS v3.3+ ([#26](https://github.com/tailwindlabs/tailwindcss-line-clamp/pull/26)) 23 | 24 | ## [0.4.2] - 2022-09-02 25 | 26 | ### Fixed 27 | 28 | - Update TypeScript types ([#23](https://github.com/tailwindlabs/tailwindcss-line-clamp/pull/23)) 29 | 30 | ## [0.4.1] - 2022-09-01 31 | 32 | ### Added 33 | 34 | - Add typescript types ([#22](https://github.com/tailwindlabs/tailwindcss-line-clamp/pull/22)) 35 | 36 | ## [0.4.0] - 2022-04-27 37 | 38 | This release of `@tailwindcss/line-clamp` is designed for Tailwind CSS v3.0+, and is not compatible with earlier versions. 39 | 40 | ### Added 41 | 42 | - Add support for arbitrary values ([#10](https://github.com/tailwindlabs/tailwindcss-line-clamp/pull/10)) 43 | 44 | ## [0.3.1] - 2021-12-09 45 | 46 | ### Fixed 47 | 48 | - Add LICENSE file ([#13](https://github.com/tailwindlabs/tailwindcss-line-clamp/pull/13)) 49 | 50 | ### Changed 51 | 52 | - Remove `dist` folder and related dependencies ([#11](https://github.com/tailwindlabs/tailwindcss-line-clamp/pull/11)) 53 | 54 | ## [0.3.0] - 2021-12-09 55 | 56 | ### Added 57 | 58 | - Make sure that Tailwind CSS v3 is in peerDependencies ([c9a9115](https://github.com/tailwindlabs/tailwindcss-line-clamp/commit/c9a9115)) 59 | 60 | ## [0.2.2] - 2021-10-01 61 | 62 | ## Changed 63 | 64 | - Update peer dependencies to support v3 alpha 65 | 66 | ## [0.2.1] - 2021-05-24 67 | 68 | ### Fixed 69 | 70 | - Mark `tailwindcss` as a peer-dependency for monorepo support ([#6](https://github.com/tailwindlabs/tailwindcss-line-clamp/pull/6)) 71 | 72 | ## [0.2.0] - 2021-01-22 73 | 74 | ### Added 75 | 76 | - Allow using numbers instead of strings in your config ([#3](https://github.com/tailwindlabs/tailwindcss-line-clamp/pull/3)) 77 | 78 | ## [0.1.0] - 2021-01-06 79 | 80 | Initial release! 81 | 82 | [unreleased]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.4.4...HEAD 83 | [0.4.4]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.4.3...v0.4.4 84 | [0.4.3]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.4.2...v0.4.3 85 | [0.4.2]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.4.1...v0.4.2 86 | [0.4.1]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.4.0...v0.4.1 87 | [0.4.0]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.3.1...v0.4.0 88 | [0.3.1]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.3.0...v0.3.1 89 | [0.3.0]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.2.1...v0.3.0 90 | [0.2.1]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.2.0...v0.2.1 91 | [0.2.0]: https://github.com/tailwindlabs/tailwindcss-line-clamp/compare/v0.1.0...v0.2.0 92 | [0.1.0]: https://github.com/tailwindlabs/tailwindcss-line-clamp/releases/tag/v0.1.0 93 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!NOTE] 2 | > As of Tailwind CSS v3.3, `line-clamp` utilities are included in the framework by default and this plugin is no longer required. 3 | 4 | # @tailwindcss/line-clamp 5 | 6 | A plugin that provides utilities for visually truncating text after a fixed number of lines. 7 | 8 | ## Installation 9 | 10 | Install the plugin from npm: 11 | 12 | ```sh 13 | npm install -D @tailwindcss/line-clamp 14 | ``` 15 | 16 | Then add the plugin to your `tailwind.config.js` file: 17 | 18 | ```js 19 | // tailwind.config.js 20 | module.exports = { 21 | theme: { 22 | // ... 23 | }, 24 | plugins: [ 25 | require('@tailwindcss/line-clamp'), 26 | // ... 27 | ], 28 | } 29 | ``` 30 | 31 | ## Usage 32 | 33 | Use the `line-clamp-{n}` utilities to specify how many lines of text should be visible before truncating: 34 | 35 | ```html 36 |

37 | Et molestiae hic earum repellat aliquid est doloribus delectus. Enim illum odio porro ut omnis dolor debitis natus. Voluptas possimus deserunt sit delectus est saepe nihil. Qui voluptate possimus et quia. Eligendi voluptas voluptas dolor cum. Rerum est quos quos id ut molestiae fugit. 38 |

39 | ``` 40 | 41 | To remove any line-clamping, use `line-clamp-none`: 42 | 43 | ```html 44 |

45 | Et molestiae hic earum repellat aliquid est doloribus delectus. Enim illum odio porro ut omnis dolor debitis natus. Voluptas possimus deserunt sit delectus est saepe nihil. Qui voluptate possimus et quia. Eligendi voluptas voluptas dolor cum. Rerum est quos quos id ut molestiae fugit. 46 |

47 | ``` 48 | 49 | > Note that the `line-clamp-{n}` set other properties like `display` and `overflow` in addition to `-webkit-line-clamp` which are not unset by `line-clamp-none`, so depending on what you are trying to achieve you may need to explicitly override those properties with utilities like `flex` or `overflow-visible` as well. 50 | 51 | Utilities are for clamping text up to 6 lines are generated by default: 52 | 53 | | Class | CSS | 54 | | --- | --- | 55 | | `line-clamp-1` | `overflow: hidden;`
`display: -webkit-box;`
`-webkit-box-orient: vertical;`
`-webkit-line-clamp: 1;` | 56 | | `line-clamp-2` | `overflow: hidden;`
`display: -webkit-box;`
`-webkit-box-orient: vertical;`
`-webkit-line-clamp: 2;` | 57 | | `line-clamp-3` | `overflow: hidden;`
`display: -webkit-box;`
`-webkit-box-orient: vertical;`
`-webkit-line-clamp: 3;` | 58 | | `line-clamp-4` | `overflow: hidden;`
`display: -webkit-box;`
`-webkit-box-orient: vertical;`
`-webkit-line-clamp: 4;` | 59 | | `line-clamp-5` | `overflow: hidden;`
`display: -webkit-box;`
`-webkit-box-orient: vertical;`
`-webkit-line-clamp: 5;` | 60 | | `line-clamp-6` | `overflow: hidden;`
`display: -webkit-box;`
`-webkit-box-orient: vertical;`
`-webkit-line-clamp: 6;` | 61 | | `line-clamp-none` | `-webkit-line-clamp: unset;` | 62 | 63 | ## Configuration 64 | 65 | You can configure which values and variants are generated by this plugin under the `lineClamp` key in your `tailwind.config.js` file: 66 | 67 | ```js 68 | // tailwind.config.js 69 | module.exports = { 70 | theme: { 71 | extend: { 72 | lineClamp: { 73 | 7: '7', 74 | 8: '8', 75 | 9: '9', 76 | 10: '10', 77 | } 78 | } 79 | }, 80 | variants: { 81 | lineClamp: ['responsive', 'hover'] 82 | } 83 | } 84 | ``` 85 | -------------------------------------------------------------------------------- /jest/customMatchers.js: -------------------------------------------------------------------------------- 1 | const prettier = require('prettier') 2 | const { diff } = require('jest-diff') 3 | 4 | function format(input) { 5 | return prettier.format(input, { 6 | parser: 'css', 7 | printWidth: 100, 8 | }) 9 | } 10 | 11 | expect.extend({ 12 | // Compare two CSS strings with all whitespace removed 13 | // This is probably naive but it's fast and works well enough. 14 | toMatchCss(received, argument) { 15 | function stripped(str) { 16 | return str.replace(/\s/g, '').replace(/;/g, '') 17 | } 18 | 19 | const options = { 20 | comment: 'stripped(received) === stripped(argument)', 21 | isNot: this.isNot, 22 | promise: this.promise, 23 | } 24 | 25 | const pass = stripped(received) === stripped(argument) 26 | 27 | const message = pass 28 | ? () => { 29 | return ( 30 | this.utils.matcherHint('toMatchCss', undefined, undefined, options) + 31 | '\n\n' + 32 | `Expected: not ${this.utils.printExpected(format(received))}\n` + 33 | `Received: ${this.utils.printReceived(format(argument))}` 34 | ) 35 | } 36 | : () => { 37 | const actual = format(received) 38 | const expected = format(argument) 39 | 40 | const diffString = diff(expected, actual, { 41 | expand: this.expand, 42 | }) 43 | 44 | return ( 45 | this.utils.matcherHint('toMatchCss', undefined, undefined, options) + 46 | '\n\n' + 47 | (diffString && diffString.includes('- Expect') 48 | ? `Difference:\n\n${diffString}` 49 | : `Expected: ${this.utils.printExpected(expected)}\n` + 50 | `Received: ${this.utils.printReceived(actual)}`) 51 | ) 52 | } 53 | 54 | return { actual: received, message, pass } 55 | }, 56 | toIncludeCss(received, argument) { 57 | const options = { 58 | comment: 'stripped(received).includes(stripped(argument))', 59 | isNot: this.isNot, 60 | promise: this.promise, 61 | } 62 | 63 | const actual = format(received) 64 | const expected = format(argument) 65 | 66 | const pass = actual.includes(expected) 67 | 68 | const message = pass 69 | ? () => { 70 | return ( 71 | this.utils.matcherHint('toIncludeCss', undefined, undefined, options) + 72 | '\n\n' + 73 | `Expected: not ${this.utils.printExpected(format(received))}\n` + 74 | `Received: ${this.utils.printReceived(format(argument))}` 75 | ) 76 | } 77 | : () => { 78 | const diffString = diff(expected, actual, { 79 | expand: this.expand, 80 | }) 81 | 82 | return ( 83 | this.utils.matcherHint('toIncludeCss', undefined, undefined, options) + 84 | '\n\n' + 85 | (diffString && diffString.includes('- Expect') 86 | ? `Difference:\n\n${diffString}` 87 | : `Expected: ${this.utils.printExpected(expected)}\n` + 88 | `Received: ${this.utils.printReceived(actual)}`) 89 | ) 90 | } 91 | 92 | return { actual: received, message, pass } 93 | }, 94 | }) 95 | 96 | expect.extend({ 97 | // Compare two CSS strings with all whitespace removed 98 | // This is probably naive but it's fast and works well enough. 99 | toMatchFormattedCss(received, argument) { 100 | function format(input) { 101 | return prettier.format(input.replace(/\n/g, ''), { 102 | parser: 'css', 103 | printWidth: 100, 104 | }) 105 | } 106 | const options = { 107 | comment: 'stripped(received) === stripped(argument)', 108 | isNot: this.isNot, 109 | promise: this.promise, 110 | } 111 | 112 | let formattedReceived = format(received) 113 | let formattedArgument = format(argument) 114 | 115 | const pass = formattedReceived === formattedArgument 116 | 117 | const message = pass 118 | ? () => { 119 | return ( 120 | this.utils.matcherHint('toMatchCss', undefined, undefined, options) + 121 | '\n\n' + 122 | `Expected: not ${this.utils.printExpected(formattedReceived)}\n` + 123 | `Received: ${this.utils.printReceived(formattedArgument)}` 124 | ) 125 | } 126 | : () => { 127 | const actual = formattedReceived 128 | const expected = formattedArgument 129 | 130 | const diffString = diff(expected, actual, { 131 | expand: this.expand, 132 | }) 133 | 134 | return ( 135 | this.utils.matcherHint('toMatchCss', undefined, undefined, options) + 136 | '\n\n' + 137 | (diffString && diffString.includes('- Expect') 138 | ? `Difference:\n\n${diffString}` 139 | : `Expected: ${this.utils.printExpected(expected)}\n` + 140 | `Received: ${this.utils.printReceived(actual)}`) 141 | ) 142 | } 143 | 144 | return { actual: received, message, pass } 145 | }, 146 | }) 147 | --------------------------------------------------------------------------------