rn-css 1.6.8 → 1.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -180,6 +180,14 @@ if(width < 70 * em) { /* Do something when width is lesser than 70em */ }
180
180
  return <View onLayout={event => setWidth(event.nativeEvent.layout.width)}>...</View>
181
181
  ```
182
182
 
183
+ Default value for `rem` units is 16. If you want to declare another value, you can use `RemContext`:
184
+
185
+ ```javascript
186
+ import { RemContext } from 'rn-css'
187
+ ...
188
+ return <RemContext.Provider value={10}>{children}</RemContext.Provider>
189
+ ```
190
+
183
191
  ---
184
192
 
185
193
  ## Convert a CSS string to React-Native Style
@@ -11,6 +11,7 @@ const react_native_1 = require("react-native");
11
11
  const convertStyle_1 = __importDefault(require("./convertStyle"));
12
12
  const cssToRN_1 = __importDefault(require("./cssToRN"));
13
13
  const features_1 = require("./features");
14
+ const generateHash_1 = __importDefault(require("./generateHash"));
14
15
  exports.defaultUnits = { em: 16, vw: 1, vh: 1, vmin: 1, vmax: 1, rem: 16, px: 1, pt: 72 / 96, in: 96, pc: 9, cm: 96 / 2.54, mm: 96 / 25.4 };
15
16
  exports.RemContext = react_1.default.createContext(exports.defaultUnits.rem);
16
17
  exports.FontSizeContext = react_1.default.createContext(exports.defaultUnits.em);
@@ -22,6 +23,23 @@ function buildCSSString(chunks, functs, props, shared) {
22
23
  computedString += props.rnCSS.replace(/=/gm, ':') + ';';
23
24
  return computedString;
24
25
  }
26
+ const styleMap = {};
27
+ function getStyle(hash, style) {
28
+ const styleInfo = styleMap[hash];
29
+ if (styleInfo) {
30
+ styleInfo.usage++;
31
+ return styleInfo.style;
32
+ }
33
+ else {
34
+ const sheet = react_native_1.StyleSheet.create({ [hash]: style });
35
+ return (styleMap[hash] = { style: sheet[hash], usage: 1 }).style;
36
+ }
37
+ }
38
+ function removeStyle(hash) {
39
+ styleMap[hash].usage--;
40
+ if (styleMap[hash].usage <= 0)
41
+ delete styleMap[hash];
42
+ }
25
43
  const styled = (Component) => {
26
44
  const styledComponent = (chunks, ...functs) => {
27
45
  const ForwardRefComponent = react_1.default.forwardRef((props, ref) => {
@@ -33,7 +51,7 @@ const styled = (Component) => {
33
51
  const rnStyle = react_1.default.useMemo(() => (0, cssToRN_1.default)(css), [css]);
34
52
  const { needsLayout, needsHover } = react_1.default.useMemo(() => ({
35
53
  // needsFontSize: !!css.match(/\b(\d+)(\.\d+)?em\b/)
36
- // needsScreenSize: !!cssString.current.match(/\b(\d+)(\.\d+)?v([hw]|min|max)\b/) || !!rnStyle.media,
54
+ // needsScreenSize: !!css.match(/\b(\d+)(\.\d*)?v([hw]|min|max)\b/) || !!rnStyle.media,
37
55
  needsLayout: !!css.match(/\d%/),
38
56
  needsHover: !!rnStyle.hover
39
57
  }), [css, rnStyle.hover]);
@@ -77,19 +95,24 @@ const styled = (Component) => {
77
95
  return style;
78
96
  }, [em, mediaQuery, tempStyle]);
79
97
  const units = react_1.default.useMemo(() => ({ ...baseUnits, em }), [baseUnits, em]);
80
- const styleConvertedFromCSS = react_1.default.useMemo(() => (0, convertStyle_1.default)(finalStyle, units), [finalStyle, units]);
81
- const style = react_1.default.useMemo(() => [styleConvertedFromCSS, props.style], [props.style, styleConvertedFromCSS]);
82
- const flatStyle = react_1.default.useMemo(() => react_native_1.StyleSheet.flatten(style), [style]);
98
+ const { style: styleConvertedFromCSS, hash } = react_1.default.useMemo(() => {
99
+ const style = (0, convertStyle_1.default)(finalStyle, units);
100
+ delete style.textOverflow;
101
+ const hash = (0, generateHash_1.default)(JSON.stringify(style));
102
+ return { style: getStyle(hash, style), hash };
103
+ }, [finalStyle, units]);
83
104
  const newProps = react_1.default.useMemo(() => {
84
- const newProps = { style, onMouseEnter, onMouseLeave, onLayout };
85
- if (flatStyle.textOverflow === 'ellipsis')
105
+ const newProps = { style: [styleConvertedFromCSS, props.style], onMouseEnter, onMouseLeave, onLayout };
106
+ if (finalStyle.textOverflow === 'ellipsis') {
86
107
  Object.assign(newProps, { numberOfLines: 1 });
108
+ }
87
109
  return newProps;
88
- }, [flatStyle.textOverflow, onLayout, onMouseEnter, onMouseLeave, style]);
110
+ }, [finalStyle.textOverflow, onLayout, onMouseEnter, onMouseLeave, props.style, styleConvertedFromCSS]);
111
+ react_1.default.useEffect(() => () => removeStyle(hash), [hash]);
89
112
  // The lines below can improve perfs, but it causes the component to remount when the font size changes
90
113
  // const currentFontSize = React.useContext(FontSizeContext)
91
114
  // if (em !== currentFontSize) {
92
- if (flatStyle.fontSize) {
115
+ if (styleConvertedFromCSS.fontSize) {
93
116
  return react_1.default.createElement(exports.FontSizeContext.Provider, { value: em },
94
117
  react_1.default.createElement(Component, { ref: ref, ...props, ...newProps }));
95
118
  }
package/dist/types.d.ts CHANGED
@@ -60,6 +60,7 @@ export declare type PartialStyle = Partial<Record<keyof ViewStyle | keyof TextSt
60
60
  width: string;
61
61
  height: string;
62
62
  };
63
+ textOverflow?: 'ellipsis';
63
64
  transform?: Transform[];
64
65
  };
65
66
  export declare type Style = PartialStyle & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-css",
3
- "version": "1.6.8",
3
+ "version": "1.6.9",
4
4
  "scripts": {
5
5
  "test": "jest",
6
6
  "prepare": "tsc",
@@ -1,11 +1,12 @@
1
1
  /* eslint-disable react/prop-types */
2
2
  /* eslint-disable react/display-name */
3
3
  import React, { MouseEvent } from 'react'
4
- import { FlatList, FlatListProps, LayoutChangeEvent, Platform, SectionList, SectionListProps, StyleProp, StyleSheet, VirtualizedList, VirtualizedListProps } from 'react-native'
4
+ import { FlatList, FlatListProps, LayoutChangeEvent, Platform, SectionList, SectionListProps, StyleProp, StyleSheet, TextStyle, ViewStyle, VirtualizedList, VirtualizedListProps } from 'react-native'
5
5
  import convertStyle from './convertStyle'
6
6
  import cssToStyle from './cssToRN'
7
7
  import { useFontSize, useHover, useLayout, useScreenSize, useMediaQuery } from './features'
8
8
  import type { Style, Units } from './types'
9
+ import generateHash from './generateHash'
9
10
 
10
11
  export const defaultUnits: Units = { em: 16, vw: 1, vh: 1, vmin: 1, vmax: 1, rem: 16, px: 1, pt: 72 / 96, in: 96, pc: 9, cm: 96 / 2.54, mm: 96 / 25.4 }
11
12
  export const RemContext = React.createContext<number>(defaultUnits.rem)
@@ -29,6 +30,22 @@ function buildCSSString<T extends { rnCSS?: string }> (chunks: TemplateStringsAr
29
30
  if (props.rnCSS) computedString += props.rnCSS.replace(/=/gm, ':') + ';'
30
31
  return computedString
31
32
  }
33
+ const styleMap: Record<string, { style: ViewStyle & TextStyle, usage: number }> = {}
34
+ function getStyle (hash: string, style: ViewStyle & TextStyle) {
35
+ const styleInfo = styleMap[hash]
36
+ if (styleInfo) {
37
+ styleInfo.usage++
38
+ return styleInfo.style
39
+ }
40
+ else {
41
+ const sheet = StyleSheet.create({ [hash]: style })
42
+ return (styleMap[hash] = { style: sheet[hash], usage: 1 }).style
43
+ }
44
+ }
45
+ function removeStyle (hash: string) {
46
+ styleMap[hash].usage--
47
+ if (styleMap[hash].usage <= 0) delete styleMap[hash]
48
+ }
32
49
  const styled = <Props, >(Component: React.ComponentType<Props>) => {
33
50
  const styledComponent = <S, >(chunks: TemplateStringsArray, ...functs: (Primitive | Functs<S & Props>)[]) => {
34
51
  const ForwardRefComponent = React.forwardRef<React.ComponentType<S & Props & OptionalProps>, S & Props & OptionalProps>((props: S & Props & OptionalProps, ref) => {
@@ -41,7 +58,7 @@ const styled = <Props, >(Component: React.ComponentType<Props>) => {
41
58
 
42
59
  const { needsLayout, needsHover } = React.useMemo(() => ({
43
60
  // needsFontSize: !!css.match(/\b(\d+)(\.\d+)?em\b/)
44
- // needsScreenSize: !!cssString.current.match(/\b(\d+)(\.\d+)?v([hw]|min|max)\b/) || !!rnStyle.media,
61
+ // needsScreenSize: !!css.match(/\b(\d+)(\.\d*)?v([hw]|min|max)\b/) || !!rnStyle.media,
45
62
  needsLayout: !!css.match(/\d%/),
46
63
  needsHover: !!rnStyle.hover
47
64
  }), [css, rnStyle.hover])
@@ -89,19 +106,26 @@ const styled = <Props, >(Component: React.ComponentType<Props>) => {
89
106
 
90
107
  const units = React.useMemo<Units>(() => ({ ...baseUnits, em }), [baseUnits, em])
91
108
 
92
- const styleConvertedFromCSS = React.useMemo(() => convertStyle(finalStyle, units), [finalStyle, units])
93
- const style: StyleProp<any> = React.useMemo(() => [styleConvertedFromCSS, props.style], [props.style, styleConvertedFromCSS])
94
- const flatStyle = React.useMemo(() => StyleSheet.flatten(style), [style])
109
+ const { style: styleConvertedFromCSS, hash } = React.useMemo(() => {
110
+ const style = convertStyle(finalStyle, units)
111
+ delete (style as Style).textOverflow
112
+ const hash = generateHash(JSON.stringify(style))
113
+ return { style: getStyle(hash, style), hash }
114
+ }, [finalStyle, units])
95
115
  const newProps = React.useMemo(() => {
96
- const newProps: OptionalProps = { style, onMouseEnter, onMouseLeave, onLayout }
97
- if (flatStyle.textOverflow === 'ellipsis') Object.assign(newProps, { numberOfLines: 1 })
116
+ const newProps: OptionalProps = { style: [styleConvertedFromCSS, props.style], onMouseEnter, onMouseLeave, onLayout }
117
+ if (finalStyle.textOverflow === 'ellipsis') {
118
+ Object.assign(newProps, { numberOfLines: 1 })
119
+ }
98
120
  return newProps
99
- }, [flatStyle.textOverflow, onLayout, onMouseEnter, onMouseLeave, style])
121
+ }, [finalStyle.textOverflow, onLayout, onMouseEnter, onMouseLeave, props.style, styleConvertedFromCSS])
122
+
123
+ React.useEffect(() => () => removeStyle(hash), [hash])
100
124
 
101
125
  // The lines below can improve perfs, but it causes the component to remount when the font size changes
102
126
  // const currentFontSize = React.useContext(FontSizeContext)
103
127
  // if (em !== currentFontSize) {
104
- if (flatStyle.fontSize) {
128
+ if (styleConvertedFromCSS.fontSize) {
105
129
  return <FontSizeContext.Provider value={em}>
106
130
  <Component ref={ref} {...props} {...newProps} />
107
131
  </FontSizeContext.Provider>
package/src/types.ts CHANGED
@@ -63,6 +63,7 @@ export type PartialStyle = Partial<Record<keyof ViewStyle | keyof TextStyle, str
63
63
  width: string;
64
64
  height: string;
65
65
  };
66
+ textOverflow?: 'ellipsis'
66
67
  transform?: Transform[];
67
68
  }
68
69