Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern based imports (* as ns-*) #2123

Open
tomrav opened this issue Oct 28, 2021 · 0 comments
Open

Pattern based imports (* as ns-*) #2123

tomrav opened this issue Oct 28, 2021 · 0 comments
Assignees
Labels
core Processing and transforming logic feature New syntax feature or behavior

Comments

@tomrav
Copy link
Collaborator

tomrav commented Oct 28, 2021

Why?

Several users have encountered cases (mostly in larger projects) where multiple (10+) symbols are imported from a specific stylesheet (e.g. project.st.css). This requires specifying each of the imported symbols, one by one, and this can get repetitive.

Related issues

Not exactly about this, but in a similar domain.

Feature suggestion

Introduce pattern based imports to allow a single import statement to provide multiple symbols under a single namespace.
This is similar in concept to JS's import * as X from './x'; with slight changes to the syntax.

CSS vars grouping

Example:

/* button.st.css */
.root {
    --bg-primary: red;
    --bg-secondary: purple;
}
/* app.st.css */
@st-import [--* as --Btn-*] from './button.st.css';

.root {
    --bg: var(--Btn-bg-primary); /* local var defined using imported value */
    
    --Btn-bg-secondary: green; /* override imported variable, using its namespace */

    --Btn-x: ...; /* will warn about unknown variable from scope Btn */
}

The example above shows how to import every CSS variable from the button.st.css stylesheet. You can then override them or use them as values.
The --Btn-* namespace will be considered as belonging to the a different context, and all resolutions will be made according to its scope.
Above, the --Btn-x use case demonstrates such a resolution failing and issuing a warning.

This example shows all variables being imported, but one could create a more narrow import by using a more specific template:

/* app.st.css */
@st-import [--bg-* as --Btn-bg-*] from './button.st.css';

.root {
    background: var(--Btn-bg-primary); /* var available */

    font: var(--Btn-bg-unknown); /* will warn about var not existing in imported scope */
}

Thinking beyond vars

While most user requests so far have focused primarily on CSS variables, other Stylable symbols might benefit from a similar approach.

/* button.st.css */
:vars {
    myFont: monospace;
}

.root {
    --bg: red;
    --c1: cyan;
}

.label {}
/* app.st.css */
@st-import [* as Btn-*] from './button.st.css';

.root {
    font: value(Btn-myFont); /* imported variable */
}

.local {} /* class belonging to this app stylesheet */

.Btn-label {} /* class belonging to the button.st.css stylesheet */

In this case, the * as Btn-* syntax imports all available symbols from the button.st.css stylesheet

  • Classes - in selectors used with a .Btn-label prefix, in directives used as a symbol name
  • Stylable vars - used with the value(Btn-myFont) function
  • CSS vars - this syntax could also expose the CSS variables, to avoid needing both * as Btn-* and --* as --Btn-* in the same import. These vars would be used by adding the required -- prefix, e.g. --Btn-bg.
  • Keyframes - exist within a separate namespace in each stylesheet to avoid colliding with classes or variables. So keyframes should probably not be exposed by this * import. To balance this out, we can consider a keyframes(* as Btn-*) like syntax. Alternatively, we can consider deciding that * should work even for keyframes, and perform transformations/validations based on the node type in which they are used.

Regardless, this can perform the same validations as shown in the suggestion for CSS vars above, so symbols are not used without assurance that they exist in the desired context.

Additional considerations

  • It could be argued that this feature becomes more helpful mostly due to the state of our language service, with completions and code actions (e.g. add import, rename symbol) being a lacking experience
  • I feel like there's a balance between speed and visible intent in this feature
    • individual specific imports make tracking usage and signifying intent easier
    • grouped imports yield smaller source files (target code is identical), but usage is harder to determine in a quick
  • If a pattern is used, do all matching symbols "pour" through the import, or only specific ones in use?
  • how are re-exports handled for each symbol type?
@tomrav tomrav added feature New syntax feature or behavior core Processing and transforming logic labels Oct 28, 2021
@tomrav tomrav self-assigned this Oct 28, 2021
@tomrav tomrav changed the title Feature suggestion: grouped pattern based imports Pattern based imports Oct 28, 2021
@tomrav tomrav changed the title Pattern based imports Pattern based imports (* as ns-*) Oct 28, 2021
@tomrav tomrav added this to Stylable Dec 14, 2021
@tomrav tomrav moved this to Awaiting Review in Stylable Dec 14, 2021
@tomrav tomrav assigned tomrav and unassigned tomrav Dec 14, 2021
@tomrav tomrav moved this to Paused in Stylable Dec 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Processing and transforming logic feature New syntax feature or behavior
Projects
Status: ⏸️ Paused
Development

No branches or pull requests

1 participant