模板文字中的Array.map可以为多个媒体查询呈现CSS规则吗?

时间:2018-11-13 09:46:11

标签: typescript styled-components

在这里,我试图遍历道具以呈现多个媒体查询的CSS规则。

用法

private void fetchDiff() {
        sDiffData = mRealm.where(DiffData.class)
                .greaterThanOrEqualTo(...)
                .lessThan(...)
                .equalTo(..)
                .findAllAsync();
        sDiffData.addChangeListener(new RealmChangeListener<RealmResults<...>>() {
            @Override
            public void onChange(RealmResults<...> element) {
                ...
        });
}

public void update() {
    sData = dataQuery.sort(Data.ORDER, Sort.ASCENDING).findAllAsync();
    sData.addChangeListener(new RealmChangeListener<RealmResults<Data>>() {
        @Override
        public void onChange(RealmResults<Data> element) {
            Realm realm = element.getRealm();
            if(realm.isInTransaction()) {
                handler.post(() -> {
                    fetchDiff();
                });
            } else {
                fetchDiff();
            }
        }
    });
}

样式化的组件

<FlexContainerExperimental
    direction="column"
    mediaQueries={[
        {mediaQueryMinWidth: props.theme.minWidthLargeDevice, direction: 'row'},
        {mediaQueryMinWidth: props.theme.minWidthMediumDevice, direction: 'row', itemsPerLane: 2},
    ]}
>
    ...
</FlexContainerExperimental>

意外行为

仅应用数组中的第一个媒体查询。换句话说,根据mediaQueries数组中对象的顺序,我会得到不同的行为

interface FlexContainerSettings {
    direction?: string;
    itemsPerLane?: number;
}

interface FlexContainerExperimentalProps extends FlexContainerSettings {
    // tslint:disable-next-line:no-any
    children: any;
    className?: string;
    mediaQueries?: MediaQuery[];
}

interface MediaQuery extends FlexContainerSettings {
    mediaQueryMinWidth: string;
}

// tslint:disable:no-any
const Container = styled.div<FlexContainerExperimentalProps>`
    display: flex;
    margin-left: -${props => props.theme.itemHorizontalMargin};
    margin-top: -${props => props.theme.itemVerticalMargin};

    flex-direction: ${props => props.direction};

    ${props => props.mediaQueries && props.mediaQueries.map((mediaQuery: MediaQuery) => `
        @media all and (min-width: ${mediaQuery.mediaQueryMinWidth}) {
            flex-direction: ${mediaQuery.direction};
            ${mediaQuery.itemsPerLane && `
                flex-wrap: wrap;
                & > * {
                    flex: 1 1 calc(${100 / mediaQuery.itemsPerLane}% - ${
                        mediaQuery.direction === 'column' || 
                        (!mediaQuery.direction && props.direction === 'column') 
                        ? props.theme.itemVerticalMargin 
                        : props.theme.itemHorizontalMargin}
                    );
                }
            `};
        };
    `).join()};
`;

function FlexContainerExperimental(props: FlexContainerExperimentalProps) {
    const { children, ...rest } = props;

    return (
        <Container {...rest}>
            {children}
        </Container>
    );
}

export { FlexContainerExperimental };
export * from './FlexItem';

1 个答案:

答案 0 :(得分:0)

我想出了解决方案。在每个媒体查询之后添加新行。

const Container = styled.div<FlexContainerExperimentalProps>`
    display: flex;
    margin-left: -${props => props.theme.itemHorizontalMargin};
    margin-top: -${props => props.theme.itemVerticalMargin};

    flex-direction: ${props => props.direction};

    ${props => props.mediaQueries && props.mediaQueries.map((mediaQuery: MediaQuery) => `
        @media all and (min-width: ${mediaQuery.mediaQueryMinWidth}) {
            flex-direction: ${mediaQuery.direction};
            ${mediaQuery.itemsPerLane && `
                flex-wrap: wrap;
                & > * {
                    flex: 1 1 calc(${100 / mediaQuery.itemsPerLane}% - ${
                        mediaQuery.direction === 'column' || 
                        (!mediaQuery.direction && props.direction === 'column') 
                        ? props.theme.itemVerticalMargin 
                        : props.theme.itemHorizontalMargin}
                    );
                }
            `};
        }

    `).join('\n')};
`;