Review VS Code Intellisense auto-complete for Tailwind classes
Describe the feature in detail (code, mocks, or screenshots encouraged)
In versions prior to Skeleton v3 we implemented a build-time process that would scan all components and generate a unique list of props that utilize the special CssClass type. This class simply represented a string, but by doing this we could generate a JSON file like this:
https://raw.githubusercontent.com/skeletonlabs/skeleton/master/packages/skeleton/scripts/tw-settings.json
This was then used as part of the Skeleton CSA (aka v2 CLI) to insert this file into user's Skeleton project. This would live here:
./.vscode/settings.json
By doing this, VS Code can identify all Skeleton props that should take CSS classes, allowing for Intellisense auto-complete.
Goal
In v3 we should try to find a way to generate similar JSON files for each component framework - since prop names can differ. Then providing a manual (but optional) onboarding step for users that wish to install this in their project and gain this functionality. Perhaps look at if similar functionality is available for other popular editors as well.
Then long term, we should revisit moving this to a dedicated Skeleton VS Code extension so users no longer have to manage this on their own.
NOTE: The CSA approach will never be possible again as we will never build tooling for scaffolding user apps again. It's just not possible when supporting multiple frameworks and meta-framework combinations.
What type of pull request would this be?
New Feature
Provide relevant links or additional information.
No response
Until an automatic version is found - Here is a manual one that covers the current development state:
"tailwindCSS.classAttributes": [
"class",
// Base
"base",
"padding",
"border",
"background",
"spaceY",
"rounded",
"width",
"widthExpanded",
"height",
"size",
"font",
"shadow",
"style",
"hover",
"active",
"flexDirection",
"classes",
// Fallback
"fallbackBase",
"fallbackClasses",
// Image
"imageBase",
"imageClasses",
// Control
"controlBase",
"controlGap",
"controlHover",
"controlInactive",
"controlActive",
"controlDisabled",
"controlWidth",
"controlHeight",
"controlPadding",
"controlRounded",
"controlHover",
"controlClasses",
// Lead
"leadBase",
"leadSpaceX",
"leadPadding",
"leadClasses",
// Center
"centerBase",
"centerAlign",
"centerPadding",
"centerClasses",
// Content
"contentBase",
"contentBackground",
"contentClasses",
// Indicator
"indicatorBase",
"indicatorBg",
"indicatorText",
"indicatorRounded",
"indicatorClasses",
// Panel
"panelBase",
"panelPadding",
"panelRounded",
"panelClasses",
// Toolbar
"toolbarBase",
"toolbarGridCols",
"toolbarGap",
"toolbarClasses",
// Trail
"trailBase",
"trailSpaceX",
"trailPadding",
"trailClasses",
// Headline
"headlineBase",
"headlineClasses",
// Interface
"interfaceBase",
"interfaceBg",
"interfaceBorder",
"interfaceBorderColor",
"interfacePadding",
"interfaceRounded",
"interfaceIcon",
"interfaceText",
"interfaceSubtext",
"interfaceClasses",
// FilesList
"filesListBase",
"filesListClasses",
// File
"fileBase",
"fileBg",
"fileGap",
"filePadding",
"fileRounded",
"fileIcon",
"fileName",
"fileSize",
"fileButton",
"fileClasses",
// State
"stateInfo",
"stateError",
"stateSuccess",
"stateActive",
"stateInactive",
"stateDisabled",
"stateInteractive",
"stateReadOnly",
"stateInvalid",
"stateFocused",
"stateDragging",
// StateLabel
"stateLabelInactive",
"stateLabelActive",
// Tiles
"tilesBase",
"tilesFlexDirection",
"tilesJustify",
"tilesItems",
"tilesGap",
"tilesClasses",
// Header
"headerBase",
"headerFlexDirection",
"headerJustify",
"headerItems",
"headerGap",
"headerClasses",
// Footer
"footerBase",
"footerFlexDirection",
"footerJustify",
"footerItems",
"footerGap",
"footerClasses",
// Expanded
"expandedPadding",
"expandedGap",
"expandedClasses",
// Label
"labelBase",
"labelText",
"labelFill",
"labelFontSize",
"labelFontWeight",
"labelClasses",
"labelExpandedBase",
"labelExpandedClasses",
// Button
"buttonBase",
"buttonActive",
"buttonInactive",
"buttonHover",
"buttonClasses",
// Track
"trackBase",
"trackStroke",
"trackBg",
"trackRounded",
"trackClasses",
// Meter
"meterBase",
"meterStroke",
"meterBg",
"meterRounded",
"meterTransition",
"meterAnimate",
"meterDuration",
"meterClasses",
// Children
"childrenBase",
"childrenClasses",
// SVG
"svgBase",
"svgClasses",
// Item
"itemBase",
"itemClasses",
// Orient
"orientVertical",
"orientHorizontal",
// Thumb
"thumbBase",
"thumbSize",
"thumbBg",
"thumbRingSize",
"thumbRingColor",
"thumbRounded",
"thumbCursor",
"thumbInactive",
"thumbActive",
"thumbTranslateX",
"thumbTransition",
"thumbEase",
"thumbDuration",
"thumbClasses",
// Markers
"markersBase",
"markersClasses",
// Mark
"markBase",
"markText",
"markOpacity",
"markClasses",
// Icon
"iconInactiveBase",
"iconActiveBase",
// List
"listBase",
"listJustify",
"listBorder",
"listMargin",
"listGap",
"listClasses",
// TagList
"tagListBase",
"tagListClasses",
// Tag
"tagBase",
"tagBackground",
"tagClasses",
// InputEdit
"inputEditBase",
// TagEdit
"tagEditBase",
"tagEditBackground",
// InputEdit
"inputEditClasses",
// ButtonDelete
"buttonDeleteBase",
"buttonDeleteClasses",
// Trigger
"triggerBase",
"triggerBackground",
"triggerClasses",
// Positioner
"positionerBase",
"positionerClasses",
// Arrow
"arrowBase",
"arrowBackground",
"arrowClasses",
// Group
"groupBase",
"groupZIndex",
"groupGap",
"groupClasses",
// Toast
"toastBase",
"toastPadding",
"toastGap",
"toastShadow",
"toastClasses",
// Message
"messageBase",
"messageTitle",
"messageDescription",
"messageClasses",
// btnDismiss
"btnDismissBase",
"btnDimissPreset",
"btnDismissHover",
"btnDismissClasses",
// Backdrop
"backdropClasses",
// ZIndex
"zIndex"
]
Hey, I'm interested in working on this. We chatted in Discord, but I'll repeat myself a bit so the conversation is followable here.
I've implemented a script that extracts the CSS class props from Skeleton, so they can be fed into VSCode's tailwindCSS.classAttributes setting or prettier-plugin-tailwind's tailwindAttributes setting.
https://gist.github.com/oatmealproblem/3792d16e52c8b95db86cf81efdffcb52
I implemented that as a 3rd party script that works with the current Skeleton dist. It has some limitations, notably it's a bit "fuzzy" in finding the CSS class props:
- it finds exported interfaces with names ending in
Props - within those interfaces, it finds optional string props whose attached JSDoc comment includes the text "class", "css", or "style"
For a first party solution, that "fuzziness" can be avoided. You mention that Skeleton v2 used a custom CssClass type for this (simple an alias of string?). Is that the approach we'd like to use for v3 as well, or were there downsides to that?
Alternatives:
- use a custom jsdoc tag (eg
@css-class-prop) - more sophisticated AST analysis, that actually tracks which props end up being passed into a class / className
- IMO more complicated that its worth, and would require special logic for each additional framework
- stick with fuzzy matching for the initial implementation
Just FYI @oatmealproblem we've had some developments over the weekend that might make this feature less critical in the future. I'll be sharing details on this soon - likely this upcoming week. In fact, maybe let me get that sorted first and then we'll decide if we think this feature is worth the effort.
Sorry to be stop-and-go here, but your time is valuable, so just want to make sure we're confident that we'll utilize this for a while before we go ahead with it.
No worries! I look forward to the news :)
@Hugos68 is there anything else we need for this to work in Skeleton v4, or are we good to go? Now that we've slimmed down to the universal class attribute this should be much more straight forward. If all is well let's close this one out.
The v4 RC announcement is here for anyone curious: https://github.com/skeletonlabs/skeleton/discussions/3844