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

CSS intellisense not working #118

Open
sarifmia opened this issue Sep 22, 2019 · 20 comments
Open

CSS intellisense not working #118

sarifmia opened this issue Sep 22, 2019 · 20 comments
Labels

Comments

@sarifmia
Copy link

Is there anyway we can make css intellisense working inside EStyleSheet.create for vscode.

@stale
Copy link

stale bot commented Nov 21, 2019

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the wontfix label Nov 21, 2019
@yvbeek
Copy link

yvbeek commented Nov 25, 2019

If you are using TypeScript, you can do the following:

[see my latest post in this thread]

That should give you code completion on the styles.

You won't be able to use everything though. See this file for more information:
https://github.com/vitalets/react-native-extended-stylesheet/blob/master/types/index.d.ts

@stale stale bot removed the wontfix label Nov 25, 2019
@yvbeek
Copy link

yvbeek commented Dec 6, 2019

TypeScript is kinda amazing. I've played around with it a bit more and I came up with this. It should give you proper intellisense / autocomplete:

[see my latest post in this thread]

@vitalets Would this be something that you can use in the .d.ts?

The interesting line is type EComponentStyle = .... That merges the regular styles definition with a copy of the style definition that allows the value of every style item to be of type string.

@yvbeek
Copy link

yvbeek commented Dec 11, 2019

The solution above would have some problems if you are trying to set the textShadowOffset.

This one should allow any value, but still give you code completion:

[see my latest post in this thread]

I can improve this a bit more if I find a way to actually merge types (which is different from using the | union operator).

@stale
Copy link

stale bot commented Feb 9, 2020

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the wontfix label Feb 9, 2020
@AAAstorga
Copy link

@yvbeek Is there a way to support media query on the style level?

text: {
    fontSize: '$fontSize',
    '@media ios': { // media query on style level
      color: 'green',
    },
    '@media android': {
      color: 'blue',
    },
  },

@stale stale bot removed the wontfix label Feb 11, 2020
@yvbeek
Copy link

yvbeek commented Mar 14, 2020

Getting closer to a fully working definition:

[see my latest post in this thread]

@AAAstorga
With this one media queries should work

@vitalets
Last piece of the puzzle would be to fix the return type. I've tried to make the function generic, but as soon as I do that, autocomplete stops working.

@yvbeek
Copy link

yvbeek commented Mar 14, 2020

The return type of this one is a bit smarter:

[see my latest post in this thread]

@nexorianus
Copy link

@yvbeek did you get back full EStyleSheet IntelliSense with your types?
And if yes, where did you put it to be recognized?

@yvbeek
Copy link

yvbeek commented May 5, 2020

@nexorianus I revisited the styles today and this is the best I could come up with so far:

import { ImageStyle, TextStyle, ViewStyle } from "react-native"
import EStyleSheet from "react-native-extended-stylesheet"

type Function<K> = () => K
type Value<T> = T | string & {}
type Variable<T> = Value<T> | Function<Value<T>>
type Extended<T> = { [K in keyof T]: Variable<T[K]> }

type AnyStyle = ImageStyle & TextStyle & ViewStyle
type AnyStyleSet = { [key: string]: AnyStyle }

type EStyleSet<T = any> = { [K in keyof T]:
  T[K] extends Variable<number> ? T[K] :
  T[K] extends MediaQuery ? T[K] :
  Extended<AnyStyle>
}

type StyleSet<T = any> = { [K in keyof T]:
  T[K] extends number ? T[K] :
  T[K] extends string ? T[K] :
  T[K] extends Function<number> ? number :
  T[K] extends Function<string> ? string :
  T[K] extends MediaQuery ? AnyStyleSet :
  AnyStyle
}

export type MediaQuery = { [key: string]: Extended<AnyStyle> }

export const createStyles = <T = EStyleSet>(styles: EStyleSet<T>) => EStyleSheet.create(styles) as StyleSet<T>
export const styleValue = (key: string, prop?: string) => EStyleSheet.value(key, prop)

In my project, this code lives in a file: styles/index.ts
This is how I use it:

import { createStyles } from "styles"

...
const styles = createStyles({
  container: {
    backgroundColor: "#fff",
    borderRadius: 4,
    flexDirection: "row",
    alignItems: "center",
    paddingLeft: "$gapSM",
    zIndex: 1
  },
  searchIcon: {
    color: "$placeholderColor",
    fontSize: "$fontSizeMD",
    marginRight: "$gapSM",
  },
  clearIcon: {
    color: "$placeholderColor",
    fontSize: "$fontSizeMD",
    marginHorizontal: "$gapSM",
    marginTop: "$gapXS"
  },
  placeholderText: {
    color: "$placeholderColor"
  },

  // For testing
  varColor: "rgba(255, 255, 255, 0.05)",
  varNumberFn: () => 10,
  varStringFn: () => "#fff",
  "@media ios": {
    header: { flex: 1 }
  } as MediaQuery
})

Updated - 2020/05/05 - 7:48pm

  • provides code completion when you create styles
  • provides code completion when you use styles
  • supports variables and functions
  • supports media queries (requires as MediaQuery, semi-completion)

Any feedback / suggestions / improvements are welcome!

@nexorianus
Copy link

This solution works like a charm.
Could you open a PR for this, so @vitalets can pull it to the repo?

@yvbeek
Copy link

yvbeek commented May 16, 2020

@nexorianus I've created the PR. It probably won't be merged because it would break existing code. But for most people this should provide some decent autocomplete.

Please try out my fork:

package.json:

"react-native-extended-stylesheet": "yvbeek/react-native-extended-stylesheet"

@stale
Copy link

stale bot commented Jul 18, 2020

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the wontfix label Jul 18, 2020
@stale stale bot closed this as completed Jul 25, 2020
@yfunk
Copy link

yfunk commented Oct 28, 2020

@yvbeek Thanks for your work on improving the type definitions, it makes working with this package and TypeScript much more pleasant. I wanted to let you know that the mentioned key augmentation feature has been implemented in the TypeScript 4.1 Beta, maybe that is something that could help with further improvements.

@ahmedam55
Copy link

Thanks a lot for your hard work, @yvbeek!

Thanks to you I have very decent CSS auto completion and solid "go to definition" functionality.

@ucheNkadiCode
Copy link

Thank you so much @yvbeek This is a fantastic wrapper that was so easy to implement! Amazing!

@Sir-Dazzling
Copy link

Thank you @yvbeek this helped me a lot

@reichhartd
Copy link

For those interested, we have a fork of react-native-extended-stylesheet that includes CSS IntelliSense support. While our fork is no longer actively maintained, it might be useful as a reference for implementing similar functionality.

Check it out here: tokenstreet/react-native-extended-stylesheet

Keep in mind that since the fork isn't actively supported, it should primarily serve as a resource or for those who need IntelliSense in their projects.

@yvbeek
Copy link

yvbeek commented Nov 25, 2024

@reichhartd Thank you for mentioning the fork.

For our project we are in the process of moving over to React-Native Unistyles:

I really appreciate all of the work that has been done on react-native-extended-stylesheet. It has worked well in our app for many years.

@gf-studios
Copy link

gf-studios commented Nov 27, 2024

I know I'm a bit late to the party but I just thought I would post this for anyone looking for it:

when you import EStylesheet from 'react-native-extended-stylesheet', in VS code you can hold control and click on your import EStylesheet.

You'll be taken to a file called index.d.ts. It's a relatively small file, and you'll see the following

type AnyObject = {[key: string]: any};`
type Event = 'build';
export function create(styles: AnyObject): AnyObject;

This is where the issue is, the object that EStylesheet.create() returns is typed to any, which turns off typescript. Here's how i fixed it.

So you have react native's original ViewStyle and TextStyle types that you can import, but you don't want to use this because then it just becomes a regular StyleSheet which defeats the purpose, so i made my own types:

import {StyleSheet, TextStyle, ViewStyle} from 'react-native';


type ViewEStyle = {[K in keyof ViewStyle]: string | number}` 

type TextEStyle = {[K in keyof TextStyle]: string | number}`

declare namespace EStyleSheet {
type AnyObject = {[key: string]: ViewEStyle | TextEStyle | number | string};
...
}

What K in keyof ViewStyle does is grab all the properties available in ViewStyle (backgroundColor, borderRadius, etc) and makes it available in the new type, but instead of restricting it to specific values, you can now put any string or number as a value (e.g padding: '3rem'). Also, extended stylesheet allows you to make local variables ($text-color: #fff), which is why i typed the AnyObject as number and string also.

Lastly, typescript will give you an error if you try to use this on the style prop, because its incompatible with what EStylesheet provides, probably why it was typed to any in the first place, so you have to declare your styles object as type any.

const styles = EStylesheet.create({
 ...
 ...
 ... 
}) as any;

Now when you create an object inside it will autocomplete the styles.

Here's the whole index.d.ts incase you want to copy and paste

import {StyleSheet, TextStyle, ViewStyle} from 'react-native';

export = EStyleSheet;

type ViewEStyle = {[K in keyof ViewStyle]: string | number} 

type TextEStyle = {[K in keyof TextStyle]: string | number}

declare namespace EStyleSheet {
    type AnyObject = {[key: string]: ViewEStyle | TextEStyle | number | string};
    type Event = 'build';

    export function create(styles: AnyObject): AnyObject;
    export function build(rawGlobalVars?: AnyObject): void;
    export function value(expr: any, prop?: string): any;
    export function child(styles: AnyObject, styleName: string, index: number, count: number): AnyObject;
    export function subscribe(event: Event, listener: () => any): void;
    export function clearCache(): void;

    // inherited from StyleSheet
    export const flatten: typeof StyleSheet.flatten;
    export const setStyleAttributePreprocessor: typeof StyleSheet.setStyleAttributePreprocessor;
    export const hairlineWidth: typeof StyleSheet.hairlineWidth;
    export const absoluteFillObject: typeof StyleSheet.absoluteFillObject;
    export const absoluteFill: typeof StyleSheet.absoluteFill;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests