0.0.1 • Published 2 years ago

react-style-utils v0.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

React Style Utils

面向跨端提供相同的样式特性供给算法。

  1. 不生成具体的样式或 className ,而是生成中间数据。
  2. 针对 React 运行机制设计,所有的特性构成方法,皆区分:属性初始化解析提取 两个入口。

属性初始化 :如,通过 flex 函数帮助快速建立 flex 特性的声明

const Test: React.FC = () => (
  <View flex={flex('col-nowrap', 'between')}>
    <View>cell 1</View>
    <View>cell 2</View>
  </View>
)

flex 函数,只将 flex 声明内容进行存储,不做任何过滤或转化,生成一个浅层的数据结构(单层)以满足浅比较的需要。React 机制,这个 Test 组件内的 props 或 state 变化时,都会触发 flex 函数被循环调用。

解析提取 :然后基于对 flex 函数返回的数据进行样式提取:

const useFlex = (props) => {
  const ref = useRef(null);

  useEffect(() => {
    if (ref.current == null || !shallowEqual(props, ref.current)) {
      ref.current = props;
      // 实际对 flex props 进行解析
      handleFlex(parseFlexProps(props));
      // h5 或 小程序,可以返回 className,不同的项目环境,className 也会不一样。
      // native 则是返回相应的 Stylesheet
    }
  }, [props]);
}

比如,针对 windi-css flexbox 生成相关的 className

const dirClasses = {
  [Flex.row]   : 'flex-row',
  [Flex.col]   : 'flex-col',
  [Flex.rowRev]: 'flex-row-reverse',
  [Flex.colRev]: 'flex-col-reverse',
};

const wrapClasses = {
  0             : undefined,
  [Flex.nowrap] : 'flex-nowrap',
  [Flex.wrap]   : 'flex-wrap',
  [Flex.wrapRev]: 'flex-wrap-reverse',
};

const justifyClass = ({ content, items, self }: CISParseResult): string => {
  return [
    content && `justify-${content}`,
    items && `justify-items-${items}`,
    self && `justify-self-${self}`,
  ].filter(Boolean).join(' ');
};

const alignClass = ({ content, items, self }: CISParseResult): string => {
  return [
    content && `content-${content}`,
    items && `items-${items}`,
    self && `self-${self}`,
  ].filter(Boolean).join(' ');
};

const windiFlexbox = (
  res: FlexParsed | undefined,
  isInlineFlex = false,
): string | undefined => {
  if (res == null) return undefined;
  return clsx(
    isInlineFlex ? 'inline-flex' : 'flex',
    dirClasses[res.dir] ?? null,
    wrapClasses[res.wrap] ?? null,
    justifyClass(res.justify),
    alignClass(res.align),
  );
};

已实现特性

  • flex
  • flex cell - basis、grow、shrink、order
  • position
  • grid
  • display - visible 、多行截取

优先实现参考:

  • yoga layout,RN 中,Flex 和 Position 是极其频繁使用的,写 Stylesheet.create 写到吐。

测试覆盖

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                  
 flex.ts  |     100 |      100 |     100 |     100 |                  
----------|---------|----------|---------|---------|-------------------