prettier-plugin-svelte icon indicating copy to clipboard operation
prettier-plugin-svelte copied to clipboard

A <textarea> can have either a value attribute or (equivalently) child content, but not boths

Open applemate opened this issue 1 year ago • 3 comments

I got this error, how can I disable it ?

CleanShot 2024-08-29 at 00 47 29 CleanShot 2024-08-29 at 00 47 39

and this is my prettierrc

{
	"useTabs": true,
	"singleQuote": true,
	"semi": false,
	"printWidth": 70,
	"bracketSameLine": true,
	"htmlWhitespaceSensitivity": "ignore",
	"plugins": [
		"prettier-plugin-svelte",
		"prettier-plugin-tailwindcss"
	],
	"overrides": [
		{
			"files": "*.svelte",
			"options": { "parser": "svelte" }
		}
	]
}

applemate avatar Aug 28 '24 17:08 applemate

Please provide a code snippet and/or reproduction link (Stackblitz or GitHub). Just from looking at the screenshot there's not much we can tell

dummdidumm avatar Aug 29 '24 07:08 dummdidumm

the code snippet

<textarea
	on:keydown={onKeyDown}
	placeholder="put a bunch of series here"
	bind:value={text}>
</textarea>

package json

"devDependencies": {
		"@silintl/svelte-google-places-autocomplete": "^1.2.5",
		"@sveltejs/adapter-auto": "^3.2.3",
		"@sveltejs/adapter-node": "^5.2.1",
		"@sveltejs/kit": "^2.5.21",
		"@sveltejs/vite-plugin-svelte": "^3.1.1",
		"@types/bun": "^1.1.6",
		"@types/js-cookie": "^3.0.6",
		"@types/store": "^2.0.5",
		"@typescript-eslint/eslint-plugin": "^8.0.1",
		"@typescript-eslint/parser": "^8.0.1",
		"autoprefixer": "^10.4.20",
		"cheerio": "^1.0.0-rc.12",
		"cross-blob": "^3.0.2",
		"eslint": "^9.9.0",
		"eslint-config-prettier": "^9.1.0",
		"eslint-plugin-svelte": "^2.43.0",
		"fzf": "^0.5.2",
		"js-cookie": "^3.0.5",
		"moment": "^2.30.1",
		"moment-timezone": "^0.5.45",
		"nprogress": "^0.2.0",
		"postcss": "^8.4.41",
		"prettier": "^3.3.3",
		"prettier-plugin-svelte": "^3.2.6",
		"prisma": "5.18.0",
		"sass": "^1.77.8",
		"socket.io-client": "^4.7.5",
		"store": "^2.0.12",
		"svelte-autosize": "^1.1.0",
		"svelte-check": "^3.8.5",
		"svelte-dnd-action": "^0.9.49",
		"svelte-file-dropzone": "^2.0.7",
		"tailwindcss": "^3.4.9",
		"tslib": "^2.6.3",
		"typescript": "^5.5.4",
		"uniqid": "^5.4.0",
		"vite": "^5.4.0",
		"vitest": "^2.0.5"
	},
	"dependencies": {
		"@prisma/client": "5.18.0",
		"@svelte-plugins/tooltips": "^3.0.1",
		"@tailwindcss/aspect-ratio": "^0.4.2",
		"@tailwindcss/forms": "^0.5.7",
		"@tailwindcss/line-clamp": "^0.4.4",
		"@types/lodash-es": "^4.17.12",
		"@types/valid-url": "^1.0.7",
		"@zerodevx/svelte-toast": "^0.9.5",
		"basic-ftp": "^5.0.5",
		"caniuse-lite": "^1.0.30001651",
		"component-emitter": "^2.0.0",
		"fontsome": "^1.0.5",
		"fuse.js": "^7.0.0",
		"googleapis": "^140.0.1",
		"knex": "^3.1.0",
		"lodash-es": "^4.17.21",
		"mysql": "^2.18.1",
		"mysql2": "^3.11.0",
		"nodemailer": "^6.9.14",
		"nodemailer-express-handlebars": "^6.1.2",
		"path": "^0.12.7",
		"pg": "^8.12.0",
		"prettier-plugin-tailwindcss": "^0.6.6",
		"sharp": "^0.33.4",
		"svelte": "^4.2.18",
		"svelte-adapter-bun": "^0.5.2",
		"svelte-flag-icons": "^1.0.3",
		"svelte-select": "^5.8.3",
		"sveltekit-barcode": "^2.0.8",
		"valid-url": "^1.0.9"
	}

prettierrc

{
	"useTabs": true,
	"singleQuote": true,
	"semi": false,
	"printWidth": 70,
	"bracketSameLine": true,
	"htmlWhitespaceSensitivity": "ignore",
	"plugins": [
		"prettier-plugin-svelte",
		"prettier-plugin-tailwindcss"
	],
	"overrides": [
		{
			"files": "*.svelte",
			"options": { "parser": "svelte" }
		}
	]
}

viteconfig


import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig } from 'vitest/config'

export default defineConfig({
	plugins: [sveltekit()],
	test: {
		include: ['src/**/*.{test,spec}.{js,ts}']
	}
})

svelte config

import adapter from 'svelte-adapter-bun'
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

/** @type {import('@sveltejs/kit').Config} */
const config = {
	preprocess: vitePreprocess(),
	onwarn: (warning, handler) => {
		if (warning.code.startsWith('a11y-')) {
			return
		}
		if (warning.code.startsWith('css-unused-selector')) {
			return
		}
		handler(warning)
	},
	kit: {
		adapter: adapter(),
	},
}

export default config

eslintrc.js

module.exports = {
	root: true,
	extends: [
		'eslint:recommended',
		'plugin:@typescript-eslint/recommended',
		'plugin:svelte/recommended',
		'prettier',
	],
	parser: '@typescript-eslint/parser',
	plugins: ['@typescript-eslint'],
	parserOptions: {
		sourceType: 'module',
		ecmaVersion: 2020,
		extraFileExtensions: ['.svelte'],
	},
	env: {
		browser: true,
		es2017: true,
		node: true,
	},
	overrides: [
		{
			files: ['*.svelte'],
			parser: 'svelte-eslint-parser',
			parserOptions: {
				parser: '@typescript-eslint/parser',
			},
		},
	],
	ignorePatterns: ['*.cjs'],
	rules: {
		'svelte/no-at-html-tags': 0,
		'svelte/valid-compile': ['error', { ignoreWarnings: true }],
		'@typescript-eslint/ban-ts-comment': 0,
		'@typescript-eslint/no-inferrable-types': 0,
		'a11y-no-static-element-interactions': 0,
		'no-var': 0,
		'prefer-const': 0,
		'@typescript-eslint/no-explicit-any': 0,
		'@typescript-eslint/no-unused-vars': 0,
		'@typescript-eslint/no-empty-function': 0,
		'a11y-label-has-associated-control': 0,
		'a11y-missing-attribute': 0,
		'a11y-click-events-have-key-events': 0,
		'no-constant-condition': 0,
		'no-prototype-builtins': 0,
		'a11y-autocomplete-valid': 0,
		'no-empty': 0,
	},
}

applemate avatar Aug 29 '24 07:08 applemate

This is a combination of your whitespaceSensitivity: "none" setting in your prettier config and the fact that whitespace inside textarea is important. Our Prettier plugin therefore formats the textarea closing block into a separate line. That does not work because whitespace is actually important within textareas - well, almost, except for the first line, which is ignored.

I think the best fix would be to handle this special case within the Svelte parser and not error in this case. Given that this is such an edge case, we're likely only going to fix this in Svelte 5. You can easily work around it by adding a <!-- prettier-ignore --> comment at the top of your textarea element and make sure there's no space between the opening and closing tag:

<!-- prettier-ignore -->
<textarea
	on:keydown={onKeyDown}
	placeholder="put a bunch of series here"
	bind:value={text}
></textarea>

I'm also wondering if we should align our formatting with that of Prettier's HTML formatting, i.e. don't force an empty line in this case, instead format it like in the code snippet above.

dummdidumm avatar Aug 29 '24 07:08 dummdidumm