react-native-skeleton-placeholder icon indicating copy to clipboard operation
react-native-skeleton-placeholder copied to clipboard

Random width of lines

Open TTATPuOT opened this issue 3 years ago • 6 comments

Hello! I created a component to make a random with of skeletons:

interface RowProps extends ViewStyle {
    min: number
    max: number
    type: "%"|""
}

const Row = (props: RowProps) => {
    const { min, max, type, ...passProps } = props;

    const width = useMemo<string>(
        () => `${getRandomArbitrary(min, max)}${type}`,
        [min, max]
    );

    return <SkeletonPlaceholder.Item {...passProps} width={width} />
}

Row.defaultProps = {
    type: "%"
}

But if i add it into SkeletonPlaceholder it's don't show:

<>
    <Text>Placeholders will be here:</Text>
    <SkeletonPlaceholder>
        <Row min={50} max={80} type={""} height={10} borderRadius={2} />
        <Row min={50} max={80} type={""} height={8} borderRadius={2} />
    </SkeletonPlaceholder>
</>

image

How can i resove this?

TTATPuOT avatar Mar 27 '21 11:03 TTATPuOT

@TTATPuOT the reason is because the width is a percentage in the output. percentage unfortunately is not working yet, it is a known issue.

but try this workaround:

import {Dimensions} from "react-native";

const {width: WINDOW_WIDTH} = Dimensions.get("window");
type RowProps {
  min: string | number
  max: string | number
} & ViewStyle

const Row = (props: RowProps) => {
  const { min, max, type, ...passProps } = props;

  const getRandomArbitrary = (min, max) => {
    return Math.random() * (max - min) + min;
  }

  const parse = (value: string | number) => {
    if(typeof value === "string") {
      if(value.includes("%")) {
        const number = Number(value.replace("%", ""));
        return WINDOW_WIDTH * (number / 100);
      }

      return Number(value);
    }
    return value;
  }

  const width = getRandomArbitrary(parse(min), parse(max));

  return <SkeletonPlaceholder.Item {...passProps} width={width} />
}
<>
    <Text>Placeholders will be here:</Text>
    <SkeletonPlaceholder>
        //with percentage
        <Row min="50%" max="80%" height={10} borderRadius={2} />
        //with number
        <Row min={50} max={80} type={""} height={8} borderRadius={2} />
    </SkeletonPlaceholder>
</>

chramos avatar Mar 29 '21 11:03 chramos

@chramos thank you for response, but percents works fine for me. Code:

<SkeletonPlaceholder>
    <SkeletonPlaceholder.Item
        marginTop={31}
        paddingHorizontal={15}
    >
        <SkeletonPlaceholder.Item width={"80%"} height={15} borderRadius={4} />
        <SkeletonPlaceholder.Item width={"95%"} marginTop={5} height={16} borderRadius={4} />
        <SkeletonPlaceholder.Item width={"90%"} marginTop={5} height={16} borderRadius={4} />
        <SkeletonPlaceholder.Item width={"85%"} marginTop={5} height={16} borderRadius={4} />
    </SkeletonPlaceholder.Item>

</SkeletonPlaceholder>

image

But if i make a simplier component, it's still not works:

const Row = (props: RowProps & ViewStyle) => {
    const { min, max, ...passProps } = props;
    console.log(width); //console.log has not printed

    return <SkeletonPlaceholder.Item {...passProps} width={getRandomArbitrary(min, max)} />
}

I think problem for another reason.

TTATPuOT avatar Mar 29 '21 14:03 TTATPuOT

It works only without Row component:

<SkeletonPlaceholder>
    <SkeletonPlaceholder.Item width={getRandomArbitrary(60, 200)} height={10} borderRadius={2} />
</SkeletonPlaceholder>

It's works, but i want to useMemo in child component for optimization

TTATPuOT avatar Mar 29 '21 14:03 TTATPuOT

hmmm.. I'll check it and try to solve

chramos avatar Apr 09 '21 11:04 chramos

Which version are you using?

chramos avatar Apr 09 '21 11:04 chramos

Which version are you using?

3.0.4

TTATPuOT avatar Apr 09 '21 12:04 TTATPuOT