Skip to content

Auto-generate stable class variants from source styles #24

@morganney

Description

@morganney

Auto-generate stable class variants from source styles

Problem

Currently, users must manually opt into stable selectors:

Sass:

.icon {
  @include knighted.stable('icon') { /* ... */ }
}

Less:

.icon {
  .stable(icon, { /* ... */ });
}

For large stylesheets or migrations, this can be tedious and error-prone.


Proposal

Add an optional mode where @knighted/css (loader or PostCSS plugin) can automatically emit stable variants for all selectors in a given file.

Use cases:

  • Large stylesheets where manually wrapping every class is tedious.
  • Migrating existing styles to support shadow DOM without refactoring every rule.
  • Design systems that want stable classes for all components by default.

Possible API

Via loader option:

{
  loader: '@knighted/css/loader',
  options: {
    autoStable: true, // or { namespace: 'myapp', include: /^\.icon/ }
  }
}

Via file-level pragma:

/* @knighted-auto-stable */

.icon { /* ... */ }
.button { /* ... */ }

Loader would transform this to:

.icon,
.knighted-icon { /* ... */ }

.button,
.knighted-button { /* ... */ }

Implementation notes

  • Could be a PostCSS plugin (postcss-knighted-stable) that runs after Sass/Less compilation.
  • Would need heuristics to:
    • Only duplicate class selectors (not IDs, attributes, pseudo-classes in isolation).
    • Optionally support a filter (e.g., only classes matching a pattern).
  • Should play nicely with existing manual @include knighted.stable() (don't double-emit).
  • Needs to handle nested selectors gracefully (e.g., .parent .child).

Open questions

  • Should this be opt-in per file, per directory, or globally?
  • How to handle nested selectors (e.g., .parent .child)?
    • Generate .knighted-parent .child?
    • Generate .knighted-parent .knighted-child?
    • Only top-level classes?
  • Should it support other selector types (IDs, attributes)?
  • How to avoid conflicts with existing manual stable class usage?

Benefits

  • Reduces manual work for large codebases.
  • Makes adoption easier for teams migrating to shadow DOM.
  • Provides a clear path from "no stable classes" to "all stable" without big refactors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions