Giter Club home page Giter Club logo

Comments (22)

cmaycumber avatar cmaycumber commented on June 17, 2024 1

I agree. I just didn't know if they mapped one-to-one or not. Sounds good hopefully, RNW supports the web box-shadows as well.

from dripsy.

nandorojo avatar nandorojo commented on June 17, 2024 1

So far, I've been using the normal React Native shadow properties without much of an issue. That said, I don't have many shadows in my current app, so maybe I'm behind on something.

This issue was actually intended to solve the fact that the sx prop's TS types don't expect values like shadowOffset, etc. that come from RN styles. Functionally speaking, the RNW shadows have been fine in my experience. Have they not for you @daxfrost ?

If RNW's shadows are insufficient for you, could you try something like this?

import React from 'react'
import { View } from 'dripsy'
import { Platform } from 'react-native'

const WithShadow = () => (
  <View
    sx={{
      ...Platform.select({
        // these are just random shadow values to illustrate
        web: {
          boxShadow: '3px 3px 5px #ccc, 1'
        },
        default: {
          shadowColor: '#000',
          shadowOffset: {
            width: 0,
            height: 2
          },
          shadowOpacity: 0.25,
          shadowRadius: 3.84,
          elevation: 5
        }
      })
    }}
  />
)

However, given that the React Native Web philosophy is quite strict on not using CSS values, I don't recommend this usage. RNW doesn't even support the className prop anymore, so I wouldn't feel safe using boxShadow directly to style it, as it might become a no-op in the future.

In general, you should aim for platform-agnostic styles. But when you can't, I think it should be up to the developer, not this library, to decide when.

I also find this tool by @EvanBacon useful for creating React Native shadows that are web-compatible: https://shadows.netlify.app/

Let me know if I missed something here.

from dripsy.

nandorojo avatar nandorojo commented on June 17, 2024 1

If you want to see which fields from React Native map onto web shadows, you can see this file from React Native Web:

/**
 * Copyright (c) Nicolas Gallagher.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import normalizeColor from '../../modules/normalizeColor';
import normalizeValueWithProperty from './normalizeValueWithProperty';

const defaultOffset = { height: 0, width: 0 };

const resolveShadowValue = (style: Object) => {
  const { shadowColor, shadowOffset, shadowOpacity, shadowRadius } = style;
  const { height, width } = shadowOffset || defaultOffset;
  const offsetX = normalizeValueWithProperty(width);
  const offsetY = normalizeValueWithProperty(height);
  const blurRadius = normalizeValueWithProperty(shadowRadius || 0);
  const color = normalizeColor(shadowColor || 'black', shadowOpacity);
  if (color != null && offsetX != null && offsetY != null && blurRadius != null) {
    return `${offsetX} ${offsetY} ${blurRadius} ${color}`;
  }
};

export default resolveShadowValue;

Since I don't see much changing about this, I'm going to close.

from dripsy.

cmaycumber avatar cmaycumber commented on June 17, 2024 1

I tried the above, what I noticed is that the following:

web: {
 boxShadow: '3px 3px 5px #ccc, 1'
},

has no effect for me on RN4W, but commenting this out and using the default values works fine.
What I am curious about is how to move these shadow values into my theme file so I can reference them in the same way I do with colors for example? Any help would be appreciated.

@daxfrost This was more of a proof of concept. I'm currently doing something like this in my theme file:

cards: {
primary: {
 ...Platform.select({
        // these are just random shadow values to illustrate
        web: {
          boxShadow: '3px 3px 5px #ccc, 1'
        },
        default: {
          shadowColor: '#000',
          shadowOffset: {
            width: 0,
            height: 2
          },
          shadowOpacity: 0.25,
          shadowRadius: 3.84,
          elevation: 5
        }
      })
   }
 }

You can map a custom theme property by using the createThemeElement export like the following:

export const Card = createThemedComponent(View, {
  themeKey: 'cards',
  defaultVariant: 'primary',
})

Let me know if this helps at all.

I like the look of this approach, too - I will try it in a sec.

This approach also works, and feels quite clean to me... however, I am also getting the following TS error:

image

I have a feeling that this might be fixed in #14. I can check just to make sure.

from dripsy.

daxfrost avatar daxfrost commented on June 17, 2024 1

@daxfrost I think the issue relates to #33. I used your code and reproduced it on the fresnel-2 branch with a dripsy View, but when I switched to a plain react-native View it works fine.

Are you using a View from dripsy or RN by any chance?

Ah, silly me! I was, and I see it fixed the issue using a RN View. I take it createThemedComponent should obviously only be used on a RN View.

That said, I take it we still want to find a work around for #33 in future.

from dripsy.

nandorojo avatar nandorojo commented on June 17, 2024 1

Yeah, I'd stick to using a native view when calling createThemedComponent for now. #33 is a high priority issue in my mind, but I haven't been able to figure it out quite yet. Any help on that would be amazing, since it's also blocking the pragma and other useful features.

I'll be putting out some release notes later when I publish the major changes from fresnel-2.

from dripsy.

nandorojo avatar nandorojo commented on June 17, 2024 1

Dripsy v3 comes with fantastic support for box shadow and text shadow. You can see more at #124.

It comes with a new theme.textShadows field, which is typed for RN. theme.shadows is also now typed with RN types. The sx prop accepts all textShadow* and shadow* props.

And, you can also pass values from your theme directly to textShadow or boxShadow in sx. It will pull these values from your theme, with intellisense!

from dripsy.

cmaycumber avatar cmaycumber commented on June 17, 2024

I imagine for this we'd probably allow for the react-native box-shadow properties and the normal css box-shadow properties in the sx prop then give the web based box-shadow precendence if the platform is web e.i:

shadowColor: "#000",
shadowOffset: { 
  width: 0,
  height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
box-shadow: "10px 5px 5px red" (This takes precedence over native shadows and is only applied on the web)

What do you think?

from dripsy.

nandorojo avatar nandorojo commented on June 17, 2024

This might be useful for converting an sx prop to RN styles. https://github.com/styled-components/css-to-react-native

from dripsy.

nandorojo avatar nandorojo commented on June 17, 2024

This takes precedence over native shadows and is only applied on the web

I prefer to just have one style across platforms. However, boxShadow would be necessary if web shadow styling isn't fully supported by RN's normal shadow styles. I'll look into what RNW says about this.

from dripsy.

cmaycumber avatar cmaycumber commented on June 17, 2024

Any idea on how we might support elevation for android? I think https://github.com/styled-components/css-to-react-native will cover most of our needs for this and be easy to integrate after taking a look at there API. But it doesn't create the elevation property.

We may be able to attach an additional space for a comma to be added for on the elevation for example:

boxShadow: '3px 3px 5px #ccc, 1',

We would then parse the style use css-to-react-native for the first part and manually add on the elevation property with the second part if it exists.

This would also allow us to use theme-ui theme object like normal but it would need to be well documented or would easily slip through the cracks.

from dripsy.

daxfrost avatar daxfrost commented on June 17, 2024

👍 this is something that became an issue for me too, I would like to support shadows, is there no work around for this with the current implementation?

The only way I can see is by using react-native when required for this an apply View as RNView for these cases... but it sucks that I have to specially do this and limiting in more complex cases.

from dripsy.

daxfrost avatar daxfrost commented on June 17, 2024

So far, I've been using the normal React Native shadow properties without much of an issue. That said, I don't have many shadows in my current app, so maybe I'm behind on something.

This issue was actually intended to solve the fact that the sx prop's TS types don't expect values like shadowOffset, etc. that come from RN styles. Functionally speaking, the RNW shadows have been fine in my experience. Have they not for you @daxfrost ?

If RNW's shadows are insufficient for you, could you try something like this?

import React from 'react'
import { View } from 'dripsy'
import { Platform } from 'react-native'

const WithShadow = () => (
  <View
    sx={{
      ...Platform.select({
        // these are just random shadow values to illustrate
        web: {
          boxShadow: '3px 3px 5px #ccc, 1'
        },
        default: {
          shadowColor: '#000',
          shadowOffset: {
            width: 0,
            height: 2
          },
          shadowOpacity: 0.25,
          shadowRadius: 3.84,
          elevation: 5
        }
      })
    }}
  />
)

However, given that the React Native Web philosophy is quite strict on not using CSS values, I don't recommend this usage. RNW doesn't even support the className prop anymore, so I wouldn't feel safe using boxShadow directly to style it, as it might become a no-op in the future.

In general, you should aim for platform-agnostic styles. But when you can't, I think it should be up to the developer, not this library, to decide when.

I also find this tool by @EvanBacon useful for creating React Native shadows that are web-compatible: https://shadows.netlify.app/

Let me know if I missed something here.

I tried the above, what I noticed is that the following:

    web: {
      boxShadow: '3px 3px 5px #ccc, 1'
    },

has no effect for me on RN4W, but commenting this out and using the default values works fine.

What I am curious about is how to move these shadow values into my theme file so I can reference them in the same way I do with colors for example? Any help would be appreciated.

from dripsy.

daxfrost avatar daxfrost commented on June 17, 2024

I see the Theme Aware props here, but I want to map my own custom keys from my custom theme file, how does one go about doing that? https://theme-ui.com/sx-prop#theme-aware-properties

e.g:



const theme = {
  colors: {
    text: '#000',
    containerBackground: '#f6fcfe',
    viewBackground: '#ffffff',
    shadowColor: '#000000',
    primary: 'tomato',
  },
  fonts: {
    body: 'system-ui, sans-serif',
    heading: '"Avenir Next", sans-serif',
  },
  spacing: [10, 12, 14],
  shadows : {
    light: {
      shadowOffset: {
        width: 0,
        height: 2
      }
    }
  }
};

export default theme;

and then in my sx prop in the theme referencing file:

<View
    sx={{
      ...Platform.select({
        default: {
          backgroundColor: 'viewBackground',
          shadowColor: 'shadowColor',
          shadowOffset: {
            width: 'shadows.light.shadowOffset.width',
            height: 2
          },
          shadowOpacity: 0.25,
          shadowRadius: 3.84,
          elevation: 5
        }
      })
    }}>

I assume I am not understanding how this lookup is done in Dripsy, but it's not mapping, and instead interpreted as the raw string value.

This line is not working: width: 'shadows.light.shadowOffset.width',

You can see the reason I want this is because the existing Theme Aware specification is web specific (box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.75);), and cannot translate to the separate React Native props.

from dripsy.

cmaycumber avatar cmaycumber commented on June 17, 2024

I tried the above, what I noticed is that the following:

web: {
 boxShadow: '3px 3px 5px #ccc, 1'
},

has no effect for me on RN4W, but commenting this out and using the default values works fine.

What I am curious about is how to move these shadow values into my theme file so I can reference them in the same way I do with colors for example? Any help would be appreciated.

@daxfrost This was more of a proof of concept. I'm currently doing something like this in my theme file:

cards: {
primary: {
...Platform.select({
        // these are just random shadow values to illustrate
        web: {
          boxShadow: '3px 3px 5px #ccc, 1'
        },
        default: {
          shadowColor: '#000',
          shadowOffset: {
            width: 0,
            height: 2
          },
          shadowOpacity: 0.25,
          shadowRadius: 3.84,
          elevation: 5
        }
      })
   }
}

You can map a custom theme property by using the createThemeElement export like the following:

export const Card = createThemedComponent(View, {
  themeKey: 'cards',
  defaultVariant: 'primary',
})

Let me know if this helps at all.

from dripsy.

nandorojo avatar nandorojo commented on June 17, 2024

@daxfrost Oh, you're right. Thanks for the useful example. Shadows don't seem to take theme values like that. I could look into adding it.

I've actually been using hooks to access theme values as variables, so it's interesting to see the different approaches.

I'm pushing a major update soon that will expose a useDripsyTheme hook that you'll be able to use. In the meantime, could you try this?

import { useThemeUI } from 'theme-ui'

const Shadows = () => {
  const { shadows } = useThemeUI().theme

  return (
    <View
      sx={{
        backgroundColor: 'viewBackground',
        shadowColor: 'shadowColor',
        shadowOffset: {
          width: shadows.light.shadowOffset.width, // no longer a string
          height: 2
        },
        shadowOpacity: 0.25,
        shadowRadius: 3.84,
        elevation: 5
      }}
    />
  )
}

I understand if this isn't the perfect approach, since using theme values is great directly in the theme itself. I'll see what it would take to add those aliases.

from dripsy.

daxfrost avatar daxfrost commented on June 17, 2024

I tried the above, what I noticed is that the following:

web: {
 boxShadow: '3px 3px 5px #ccc, 1'
},

has no effect for me on RN4W, but commenting this out and using the default values works fine.
What I am curious about is how to move these shadow values into my theme file so I can reference them in the same way I do with colors for example? Any help would be appreciated.

@daxfrost This was more of a proof of concept. I'm currently doing something like this in my theme file:

cards: {
primary: {
...Platform.select({
        // these are just random shadow values to illustrate
        web: {
          boxShadow: '3px 3px 5px #ccc, 1'
        },
        default: {
          shadowColor: '#000',
          shadowOffset: {
            width: 0,
            height: 2
          },
          shadowOpacity: 0.25,
          shadowRadius: 3.84,
          elevation: 5
        }
      })
   }
}

You can map a custom theme property by using the createThemeElement export like the following:

export const Card = createThemedComponent(View, {
  themeKey: 'cards',
  defaultVariant: 'primary',
})

Let me know if this helps at all.

I like the look of this approach, too - I will try it in a sec.

from dripsy.

daxfrost avatar daxfrost commented on June 17, 2024

@daxfrost Oh, you're right. Thanks for the useful example. Shadows don't seem to take theme values like that. I could look into adding it.

I've actually been using hooks to access theme values as variables, so it's interesting to see the different approaches.

I'm pushing a major update soon that will expose a useDripsyTheme hook that you'll be able to use. In the meantime, could you try this?

import { useThemeUI } from 'theme-ui'

const Shadows = () => {
  const { shadows } = useThemeUI().theme

  return (
    <View
      sx={{
        backgroundColor: 'viewBackground',
        shadowColor: 'shadowColor',
        shadowOffset: {
          width: shadows.light.shadowOffset.width, // no longer a string
          height: 2
        },
        shadowOpacity: 0.25,
        shadowRadius: 3.84,
        elevation: 5
      }}
    />
  )
}

I understand if this isn't the perfect approach, since using theme values is great directly in the theme itself. I'll see what it would take to add those aliases.

So, I tried this, and it actually works... however I get a TS compiler error.

image

from dripsy.

daxfrost avatar daxfrost commented on June 17, 2024

I tried the above, what I noticed is that the following:

web: {
 boxShadow: '3px 3px 5px #ccc, 1'
},

has no effect for me on RN4W, but commenting this out and using the default values works fine.
What I am curious about is how to move these shadow values into my theme file so I can reference them in the same way I do with colors for example? Any help would be appreciated.

@daxfrost This was more of a proof of concept. I'm currently doing something like this in my theme file:

cards: {
primary: {
...Platform.select({
        // these are just random shadow values to illustrate
        web: {
          boxShadow: '3px 3px 5px #ccc, 1'
        },
        default: {
          shadowColor: '#000',
          shadowOffset: {
            width: 0,
            height: 2
          },
          shadowOpacity: 0.25,
          shadowRadius: 3.84,
          elevation: 5
        }
      })
   }
}

You can map a custom theme property by using the createThemeElement export like the following:

export const Card = createThemedComponent(View, {
  themeKey: 'cards',
  defaultVariant: 'primary',
})

Let me know if this helps at all.

I like the look of this approach, too - I will try it in a sec.

This approach also works, and feels quite clean to me... however, I am also getting the following TS error:

image

from dripsy.

daxfrost avatar daxfrost commented on June 17, 2024

@cmaycumber that would be so great if it is fixed, this would really give me confidence. I see you plan to merge it today 👍 looking forward to this if it is fixed.

from dripsy.

cmaycumber avatar cmaycumber commented on June 17, 2024

@daxfrost I think the issue relates to #33. I used your code and reproduced it on the fresnel-2 branch with a dripsy View, but when I switched to a plain react-native View it works fine.

Are you using a View from dripsy or RN by any chance?

from dripsy.

nandorojo avatar nandorojo commented on June 17, 2024

TS warnings for components are fixed in 1.2.1. Now that multiple variants is supported, I think #33 is a bit of an urgent problem, especially since we want to build UI libraries on top of Dripsy.

from dripsy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.