diff --git a/packages/discuz-design/components/flex/README.md b/packages/discuz-design/components/flex/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..7442a3a8770bd782445b10b95a21e27d51789c46
--- /dev/null
+++ b/packages/discuz-design/components/flex/README.md
@@ -0,0 +1,19 @@
+# Flex
+
+## 组件说明
+
+常用的布局。
+
+## 示例
+
+### WEB 示例
+
+[基础用法](./__examples__/web/index.tsx)
+
+### 小程序示例
+
+[基础用法](./__examples__/mini/index.tsx)
+
+## API 参数
+
+[API 参数](./interface.ts)
diff --git a/packages/discuz-design/components/flex/__examples__/mini/index.scss b/packages/discuz-design/components/flex/__examples__/mini/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..1b3b064d19a0481044f2098ece9f5fb7d7cd81df
--- /dev/null
+++ b/packages/discuz-design/components/flex/__examples__/mini/index.scss
@@ -0,0 +1,60 @@
+.page {
+ .box-row {
+ position: relative;
+ flex: 1;
+ color: #ffffff;
+ min-height: 10px;
+ margin-bottom: 0;
+ background: #aacfff;
+ border: 1px solid #ffffff;
+ border-radius: 2px;
+ overflow: hidden;
+ text-align: center;
+ box-sizing: border-box;
+ }
+ .box,
+ .box-first,
+ .box-nested,
+ .box-large {
+ position: relative;
+ flex: 1;
+ color: #ffffff;
+ min-height: 10px;
+ margin-bottom: 0;
+ background: #aacfff;
+ border: 1px solid #ffffff;
+ border-radius: 2px;
+ overflow: hidden;
+ text-align: center;
+ box-sizing: border-box;
+ }
+ .box-first {
+ font-size: 12px;
+ padding: 4px;
+ background: #559eff;
+ border-color: #aacfff;
+ }
+ .box-nested {
+ font-size: 12px;
+ padding: 4px;
+ background: #006eff;
+ border-color: #aacfff;
+ }
+ .box-large {
+ height: 80px;
+ }
+ .box-container {
+ padding: 5px;
+ box-sizing: border-box;
+ }
+ .code {
+ font-size: 10px;
+ color: #aacfff;
+ margin: 8px 0;
+ }
+ .box-wrap {
+ padding: 5px 0;
+ box-sizing: border-box;
+ }
+ }
+
\ No newline at end of file
diff --git a/packages/discuz-design/components/flex/__examples__/mini/index.tsx b/packages/discuz-design/components/flex/__examples__/mini/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..0900fc0874882dcbb6675afea34fe02d3e40062f
--- /dev/null
+++ b/packages/discuz-design/components/flex/__examples__/mini/index.tsx
@@ -0,0 +1,455 @@
+import React from "react";
+import { View, Text } from "@tarojs/components";
+import Flex from '../../index';
+import "./index.scss";
+
+const { Row, Col } = Flex
+
+export default function FlexExample() {
+ return (
+
+ Flex 弹性布局
+
+ 基本用法
+
+
+
+
+
+
+
+
+
+
+ 列宽均分
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 折行展示(默认)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 单行展示(可滚动)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 嵌套栅格
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 自定义槽宽
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Offsets
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 垂直方向对齐
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 水平分布
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+ 排序
+
+
+
+
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+ 6
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+ 6
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+ 6
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/discuz-design/components/flex/__examples__/web/index.scss b/packages/discuz-design/components/flex/__examples__/web/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..1b3b064d19a0481044f2098ece9f5fb7d7cd81df
--- /dev/null
+++ b/packages/discuz-design/components/flex/__examples__/web/index.scss
@@ -0,0 +1,60 @@
+.page {
+ .box-row {
+ position: relative;
+ flex: 1;
+ color: #ffffff;
+ min-height: 10px;
+ margin-bottom: 0;
+ background: #aacfff;
+ border: 1px solid #ffffff;
+ border-radius: 2px;
+ overflow: hidden;
+ text-align: center;
+ box-sizing: border-box;
+ }
+ .box,
+ .box-first,
+ .box-nested,
+ .box-large {
+ position: relative;
+ flex: 1;
+ color: #ffffff;
+ min-height: 10px;
+ margin-bottom: 0;
+ background: #aacfff;
+ border: 1px solid #ffffff;
+ border-radius: 2px;
+ overflow: hidden;
+ text-align: center;
+ box-sizing: border-box;
+ }
+ .box-first {
+ font-size: 12px;
+ padding: 4px;
+ background: #559eff;
+ border-color: #aacfff;
+ }
+ .box-nested {
+ font-size: 12px;
+ padding: 4px;
+ background: #006eff;
+ border-color: #aacfff;
+ }
+ .box-large {
+ height: 80px;
+ }
+ .box-container {
+ padding: 5px;
+ box-sizing: border-box;
+ }
+ .code {
+ font-size: 10px;
+ color: #aacfff;
+ margin: 8px 0;
+ }
+ .box-wrap {
+ padding: 5px 0;
+ box-sizing: border-box;
+ }
+ }
+
\ No newline at end of file
diff --git a/packages/discuz-design/components/flex/__examples__/web/index.tsx b/packages/discuz-design/components/flex/__examples__/web/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..bf9cad0605ef717acbe73d9b6092fcbc9a192902
--- /dev/null
+++ b/packages/discuz-design/components/flex/__examples__/web/index.tsx
@@ -0,0 +1,454 @@
+import React from "react";
+import Flex from "../../index";
+import "./index.scss";
+
+const { Row, Col } = Flex
+
+export default function FlexExample() {
+ return (
+
+
Flex 弹性布局
+
+
+
列宽均分
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
折行展示(默认)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
单行展示(可滚动)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
自定义槽宽
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Offsets
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
水平分布
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
+
+
+
+ Box Start
+
+
+ Box Center
+
+
+ Box End
+
+
+
+
+
+
+
+
+
排序
+
+
+
+
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+ 6
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+ 6
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ 2
+
+
+ 3
+
+
+ 4
+
+
+ 5
+
+
+ 6
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/discuz-design/components/flex/adapters/index.ts b/packages/discuz-design/components/flex/adapters/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..85c4466641df5bb617e037956eb822e02e18c6d2
--- /dev/null
+++ b/packages/discuz-design/components/flex/adapters/index.ts
@@ -0,0 +1,14 @@
+import { baseAdapterFactory } from '../../../extends/baseAdapter';
+
+export const FlexLogicalAdapter = baseAdapterFactory({
+ defaultAdapter: {},
+ adapterImplement() {
+ if (process.env.DISCUZ_ENV === 'web') {
+ return require('./web').useWebAdapter;
+ }
+
+ if (process.env.DISCUZ_ENV === 'mini') {
+ return require('./mini').useMiniAdapter;
+ }
+ },
+});
diff --git a/packages/discuz-design/components/flex/adapters/mini.tsx b/packages/discuz-design/components/flex/adapters/mini.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..375ada8057fda3cc90e49e80cb951ae95c843e2c
--- /dev/null
+++ b/packages/discuz-design/components/flex/adapters/mini.tsx
@@ -0,0 +1,4 @@
+import React, { useCallback } from 'react';
+
+export const useMiniAdapter = () => {
+}
\ No newline at end of file
diff --git a/packages/discuz-design/components/flex/adapters/web.tsx b/packages/discuz-design/components/flex/adapters/web.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..892f00166c328826919ff22eb274b476c062bb90
--- /dev/null
+++ b/packages/discuz-design/components/flex/adapters/web.tsx
@@ -0,0 +1,4 @@
+import React, { useCallback } from 'react';
+
+export const useWebAdapter = () => {
+}
\ No newline at end of file
diff --git a/packages/discuz-design/components/flex/index.tsx b/packages/discuz-design/components/flex/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..c3665067f62a6c3bda2f8cef826f38f4c7cec8a9
--- /dev/null
+++ b/packages/discuz-design/components/flex/index.tsx
@@ -0,0 +1,6 @@
+
+import React from 'react';
+import { RowProps, ColProps } from './interface';
+import { FlexViewAdapter } from './layouts/index';
+
+export default FlexViewAdapter() as { Row: React.FC, Col: React.FC };
diff --git a/packages/discuz-design/components/flex/interface.ts b/packages/discuz-design/components/flex/interface.ts
new file mode 100644
index 0000000000000000000000000000000000000000..19c0f8ef1b2b3e90a2698bea694a27de25408737
--- /dev/null
+++ b/packages/discuz-design/components/flex/interface.ts
@@ -0,0 +1,81 @@
+import { StyledProps } from 'utils/_type/StyledProps';
+
+/**
+ * Row 组件支持的属性
+ */
+export interface RowProps extends StyledProps {
+ /**
+ * 元素间隔
+ * @default 20
+ */
+ gutter?: number;
+
+ /**
+ * 元素超出 flex 容器时处理方式
+ * @default "wrap"
+ */
+ flexWrap?: "wrap" | "nowrap";
+
+ /**
+ * 设置 flex-direction: row-reverse;
+ * @default false
+ */
+ reverse?: boolean;
+
+ /**
+ * flex 布局下的垂直排列方式
+ * @default "stretch"
+ */
+ align?: "stretch" | "flex-start" | "flex-end" | "center" | "baseline";
+
+ /**
+ * flex 布局下的水平排列方式
+ * @default "flex-start"
+ */
+ justify?:
+ | "flex-start"
+ | "flex-end"
+ | "center"
+ | "space-around"
+ | "space-between"
+ | "space-evenly";
+
+ /**
+ * 包括的栅格列,请使用 作为子节点
+ */
+ children?: ColChild | ColChild[];
+}
+
+/**
+ * Col 组件支持的属性
+ */
+export interface ColProps extends StyledProps {
+ /**
+ * flex 布局属性
+ */
+ flex?: string | number;
+
+ /**
+ * Col 向右偏移列的数量
+ * @default 0
+ */
+ offset?: number;
+
+ /**
+ * 栅格顺序
+ * @default 0
+ */
+ order?: number;
+
+ /**
+ * 栅格占位格数
+ */
+ span?: number;
+
+ /**
+ * 栅格单元中内容
+ */
+ children?: React.ReactNode;
+}
+
+interface ColChild extends React.ReactElement {}
diff --git a/packages/discuz-design/components/flex/layouts/index.tsx b/packages/discuz-design/components/flex/layouts/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..17af8ab7de4071c8c91ffb78087ac2949597cc7e
--- /dev/null
+++ b/packages/discuz-design/components/flex/layouts/index.tsx
@@ -0,0 +1,9 @@
+export const FlexViewAdapter = () => {
+ if (process.env.DISCUZ_ENV === 'web') {
+ return require('./web').FlexWebLayout;
+ }
+
+ if (process.env.DISCUZ_ENV === 'mini') {
+ return require('./mini').FlexMiniLayout;
+ }
+};
diff --git a/packages/discuz-design/components/flex/layouts/mini.tsx b/packages/discuz-design/components/flex/layouts/mini.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..9c9bf6be2bd982caf30158571e52d76b31f831ad
--- /dev/null
+++ b/packages/discuz-design/components/flex/layouts/mini.tsx
@@ -0,0 +1,104 @@
+import React, { useContext, Component } from "react";
+import classNames from "classnames";
+import { View } from "@tarojs/components";
+import {RowProps, ColProps} from '../interface'
+import { useConfig } from '../../../extends/configContext';
+
+interface FlexContextValue {
+ gutter: number;
+}
+
+const FlexContext = React.createContext({ gutter: 20 });
+
+export function Row({
+ gutter = 20,
+ flexWrap = "wrap",
+ reverse = false,
+ align = "stretch",
+ justify = "flex-start",
+ children,
+ className,
+ style,
+}: RowProps) {
+ let flex: FlexContextValue = null;
+ let rowStyle: React.CSSProperties = null;
+
+ const { clsPrefix } = useConfig();
+
+ // 定义了 gutter 的,才生成一个 flex 上下文,否则使用默认样式即可
+ if (typeof gutter === "number") {
+ const gutterCompensation = Math.ceil(Number(gutter) / 2) * -1;
+ flex = {
+ gutter,
+ };
+ rowStyle = {
+ margin: `${gutterCompensation}px`,
+ };
+ }
+
+ rowStyle = {
+ ...(rowStyle || {}),
+ ...(style || {}),
+ };
+
+ const rowClassName = classNames(`${clsPrefix}-row`, className, {
+ [`${clsPrefix}-flex-wrap-nowrap`]: flexWrap === "nowrap",
+ [`${clsPrefix}-align-items-${align}`]: typeof align !== "undefined",
+ [`${clsPrefix}-justify-content-${justify}`]: typeof justify !== "undefined",
+ [`${clsPrefix}-flex-row-reverse`]: reverse,
+ });
+
+ return (
+
+ {children}
+
+ );
+}
+
+export function Col({
+ children,
+ className,
+ offset = 0,
+ order = 0,
+ flex: flexStyle,
+ span,
+ style,
+}: ColProps) {
+ const { clsPrefix } = useConfig();
+
+ const flex = useContext(FlexContext);
+
+ let colStyle: React.CSSProperties = null;
+ if (flex) {
+ const gutterCompensation = Math.ceil(Number(flex.gutter) / 2);
+ colStyle = {
+ padding: `${gutterCompensation}px`,
+ };
+ }
+
+ colStyle = {
+ ...(colStyle || {}),
+ ...(style || {}),
+ };
+
+ return (
+ = 1 && offset <= 11,
+ [`col-${span}`]: span >= 1 && span <= 12,
+ })}
+ style={{
+ ...colStyle,
+ order,
+ flex: flexStyle,
+ }}
+ >
+ {children}
+
+ );
+}
+
+export const FlexMiniLayout = {
+ Row: Row,
+ Col: Col
+}
diff --git a/packages/discuz-design/components/flex/layouts/web.tsx b/packages/discuz-design/components/flex/layouts/web.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..7729481080636c9310e9bf5264d76fe613bee883
--- /dev/null
+++ b/packages/discuz-design/components/flex/layouts/web.tsx
@@ -0,0 +1,103 @@
+import React, { useContext, Component } from "react";
+import classNames from "classnames";
+import {RowProps, ColProps} from '../interface'
+import { useConfig } from '../../../extends/configContext';
+
+interface FlexContextValue {
+ gutter: number;
+}
+
+const FlexContext = React.createContext({ gutter: 20 });
+
+export function Row({
+ gutter = 20,
+ flexWrap = "wrap",
+ reverse = false,
+ align = "stretch",
+ justify = "flex-start",
+ children,
+ className,
+ style,
+}: RowProps) {
+ let flex: FlexContextValue = null;
+ let rowStyle: React.CSSProperties = null;
+
+ const { clsPrefix } = useConfig();
+
+ // 定义了 gutter 的,才生成一个 flex 上下文,否则使用默认样式即可
+ if (typeof gutter === "number") {
+ const gutterCompensation = Math.ceil(Number(gutter) / 2) * -1;
+ flex = {
+ gutter,
+ };
+ rowStyle = {
+ margin: `${gutterCompensation}px`,
+ };
+ }
+
+ rowStyle = {
+ ...(rowStyle || {}),
+ ...(style || {}),
+ };
+
+ const rowClassName = classNames(`${clsPrefix}-row`, className, {
+ [`${clsPrefix}-flex-wrap-nowrap`]: flexWrap === "nowrap",
+ [`${clsPrefix}-align-items-${align}`]: typeof align !== "undefined",
+ [`${clsPrefix}-justify-content-${justify}`]: typeof justify !== "undefined",
+ [`${clsPrefix}-flex-row-reverse`]: reverse,
+ });
+
+ return (
+
+ {children}
+
+ );
+}
+
+export function Col({
+ children,
+ className,
+ offset = 0,
+ order = 0,
+ flex: flexStyle,
+ span,
+ style,
+}: ColProps) {
+ const flex = useContext(FlexContext);
+ const { clsPrefix } = useConfig();
+
+ let colStyle: React.CSSProperties = null;
+ if (flex) {
+ const gutterCompensation = Math.ceil(Number(flex.gutter) / 2);
+ colStyle = {
+ padding: `${gutterCompensation}px`,
+ };
+ }
+
+ colStyle = {
+ ...(colStyle || {}),
+ ...(style || {}),
+ };
+
+ return (
+ = 1 && offset <= 11,
+ [`col-${span}`]: span >= 1 && span <= 12,
+ })}
+ style={{
+ ...colStyle,
+ order,
+ flex: flexStyle,
+ }}
+ >
+ {children}
+
+ );
+}
+
+export const FlexWebLayout = {
+ Row: Row,
+ Col: Col
+}
+
diff --git a/packages/discuz-design/components/flex/styles/index.scss b/packages/discuz-design/components/flex/styles/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..191faeb4f0ed5565436e42526bed45dceafec44c
--- /dev/null
+++ b/packages/discuz-design/components/flex/styles/index.scss
@@ -0,0 +1,251 @@
+:host {
+ width: 100%;
+}
+.#{$namespace}-row {
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+}
+
+.#{$namespace}-flex-wrap-nowrap {
+ flex-wrap: nowrap;
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+.#{$namespace}-flex-wrap-nowrap::-webkit-scrollbar {
+ display: none;
+}
+
+.#{$namespace}-flex-row-reverse {
+ flex-direction: row-reverse;
+}
+
+.#{$namespace}-justify-content-flex-start {
+ justify-content: flex-start;
+}
+.#{$namespace}-justify-content-center {
+ justify-content: center;
+}
+.#{$namespace}-justify-content-flex-end {
+ justify-content: flex-end;
+}
+
+.#{$namespace}-justify-content-space-around {
+ justify-content: space-around;
+}
+.#{$namespace}-justify-content-space-between {
+ justify-content: space-between;
+}
+.#{$namespace}-justify-content-space-evenly {
+ justify-content: space-evenly;
+}
+
+.#{$namespace}-align-items-stretch {
+ align-items: stretch;
+}
+.#{$namespace}-align-items-flex-start {
+ align-items: flex-start;
+}
+.#{$namespace}-align-items-flex-end {
+ align-items: flex-end;
+}
+.#{$namespace}-align-items-center {
+ align-items: center;
+}
+.#{$namespace}-align-items-baseline {
+ align-items: baseline;
+}
+
+.#{$namespace}-col {
+ box-sizing: border-box;
+ flex: 1;
+ display: flex;
+}
+
+.flex-none {
+ flex-grow: 0;
+ flex-shrink: 0;
+ flex-basis: auto;
+}
+
+/*
+ * 小程序不支持此选择器
+ * 目的:为插入到slot中的选择器,设置默认样式
+ * 此处为了实现所有列等高,tea-col设置为flex,所以插入的内容必须要声明flex:1属性
+
+::slotted(view) {
+ background: pink;
+ flex: 1;
+} */
+
+:host {
+ box-sizing: border-box;
+ flex-grow: 1;
+ flex-shrink: 0;
+ flex-basis: 0;
+ max-width: 100%;
+ display: flex;
+}
+
+:host(.start) {
+ flex-grow: 0;
+ flex-shrink: 0;
+ flex-basis: auto;
+ align-items: center;
+}
+:host(.center) {
+ flex-grow: 0;
+ flex-shrink: 0;
+ flex-basis: auto;
+
+ align-items: center;
+}
+:host(.end) {
+ flex-grow: 0;
+ flex-shrink: 0;
+ flex-basis: auto;
+
+ align-items: center;
+}
+
+/* cols */
+.col-1,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9,
+.col-10,
+.col-11,
+.col-12 {
+ flex-grow: 0;
+ flex-shrink: 0;
+ flex-basis: auto;
+}
+
+.col-1 {
+ flex-basis: 8.33333333%;
+ max-width: 8.33333333%;
+}
+
+.col-2 {
+ flex-basis: 16.66666667%;
+ max-width: 16.66666667%;
+}
+
+.col-3 {
+ flex-basis: 25%;
+ max-width: 25%;
+}
+
+.col-4 {
+ flex-basis: 33.33333333%;
+ max-width: 33.33333333%;
+}
+
+.col-5 {
+ flex-basis: 41.66666667%;
+ max-width: 41.66666667%;
+}
+
+.col-6 {
+ flex-basis: 50%;
+ max-width: 50%;
+}
+
+.col-7 {
+ flex-basis: 58.33333333%;
+ max-width: 58.33333333%;
+}
+
+.col-8 {
+ flex-basis: 66.66666667%;
+ max-width: 66.66666667%;
+}
+
+.col-9 {
+ flex-basis: 75%;
+ max-width: 75%;
+}
+
+.col-10 {
+ flex-basis: 83.33333333%;
+ max-width: 83.33333333%;
+}
+
+.col-11 {
+ flex-basis: 91.66666667%;
+ max-width: 91.66666667%;
+}
+
+.col-12 {
+ flex-basis: 100%;
+ max-width: 100%;
+}
+
+/* Offsets */
+.col-offset-1 {
+ margin-left: 8.33333333%;
+}
+
+.col-offset-2 {
+ margin-left: 16.66666667%;
+}
+
+.col-offset-3 {
+ margin-left: 25%;
+}
+
+.col-offset-4 {
+ margin-left: 33.33333333%;
+}
+
+.col-offset-5 {
+ margin-left: 41.66666667%;
+}
+
+.col-offset-6 {
+ margin-left: 50%;
+}
+
+.col-offset-7 {
+ margin-left: 58.33333333%;
+}
+
+.col-offset-8 {
+ margin-left: 66.66666667%;
+}
+
+.col-offset-9 {
+ margin-left: 75%;
+}
+
+.col-offset-10 {
+ margin-left: 83.33333333%;
+}
+
+.col-offset-11 {
+ margin-left: 91.66666667%;
+}
+
+/* align */
+.#{$namespace}-align-self-stretch {
+ align-self: stretch;
+}
+.#{$namespace}-align-self-flex-start {
+ align-self: flex-start;
+}
+.#{$namespace}-align-self-flex-end {
+ align-self: flex-end;
+}
+.#{$namespace}-align-self-center {
+ align-self: center;
+}
+.#{$namespace}-align-self-baseline {
+ align-self: baseline;
+}
diff --git a/packages/discuz-design/components/index.ts b/packages/discuz-design/components/index.ts
index 39edee032fb99d2d431a16174d590a99baa2fdbc..ee4401f546e150e494645b749989bb8435c7360e 100644
--- a/packages/discuz-design/components/index.ts
+++ b/packages/discuz-design/components/index.ts
@@ -5,3 +5,4 @@ export * as Dialog from './dialog';
export * as Card from './card';
export * as ScrollView from './scrollView';
export * as Toast from './Toast';
+export * as Flex from './flex';
\ No newline at end of file
diff --git a/packages/discuz-design/site/mini/src/app.config.js b/packages/discuz-design/site/mini/src/app.config.js
index 879ac02fb7581a07efeb1c99631efe50e9b6c964..c1bcab924c9600be66eb34d28ef3db225e252378 100644
--- a/packages/discuz-design/site/mini/src/app.config.js
+++ b/packages/discuz-design/site/mini/src/app.config.js
@@ -10,7 +10,8 @@ export default {
'pages/scrollView/normalList/index',
'pages/scrollView/renderBottom/index',
'pages/scrollView/virtualList/index',
- 'pages/toast/index'
+ 'pages/toast/index',
+ 'pages/flex/index'
],
window: {
backgroundTextStyle: 'light',
diff --git a/packages/discuz-design/site/mini/src/app.scss b/packages/discuz-design/site/mini/src/app.scss
index a7c08c781bfb2c413fed9888175ba771f11111fc..6e07f5d403eaa643e1cfdb6f1b259eda1a42b014 100644
--- a/packages/discuz-design/site/mini/src/app.scss
+++ b/packages/discuz-design/site/mini/src/app.scss
@@ -1,2 +1,3 @@
@import '../../../styles/index.scss';
-@import '../../../components/scrollView/__examples__/mini/index.scss';
\ No newline at end of file
+@import '../../../components/scrollView/__examples__/mini/index.scss';
+@import '../../../components/flex/__examples__/mini/index.scss';
\ No newline at end of file
diff --git a/packages/discuz-design/site/mini/src/componentList.json b/packages/discuz-design/site/mini/src/componentList.json
index f5884c3cdab2af28e64e625b2660e342c564a897..0a097e7d2b494a23d09aa0e6b8ecdc30ac9e4a06 100644
--- a/packages/discuz-design/site/mini/src/componentList.json
+++ b/packages/discuz-design/site/mini/src/componentList.json
@@ -20,6 +20,9 @@
},
"toast": {
"url": "toast"
+ },
+ "flex": {
+ "url": "flex"
}
}
}
\ No newline at end of file
diff --git a/packages/discuz-design/site/mini/src/pages/flex/index.config.js b/packages/discuz-design/site/mini/src/pages/flex/index.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..062986bdf139532541e1d8eedfa95a7ae28b0c40
--- /dev/null
+++ b/packages/discuz-design/site/mini/src/pages/flex/index.config.js
@@ -0,0 +1,3 @@
+export default {
+ navigationBarTitleText: 'scrollView'
+}
diff --git a/packages/discuz-design/site/mini/src/pages/flex/index.jsx b/packages/discuz-design/site/mini/src/pages/flex/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..7c9f5afedd502760491885b40e948938e7a4acec
--- /dev/null
+++ b/packages/discuz-design/site/mini/src/pages/flex/index.jsx
@@ -0,0 +1,22 @@
+import React, { Component } from "react";
+import Taro from '@tarojs/taro';
+import { View, Button } from "@tarojs/components";
+import Flex from "../../../../../components/flex/__examples__/mini/index";
+
+export default class Index extends Component {
+ componentWillMount() {}
+
+ componentDidMount() {}
+
+ componentWillUnmount() {}
+
+ componentDidShow() {}
+
+ componentDidHide() {}
+
+ render() {
+ return (
+
+ );
+ }
+}
diff --git a/packages/discuz-design/site/web/pages/flex.js b/packages/discuz-design/site/web/pages/flex.js
new file mode 100644
index 0000000000000000000000000000000000000000..4cfcf087a4e9de8229dbbbf21fe32e109f597949
--- /dev/null
+++ b/packages/discuz-design/site/web/pages/flex.js
@@ -0,0 +1,11 @@
+import React from 'react';
+import Flex from '../../../components/flex/__examples__/web/index';
+import '../../../components/flex/__examples__/web/index.scss';
+
+function Preview() {
+ return (
+
+ );
+}
+
+export default Preview;
\ No newline at end of file
diff --git a/packages/discuz-design/styles/index.scss b/packages/discuz-design/styles/index.scss
index 4ed3736b9ae11b33f24b7ee9b5af9f251a7577c0..2dc43bd56ac721ee8da087000f1b542b5e22b565 100644
--- a/packages/discuz-design/styles/index.scss
+++ b/packages/discuz-design/styles/index.scss
@@ -6,6 +6,7 @@
@import '../components/dialog/styles/index.scss';
@import '../components/card/styles/index.scss';
@import '../components/toast/styles/index.scss';
+@import '../components/flex/styles/index.scss';
page,
[data-dzq-theme='light'] {