deepsea-components 3.0.0 → 3.0.2-beta.20240527145411

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.
@@ -1,4 +1,4 @@
1
- import { CSSProperties, HTMLAttributes, ReactNode } from "react";
1
+ import { CSSProperties, HTMLAttributes, Key, ReactNode } from "react";
2
2
  export interface FlowSizeData {
3
3
  /** 容器宽度 */
4
4
  width: number;
@@ -37,9 +37,13 @@ export interface FlowProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, "chil
37
37
  /** 源数据 */
38
38
  data: T[];
39
39
  /** 渲染 */
40
- render: (item: T, index: number, hidden: boolean) => ReactNode;
40
+ render: (item: T, index: number, arr: T[]) => ReactNode;
41
41
  /** key释放器,默认为 index */
42
- keyExactor?: (item: T, index: number) => string | number;
42
+ keyExactor?: (item: T, index: number, arr: T[]) => Key;
43
+ /** 容器类名 */
44
+ wrapperClassName?: string;
45
+ /** 容器样式 */
46
+ wrapperStyle?: CSSProperties;
43
47
  /** 容器类名 */
44
48
  containerClassName?: string;
45
49
  /** 容器样式 */
@@ -25,7 +25,10 @@ __export(Flow_exports, {
25
25
  getGapRange: () => getGapRange
26
26
  });
27
27
  module.exports = __toCommonJS(Flow_exports);
28
+ var import_css = require("@emotion/css");
29
+ var import_deepsea_tools = require("deepsea-tools");
28
30
  var import_react = require("react");
31
+ var import_utils = require("../utils");
29
32
  function getGapRange(gap) {
30
33
  if (typeof gap === "number")
31
34
  return [gap, gap];
@@ -45,7 +48,7 @@ function getGapCountAndSize(width, itemWidth, minGap, maxGap) {
45
48
  return [count, averageGap];
46
49
  }
47
50
  function Flow(props) {
48
- const { itemWidth, itemHeight, columnGap, rowGap = 0, maxRows, data, render, keyExactor, className, style, containerClassName, containerStyle, throttle, transitionDuration, onSizeChange, ...rest } = props;
51
+ const { itemWidth, itemHeight, columnGap, rowGap = 0, maxRows, data, render, keyExactor, className, style, wrapperClassName, wrapperStyle, throttle, transitionDuration, onSizeChange, containerClassName, containerStyle, ...rest } = props;
49
52
  const [minColumnGap, maxColumnGap] = getGapRange(columnGap);
50
53
  const [width, setWidth] = (0, import_react.useState)(0);
51
54
  const [columnCount, setColumnCount] = (0, import_react.useState)(1);
@@ -94,21 +97,63 @@ function Flow(props) {
94
97
  (0, import_react.useEffect)(() => {
95
98
  onSizeChange?.({ width, height, itemWidth, itemHeight, columnGap: columnGapSize, columnCount, rowGap, rowCount: contentShownRows, overflow: data.length > contentShownRows * columnCount, itemCount: data.length, maxRows: maxRows ?? null });
96
99
  }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows]);
97
- return /* @__PURE__ */ React.createElement("div", { ref: ele, className, style: { position: "relative", boxSizing: "border-box", height, ...style }, ...rest }, showItems && data.map((item, index) => /* @__PURE__ */ React.createElement(
100
+ return /* @__PURE__ */ React.createElement(
98
101
  "div",
99
102
  {
100
- key: keyExactor ? keyExactor(item, index) : index,
101
- className: containerClassName,
102
- style: {
103
- position: "absolute",
104
- width: itemWidth,
105
- height: itemHeight,
106
- transition: transitionDuration !== null ? `all ${transitionDuration ?? 400}ms` : void 0,
107
- ...getPosition(index)
108
- }
103
+ ref: ele,
104
+ className: (0, import_deepsea_tools.clsx)(
105
+ import_css.css`
106
+ position: relative;
107
+ height: var(--height);
108
+ overflow: hidden;
109
+ `,
110
+ className
111
+ ),
112
+ style: (0, import_utils.styleWithCSSVariable)({ "--height": (0, import_utils.px)(height) }),
113
+ ...rest
109
114
  },
110
- /* @__PURE__ */ React.createElement("div", { style: { width: itemWidth, height: itemHeight, display: maxRows && index >= maxRows * columnCount ? "none" : "block", ...containerStyle } }, render(item, index, getHidden(index)))
111
- )));
115
+ showItems && data.map((item, index, arr) => /* @__PURE__ */ React.createElement(
116
+ "div",
117
+ {
118
+ key: keyExactor ? keyExactor(item, index, arr) : index,
119
+ className: (0, import_deepsea_tools.clsx)(
120
+ import_css.css`
121
+ position: absolute;
122
+ width: var(--width);
123
+ height: var(--height);
124
+ transition: var(--transition);
125
+ left: 0;
126
+ top: 0;
127
+ transform: translate(var(--left), var(--top));
128
+ `,
129
+ wrapperClassName
130
+ ),
131
+ style: (0, import_utils.styleWithCSSVariable)({
132
+ "--width": (0, import_utils.px)(itemWidth),
133
+ "--height": (0, import_utils.px)(itemHeight),
134
+ "--transition": transitionDuration === null ? "none" : `all ${transitionDuration || 400}ms`,
135
+ "--left": (0, import_utils.px)(getPosition(index).left),
136
+ "--top": (0, import_utils.px)(getPosition(index).top),
137
+ ...wrapperStyle
138
+ })
139
+ },
140
+ /* @__PURE__ */ React.createElement(
141
+ "div",
142
+ {
143
+ className: (0, import_deepsea_tools.clsx)(
144
+ import_css.css`
145
+ width: 100%;
146
+ height: 100%;
147
+ display: var(--display);
148
+ `,
149
+ containerClassName
150
+ ),
151
+ style: (0, import_utils.styleWithCSSVariable)({ "--display": getHidden(index) ? "none" : "block", ...containerStyle })
152
+ },
153
+ render(item, index, arr)
154
+ )
155
+ ))
156
+ );
112
157
  }
113
158
  // Annotate the CommonJS export names for ESM import in node:
114
159
  0 && (module.exports = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/Flow.tsx"],
4
- "sourcesContent": ["\"use client\"\r\n\r\nimport { CSSProperties, HTMLAttributes, ReactNode, useEffect, useRef, useState } from \"react\"\r\n\r\nexport interface FlowSizeData {\r\n /** 容器宽度 */\r\n width: number\r\n /** 容器高度 */\r\n height: number\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap: number\r\n /** 列数 */\r\n columnCount: number\r\n /** 行间距 */\r\n rowGap: number\r\n /** 行数 */\r\n rowCount: number\r\n /** 元素格数 */\r\n itemCount: number\r\n /** 最大行数 */\r\n maxRows: number | null\r\n /** 是否有元素被隐藏 */\r\n overflow: boolean\r\n}\r\n\r\nexport interface FlowProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap?: number | null | (number | null)[]\r\n /** 行间距 */\r\n rowGap?: number\r\n /** 最大行数 */\r\n maxRows?: number | null\r\n /** 源数据 */\r\n data: T[]\r\n /** 渲染 */\r\n render: (item: T, index: number, hidden: boolean) => ReactNode\r\n /** key释放器,默认为 index */\r\n keyExactor?: (item: T, index: number) => string | number\r\n /** 容器类名 */\r\n containerClassName?: string\r\n /** 容器样式 */\r\n containerStyle?: CSSProperties\r\n /** 节流时间,单位毫秒,默认200ms,传入 null 不节流 */\r\n throttle?: number | null\r\n /** 动画时间,单位毫秒,默认400ms,传入 null 不展示动画 */\r\n transitionDuration?: number | null\r\n /** 变化的回调函数 */\r\n onSizeChange?: (sizeData: FlowSizeData) => void\r\n}\r\n\r\nexport function getGapRange(gap?: undefined | number | null | (number | null)[]): [number, number | null] {\r\n if (typeof gap === \"number\") return [gap, gap]\r\n if (Array.isArray(gap)) return [gap[0] || 0, gap[1]]\r\n return [0, null]\r\n}\r\n\r\nexport function getGapCountAndSize(width: number, itemWidth: number, minGap: number, maxGap: number | null): [number, number] {\r\n const count = Math.floor((width + minGap) / (itemWidth + minGap)) || 1\r\n if (count === 1) return [count, 0]\r\n const averageGap = (width - itemWidth * count) / (count - 1)\r\n if (averageGap < minGap) return [count, minGap]\r\n if (maxGap !== null && averageGap > maxGap) return [count, maxGap]\r\n return [count, averageGap]\r\n}\r\n\r\ninterface Position {\r\n left: number\r\n top: number\r\n}\r\n\r\n/** 自适应浮动组件 */\r\nexport function Flow<T>(props: FlowProps<T>) {\r\n const { itemWidth, itemHeight, columnGap, rowGap = 0, maxRows, data, render, keyExactor, className, style, containerClassName, containerStyle, throttle, transitionDuration, onSizeChange, ...rest } = props\r\n const [minColumnGap, maxColumnGap] = getGapRange(columnGap)\r\n const [width, setWidth] = useState(0)\r\n const [columnCount, setColumnCount] = useState(1)\r\n const [columnGapSize, setColumnGapSize] = useState(minColumnGap)\r\n const [showItems, setShowItems] = useState(false)\r\n const ele = useRef<HTMLDivElement>(null)\r\n const contentRows = Math.ceil(data.length / columnCount)\r\n const contentShownRows = typeof maxRows === \"number\" ? Math.min(contentRows, maxRows) : contentRows\r\n const height = contentShownRows > 0 ? contentShownRows * (itemHeight + rowGap) - rowGap : 0\r\n\r\n function getPosition(index: number): Position {\r\n const y = Math.floor(index / columnCount)\r\n const x = index - y * columnCount\r\n return {\r\n left: x * (itemWidth + columnGapSize),\r\n top: y * (itemHeight + rowGap)\r\n }\r\n }\r\n\r\n function getHidden(index: number) {\r\n if (typeof maxRows !== \"number\") return false\r\n return index >= maxRows * columnCount\r\n }\r\n\r\n useEffect(() => {\r\n let timeout: number\r\n const observer = new ResizeObserver(entries => {\r\n clearTimeout(timeout)\r\n function task() {\r\n const { width } = entries[0].contentRect\r\n const [newColumnCount, newColumnGapSize] = getGapCountAndSize(width, itemWidth, minColumnGap, maxColumnGap)\r\n setShowItems(true)\r\n setWidth(width)\r\n setColumnCount(newColumnCount)\r\n setColumnGapSize(newColumnGapSize)\r\n }\r\n if (throttle === null) {\r\n task()\r\n } else {\r\n timeout = window.setTimeout(task, throttle || 200)\r\n }\r\n })\r\n observer.observe(ele.current!)\r\n\r\n return () => {\r\n observer.disconnect()\r\n }\r\n }, [itemWidth, throttle, columnGap])\r\n\r\n useEffect(() => {\r\n onSizeChange?.({ width, height, itemWidth, itemHeight, columnGap: columnGapSize, columnCount, rowGap, rowCount: contentShownRows, overflow: data.length > contentShownRows * columnCount, itemCount: data.length, maxRows: maxRows ?? null })\r\n }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows])\r\n\r\n return (\r\n <div ref={ele} className={className} style={{ position: \"relative\", boxSizing: \"border-box\", height, ...style }} {...rest}>\r\n {showItems &&\r\n data.map((item, index) => (\r\n <div\r\n key={keyExactor ? keyExactor(item, index) : index}\r\n className={containerClassName}\r\n style={{\r\n position: \"absolute\",\r\n width: itemWidth,\r\n height: itemHeight,\r\n transition: transitionDuration !== null ? `all ${transitionDuration ?? 400}ms` : undefined,\r\n ...getPosition(index)\r\n }}>\r\n <div style={{ width: itemWidth, height: itemHeight, display: maxRows && index >= maxRows * columnCount ? \"none\" : \"block\", ...containerStyle }}>{render(item, index, getHidden(index))}</div>\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n}\r\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAAsF;AAwD/E,SAAS,YAAY,KAA8E;AACtG,MAAI,OAAO,QAAQ;AAAU,WAAO,CAAC,KAAK,GAAG;AAC7C,MAAI,MAAM,QAAQ,GAAG;AAAG,WAAO,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;AACnD,SAAO,CAAC,GAAG,IAAI;AACnB;AAEO,SAAS,mBAAmB,OAAe,WAAmB,QAAgB,QAAyC;AAC1H,QAAM,QAAQ,KAAK,OAAO,QAAQ,WAAW,YAAY,OAAO,KAAK;AACrE,MAAI,UAAU;AAAG,WAAO,CAAC,OAAO,CAAC;AACjC,QAAM,cAAc,QAAQ,YAAY,UAAU,QAAQ;AAC1D,MAAI,aAAa;AAAQ,WAAO,CAAC,OAAO,MAAM;AAC9C,MAAI,WAAW,QAAQ,aAAa;AAAQ,WAAO,CAAC,OAAO,MAAM;AACjE,SAAO,CAAC,OAAO,UAAU;AAC7B;AAQO,SAAS,KAAQ,OAAqB;AACzC,QAAM,EAAE,WAAW,YAAY,WAAW,SAAS,GAAG,SAAS,MAAM,QAAQ,YAAY,WAAW,OAAO,oBAAoB,gBAAgB,UAAU,oBAAoB,cAAc,GAAG,KAAK,IAAI;AACvM,QAAM,CAAC,cAAc,YAAY,IAAI,YAAY,SAAS;AAC1D,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,CAAC;AACpC,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,CAAC;AAChD,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAS,YAAY;AAC/D,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAChD,QAAM,UAAM,qBAAuB,IAAI;AACvC,QAAM,cAAc,KAAK,KAAK,KAAK,SAAS,WAAW;AACvD,QAAM,mBAAmB,OAAO,YAAY,WAAW,KAAK,IAAI,aAAa,OAAO,IAAI;AACxF,QAAM,SAAS,mBAAmB,IAAI,oBAAoB,aAAa,UAAU,SAAS;AAE1F,WAAS,YAAY,OAAyB;AAC1C,UAAM,IAAI,KAAK,MAAM,QAAQ,WAAW;AACxC,UAAM,IAAI,QAAQ,IAAI;AACtB,WAAO;AAAA,MACH,MAAM,KAAK,YAAY;AAAA,MACvB,KAAK,KAAK,aAAa;AAAA,IAC3B;AAAA,EACJ;AAEA,WAAS,UAAU,OAAe;AAC9B,QAAI,OAAO,YAAY;AAAU,aAAO;AACxC,WAAO,SAAS,UAAU;AAAA,EAC9B;AAEA,8BAAU,MAAM;AACZ,QAAI;AACJ,UAAM,WAAW,IAAI,eAAe,aAAW;AAC3C,mBAAa,OAAO;AACpB,eAAS,OAAO;AACZ,cAAM,EAAE,OAAAA,OAAM,IAAI,QAAQ,CAAC,EAAE;AAC7B,cAAM,CAAC,gBAAgB,gBAAgB,IAAI,mBAAmBA,QAAO,WAAW,cAAc,YAAY;AAC1G,qBAAa,IAAI;AACjB,iBAASA,MAAK;AACd,uBAAe,cAAc;AAC7B,yBAAiB,gBAAgB;AAAA,MACrC;AACA,UAAI,aAAa,MAAM;AACnB,aAAK;AAAA,MACT,OAAO;AACH,kBAAU,OAAO,WAAW,MAAM,YAAY,GAAG;AAAA,MACrD;AAAA,IACJ,CAAC;AACD,aAAS,QAAQ,IAAI,OAAQ;AAE7B,WAAO,MAAM;AACT,eAAS,WAAW;AAAA,IACxB;AAAA,EACJ,GAAG,CAAC,WAAW,UAAU,SAAS,CAAC;AAEnC,8BAAU,MAAM;AACZ,mBAAe,EAAE,OAAO,QAAQ,WAAW,YAAY,WAAW,eAAe,aAAa,QAAQ,UAAU,kBAAkB,UAAU,KAAK,SAAS,mBAAmB,aAAa,WAAW,KAAK,QAAQ,SAAS,WAAW,KAAK,CAAC;AAAA,EAChP,GAAG,CAAC,OAAO,QAAQ,eAAe,aAAa,QAAQ,kBAAkB,KAAK,QAAQ,WAAW,YAAY,OAAO,CAAC;AAErH,SACI,oCAAC,SAAI,KAAK,KAAK,WAAsB,OAAO,EAAE,UAAU,YAAY,WAAW,cAAc,QAAQ,GAAG,MAAM,GAAI,GAAG,QAChH,aACG,KAAK,IAAI,CAAC,MAAM,UACZ;AAAA,IAAC;AAAA;AAAA,MACG,KAAK,aAAa,WAAW,MAAM,KAAK,IAAI;AAAA,MAC5C,WAAW;AAAA,MACX,OAAO;AAAA,QACH,UAAU;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,YAAY,uBAAuB,OAAO,OAAO,sBAAsB,UAAU;AAAA,QACjF,GAAG,YAAY,KAAK;AAAA,MACxB;AAAA;AAAA,IACA,oCAAC,SAAI,OAAO,EAAE,OAAO,WAAW,QAAQ,YAAY,SAAS,WAAW,SAAS,UAAU,cAAc,SAAS,SAAS,GAAG,eAAe,KAAI,OAAO,MAAM,OAAO,UAAU,KAAK,CAAC,CAAE;AAAA,EAC3L,CACH,CACT;AAER;",
4
+ "sourcesContent": ["\"use client\"\r\n\r\nimport { css } from \"@emotion/css\"\r\nimport { clsx } from \"deepsea-tools\"\r\nimport { CSSProperties, HTMLAttributes, Key, ReactNode, useEffect, useRef, useState } from \"react\"\r\nimport { px, styleWithCSSVariable } from \"../utils\"\r\n\r\nexport interface FlowSizeData {\r\n /** 容器宽度 */\r\n width: number\r\n /** 容器高度 */\r\n height: number\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap: number\r\n /** 列数 */\r\n columnCount: number\r\n /** 行间距 */\r\n rowGap: number\r\n /** 行数 */\r\n rowCount: number\r\n /** 元素格数 */\r\n itemCount: number\r\n /** 最大行数 */\r\n maxRows: number | null\r\n /** 是否有元素被隐藏 */\r\n overflow: boolean\r\n}\r\n\r\nexport interface FlowProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap?: number | null | (number | null)[]\r\n /** 行间距 */\r\n rowGap?: number\r\n /** 最大行数 */\r\n maxRows?: number | null\r\n /** 源数据 */\r\n data: T[]\r\n /** 渲染 */\r\n render: (item: T, index: number, arr: T[]) => ReactNode\r\n /** key释放器,默认为 index */\r\n keyExactor?: (item: T, index: number, arr: T[]) => Key\r\n /** 容器类名 */\r\n wrapperClassName?: string\r\n /** 容器样式 */\r\n wrapperStyle?: CSSProperties\r\n /** 容器类名 */\r\n containerClassName?: string\r\n /** 容器样式 */\r\n containerStyle?: CSSProperties\r\n /** 节流时间,单位毫秒,默认200ms,传入 null 不节流 */\r\n throttle?: number | null\r\n /** 动画时间,单位毫秒,默认400ms,传入 null 不展示动画 */\r\n transitionDuration?: number | null\r\n /** 变化的回调函数 */\r\n onSizeChange?: (sizeData: FlowSizeData) => void\r\n}\r\n\r\nexport function getGapRange(gap?: undefined | number | null | (number | null)[]): [number, number | null] {\r\n if (typeof gap === \"number\") return [gap, gap]\r\n if (Array.isArray(gap)) return [gap[0] || 0, gap[1]]\r\n return [0, null]\r\n}\r\n\r\nexport function getGapCountAndSize(width: number, itemWidth: number, minGap: number, maxGap: number | null): [number, number] {\r\n const count = Math.floor((width + minGap) / (itemWidth + minGap)) || 1\r\n if (count === 1) return [count, 0]\r\n const averageGap = (width - itemWidth * count) / (count - 1)\r\n if (averageGap < minGap) return [count, minGap]\r\n if (maxGap !== null && averageGap > maxGap) return [count, maxGap]\r\n return [count, averageGap]\r\n}\r\n\r\ninterface Position {\r\n left: number\r\n top: number\r\n}\r\n\r\n/** 自适应浮动组件 */\r\nexport function Flow<T>(props: FlowProps<T>) {\r\n const { itemWidth, itemHeight, columnGap, rowGap = 0, maxRows, data, render, keyExactor, className, style, wrapperClassName, wrapperStyle, throttle, transitionDuration, onSizeChange, containerClassName, containerStyle, ...rest } = props\r\n const [minColumnGap, maxColumnGap] = getGapRange(columnGap)\r\n const [width, setWidth] = useState(0)\r\n const [columnCount, setColumnCount] = useState(1)\r\n const [columnGapSize, setColumnGapSize] = useState(minColumnGap)\r\n const [showItems, setShowItems] = useState(false)\r\n const ele = useRef<HTMLDivElement>(null)\r\n const contentRows = Math.ceil(data.length / columnCount)\r\n const contentShownRows = typeof maxRows === \"number\" ? Math.min(contentRows, maxRows) : contentRows\r\n const height = contentShownRows > 0 ? contentShownRows * (itemHeight + rowGap) - rowGap : 0\r\n\r\n function getPosition(index: number): Position {\r\n const y = Math.floor(index / columnCount)\r\n const x = index - y * columnCount\r\n return {\r\n left: x * (itemWidth + columnGapSize),\r\n top: y * (itemHeight + rowGap)\r\n }\r\n }\r\n\r\n function getHidden(index: number) {\r\n if (typeof maxRows !== \"number\") return false\r\n return index >= maxRows * columnCount\r\n }\r\n\r\n useEffect(() => {\r\n let timeout: number\r\n const observer = new ResizeObserver(entries => {\r\n clearTimeout(timeout)\r\n function task() {\r\n const { width } = entries[0].contentRect\r\n const [newColumnCount, newColumnGapSize] = getGapCountAndSize(width, itemWidth, minColumnGap, maxColumnGap)\r\n setShowItems(true)\r\n setWidth(width)\r\n setColumnCount(newColumnCount)\r\n setColumnGapSize(newColumnGapSize)\r\n }\r\n if (throttle === null) {\r\n task()\r\n } else {\r\n timeout = window.setTimeout(task, throttle || 200)\r\n }\r\n })\r\n observer.observe(ele.current!)\r\n\r\n return () => {\r\n observer.disconnect()\r\n }\r\n }, [itemWidth, throttle, columnGap])\r\n\r\n useEffect(() => {\r\n onSizeChange?.({ width, height, itemWidth, itemHeight, columnGap: columnGapSize, columnCount, rowGap, rowCount: contentShownRows, overflow: data.length > contentShownRows * columnCount, itemCount: data.length, maxRows: maxRows ?? null })\r\n }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows])\r\n\r\n return (\r\n <div\r\n ref={ele}\r\n className={clsx(\r\n css`\r\n position: relative;\r\n height: var(--height);\r\n overflow: hidden;\r\n `,\r\n className\r\n )}\r\n style={styleWithCSSVariable({ \"--height\": px(height) })}\r\n {...rest}>\r\n {showItems &&\r\n data.map((item, index, arr) => (\r\n <div\r\n key={keyExactor ? keyExactor(item, index, arr) : index}\r\n className={clsx(\r\n css`\r\n position: absolute;\r\n width: var(--width);\r\n height: var(--height);\r\n transition: var(--transition);\r\n left: 0;\r\n top: 0;\r\n transform: translate(var(--left), var(--top));\r\n `,\r\n wrapperClassName\r\n )}\r\n style={styleWithCSSVariable({\r\n \"--width\": px(itemWidth),\r\n \"--height\": px(itemHeight),\r\n \"--transition\": transitionDuration === null ? \"none\" : `all ${transitionDuration || 400}ms`,\r\n \"--left\": px(getPosition(index).left),\r\n \"--top\": px(getPosition(index).top),\r\n ...wrapperStyle\r\n })}>\r\n <div\r\n className={clsx(\r\n css`\r\n width: 100%;\r\n height: 100%;\r\n display: var(--display);\r\n `,\r\n containerClassName\r\n )}\r\n style={styleWithCSSVariable({ \"--display\": getHidden(index) ? \"none\" : \"block\", ...containerStyle })}>\r\n {render(item, index, arr)}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n}\r\n"],
5
+ "mappings": "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",
6
6
  "names": ["width"]
7
7
  }
@@ -0,0 +1,6 @@
1
+ import { MediaHTMLAttributes } from "react";
2
+ export interface HlsPlayerProps extends Omit<MediaHTMLAttributes<HTMLVideoElement>, "src"> {
3
+ src: string;
4
+ }
5
+ declare const HlsPlayer: import("react").ForwardRefExoticComponent<HlsPlayerProps & import("react").RefAttributes<HTMLVideoElement>>;
6
+ export default HlsPlayer;
@@ -0,0 +1,64 @@
1
+ "use client";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/components/HlsPlayer.tsx
31
+ var HlsPlayer_exports = {};
32
+ __export(HlsPlayer_exports, {
33
+ default: () => HlsPlayer_default
34
+ });
35
+ module.exports = __toCommonJS(HlsPlayer_exports);
36
+ var import_hls = __toESM(require("hls.js"));
37
+ var import_react = require("react");
38
+ var HlsPlayer = (0, import_react.forwardRef)((props, ref) => {
39
+ const { src, ...rest } = props;
40
+ const video = (0, import_react.useRef)(null);
41
+ (0, import_react.useImperativeHandle)(ref, () => video.current, []);
42
+ (0, import_react.useEffect)(() => {
43
+ const { current: player } = video;
44
+ if (!player || !src)
45
+ return;
46
+ if (player.canPlayType("application/vnd.apple.mpegurl")) {
47
+ player.src = src;
48
+ player.play();
49
+ return;
50
+ }
51
+ if (import_hls.default.isSupported()) {
52
+ const hls = new import_hls.default();
53
+ hls.loadSource(src);
54
+ hls.attachMedia(player);
55
+ player.play();
56
+ return () => {
57
+ hls.destroy();
58
+ };
59
+ }
60
+ }, [src]);
61
+ return /* @__PURE__ */ React.createElement("video", { ref: video, ...rest });
62
+ });
63
+ var HlsPlayer_default = HlsPlayer;
64
+ //# sourceMappingURL=HlsPlayer.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/components/HlsPlayer.tsx"],
4
+ "sourcesContent": ["\"use client\"\r\n\r\nimport Hls from \"hls.js\"\r\nimport { MediaHTMLAttributes, forwardRef, useEffect, useImperativeHandle, useRef } from \"react\"\r\n\r\nexport interface HlsPlayerProps extends Omit<MediaHTMLAttributes<HTMLVideoElement>, \"src\"> {\r\n src: string\r\n}\r\n\r\nconst HlsPlayer = forwardRef<HTMLVideoElement, HlsPlayerProps>((props, ref) => {\r\n const { src, ...rest } = props\r\n const video = useRef<HTMLVideoElement>(null)\r\n\r\n useImperativeHandle(ref, () => video.current!, [])\r\n\r\n useEffect(() => {\r\n const { current: player } = video\r\n if (!player || !src) return\r\n if (player.canPlayType(\"application/vnd.apple.mpegurl\")) {\r\n player.src = src\r\n player.play()\r\n return\r\n }\r\n if (Hls.isSupported()) {\r\n const hls = new Hls()\r\n hls.loadSource(src)\r\n hls.attachMedia(player)\r\n player.play()\r\n return () => {\r\n hls.destroy()\r\n }\r\n }\r\n }, [src])\r\n\r\n return <video ref={video} {...rest} />\r\n})\r\n\r\nexport default HlsPlayer\r\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAgB;AAChB,mBAAwF;AAMxF,IAAM,gBAAY,yBAA6C,CAAC,OAAO,QAAQ;AAC3E,QAAM,EAAE,KAAK,GAAG,KAAK,IAAI;AACzB,QAAM,YAAQ,qBAAyB,IAAI;AAE3C,wCAAoB,KAAK,MAAM,MAAM,SAAU,CAAC,CAAC;AAEjD,8BAAU,MAAM;AACZ,UAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,QAAI,CAAC,UAAU,CAAC;AAAK;AACrB,QAAI,OAAO,YAAY,+BAA+B,GAAG;AACrD,aAAO,MAAM;AACb,aAAO,KAAK;AACZ;AAAA,IACJ;AACA,QAAI,WAAAA,QAAI,YAAY,GAAG;AACnB,YAAM,MAAM,IAAI,WAAAA,QAAI;AACpB,UAAI,WAAW,GAAG;AAClB,UAAI,YAAY,MAAM;AACtB,aAAO,KAAK;AACZ,aAAO,MAAM;AACT,YAAI,QAAQ;AAAA,MAChB;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,GAAG,CAAC;AAER,SAAO,oCAAC,WAAM,KAAK,OAAQ,GAAG,MAAM;AACxC,CAAC;AAED,IAAO,oBAAQ;",
6
+ "names": ["Hls"]
7
+ }
@@ -26,11 +26,12 @@ module.exports = __toCommonJS(Skeleton_exports);
26
26
  var import_css = require("@emotion/css");
27
27
  var import_deepsea_tools = require("deepsea-tools");
28
28
  var import_react = require("react");
29
- var Skeleton = (0, import_react.forwardRef)((props) => {
29
+ var Skeleton = (0, import_react.forwardRef)((props, ref) => {
30
30
  const { className, ...rest } = props;
31
31
  return /* @__PURE__ */ React.createElement(
32
32
  "div",
33
33
  {
34
+ ref,
34
35
  className: (0, import_deepsea_tools.clsx)(
35
36
  import_css.css`
36
37
  @keyframes shimmer {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/Skeleton.tsx"],
4
- "sourcesContent": ["\"use client\"\r\n\r\nimport { css } from \"@emotion/css\"\r\nimport { clsx } from \"deepsea-tools\"\r\nimport { forwardRef, HTMLAttributes } from \"react\"\r\n\r\nconst Skeleton = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(props => {\r\n const { className, ...rest } = props\r\n\r\n return (\r\n <div\r\n className={clsx(\r\n css`\r\n @keyframes shimmer {\r\n 0% {\r\n background-position: -400px 0px;\r\n }\r\n 100% {\r\n background-position: 400px 0px;\r\n }\r\n }\r\n\r\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.067) 8%, rgba(0, 0, 0, 0.133) 18%, rgba(0, 0, 0, 0.067) 33%);\r\n animation-duration: 1s;\r\n animation-fill-mode: forwards;\r\n animation-iteration-count: infinite;\r\n animation-name: shimmer;\r\n animation-timing-function: linear;\r\n background-size: 800px 104px;\r\n `,\r\n className\r\n )}\r\n {...rest}\r\n />\r\n )\r\n})\r\n\r\nexport default Skeleton\r\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAoB;AACpB,2BAAqB;AACrB,mBAA2C;AAE3C,IAAM,eAAW,yBAA2D,WAAS;AACjF,QAAM,EAAE,WAAW,GAAG,KAAK,IAAI;AAE/B,SACI;AAAA,IAAC;AAAA;AAAA,MACG,eAAW;AAAA,QACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAkBA;AAAA,MACJ;AAAA,MACC,GAAG;AAAA;AAAA,EACR;AAER,CAAC;AAED,IAAO,mBAAQ;",
4
+ "sourcesContent": ["\"use client\"\r\n\r\nimport { css } from \"@emotion/css\"\r\nimport { clsx } from \"deepsea-tools\"\r\nimport { forwardRef, HTMLAttributes } from \"react\"\r\n\r\nconst Skeleton = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>((props, ref) => {\r\n const { className, ...rest } = props\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n className={clsx(\r\n css`\r\n @keyframes shimmer {\r\n 0% {\r\n background-position: -400px 0px;\r\n }\r\n 100% {\r\n background-position: 400px 0px;\r\n }\r\n }\r\n\r\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.067) 8%, rgba(0, 0, 0, 0.133) 18%, rgba(0, 0, 0, 0.067) 33%);\r\n animation-duration: 1s;\r\n animation-fill-mode: forwards;\r\n animation-iteration-count: infinite;\r\n animation-name: shimmer;\r\n animation-timing-function: linear;\r\n background-size: 800px 104px;\r\n `,\r\n className\r\n )}\r\n {...rest}\r\n />\r\n )\r\n})\r\n\r\nexport default Skeleton\r\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAoB;AACpB,2BAAqB;AACrB,mBAA2C;AAE3C,IAAM,eAAW,yBAA2D,CAAC,OAAO,QAAQ;AACxF,QAAM,EAAE,WAAW,GAAG,KAAK,IAAI;AAE/B,SACI;AAAA,IAAC;AAAA;AAAA,MACG;AAAA,MACA,eAAW;AAAA,QACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAkBA;AAAA,MACJ;AAAA,MACC,GAAG;AAAA;AAAA,EACR;AAER,CAAC;AAED,IAAO,mBAAQ;",
6
6
  "names": []
7
7
  }
@@ -3,6 +3,7 @@ export * from "./components/AutoScroll";
3
3
  export * from "./components/AutoSizeTextarea";
4
4
  export * from "./components/CircleText";
5
5
  export * from "./components/Flow";
6
+ export * from "./components/HlsPlayer";
6
7
  export * from "./components/InputFile";
7
8
  export * from "./components/LoopSwiper";
8
9
  export * from "./components/Ring";
package/dist/cjs/index.js CHANGED
@@ -21,6 +21,7 @@ __reExport(src_exports, require("./components/AutoScroll"), module.exports);
21
21
  __reExport(src_exports, require("./components/AutoSizeTextarea"), module.exports);
22
22
  __reExport(src_exports, require("./components/CircleText"), module.exports);
23
23
  __reExport(src_exports, require("./components/Flow"), module.exports);
24
+ __reExport(src_exports, require("./components/HlsPlayer"), module.exports);
24
25
  __reExport(src_exports, require("./components/InputFile"), module.exports);
25
26
  __reExport(src_exports, require("./components/LoopSwiper"), module.exports);
26
27
  __reExport(src_exports, require("./components/Ring"), module.exports);
@@ -37,6 +38,7 @@ __reExport(src_exports, require("./components/Trapezium"), module.exports);
37
38
  ...require("./components/AutoSizeTextarea"),
38
39
  ...require("./components/CircleText"),
39
40
  ...require("./components/Flow"),
41
+ ...require("./components/HlsPlayer"),
40
42
  ...require("./components/InputFile"),
41
43
  ...require("./components/LoopSwiper"),
42
44
  ...require("./components/Ring"),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.tsx"],
4
- "sourcesContent": ["export * from \"./components/AutoFit\"\r\nexport * from \"./components/AutoScroll\"\r\nexport * from \"./components/AutoSizeTextarea\"\r\nexport * from \"./components/CircleText\"\r\nexport * from \"./components/Flow\"\r\nexport * from \"./components/InputFile\"\r\nexport * from \"./components/LoopSwiper\"\r\nexport * from \"./components/Ring\"\r\nexport * from \"./components/Scroll\"\r\nexport * from \"./components/SectionRing\"\r\nexport * from \"./components/Skeleton\"\r\nexport * from \"./components/TransitionBox\"\r\nexport * from \"./components/TransitionNum\"\r\nexport * from \"./components/Trapezium\"\r\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,wBAAc,iCAAd;AACA,wBAAc,oCADd;AAEA,wBAAc,0CAFd;AAGA,wBAAc,oCAHd;AAIA,wBAAc,8BAJd;AAKA,wBAAc,mCALd;AAMA,wBAAc,oCANd;AAOA,wBAAc,8BAPd;AAQA,wBAAc,gCARd;AASA,wBAAc,qCATd;AAUA,wBAAc,kCAVd;AAWA,wBAAc,uCAXd;AAYA,wBAAc,uCAZd;AAaA,wBAAc,mCAbd;",
4
+ "sourcesContent": ["export * from \"./components/AutoFit\"\r\nexport * from \"./components/AutoScroll\"\r\nexport * from \"./components/AutoSizeTextarea\"\r\nexport * from \"./components/CircleText\"\r\nexport * from \"./components/Flow\"\r\nexport * from \"./components/HlsPlayer\"\r\nexport * from \"./components/InputFile\"\r\nexport * from \"./components/LoopSwiper\"\r\nexport * from \"./components/Ring\"\r\nexport * from \"./components/Scroll\"\r\nexport * from \"./components/SectionRing\"\r\nexport * from \"./components/Skeleton\"\r\nexport * from \"./components/TransitionBox\"\r\nexport * from \"./components/TransitionNum\"\r\nexport * from \"./components/Trapezium\"\r\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,wBAAc,iCAAd;AACA,wBAAc,oCADd;AAEA,wBAAc,0CAFd;AAGA,wBAAc,oCAHd;AAIA,wBAAc,8BAJd;AAKA,wBAAc,mCALd;AAMA,wBAAc,mCANd;AAOA,wBAAc,oCAPd;AAQA,wBAAc,8BARd;AASA,wBAAc,gCATd;AAUA,wBAAc,qCAVd;AAWA,wBAAc,kCAXd;AAYA,wBAAc,uCAZd;AAaA,wBAAc,uCAbd;AAcA,wBAAc,mCAdd;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,8 @@
1
+ import { CSSProperties } from "react";
2
+ export type CSSVariableName = `--${string}`;
3
+ export type CSSVariableValue = string | number;
4
+ export interface StyleWithCSSVariable extends CSSProperties {
5
+ [X: CSSVariableName]: CSSVariableValue;
6
+ }
7
+ export declare function styleWithCSSVariable(style: StyleWithCSSVariable): CSSProperties;
8
+ export declare function px(value: number): string;
@@ -0,0 +1,37 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/utils/index.ts
20
+ var utils_exports = {};
21
+ __export(utils_exports, {
22
+ px: () => px,
23
+ styleWithCSSVariable: () => styleWithCSSVariable
24
+ });
25
+ module.exports = __toCommonJS(utils_exports);
26
+ function styleWithCSSVariable(style) {
27
+ return style;
28
+ }
29
+ function px(value) {
30
+ return `${value}px`;
31
+ }
32
+ // Annotate the CommonJS export names for ESM import in node:
33
+ 0 && (module.exports = {
34
+ px,
35
+ styleWithCSSVariable
36
+ });
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/utils/index.ts"],
4
+ "sourcesContent": ["import { CSSProperties } from \"react\"\r\n\r\nexport type CSSVariableName = `--${string}`\r\n\r\nexport type CSSVariableValue = string | number\r\n\r\nexport interface StyleWithCSSVariable extends CSSProperties {\r\n [X: CSSVariableName]: CSSVariableValue\r\n}\r\n\r\nexport function styleWithCSSVariable(style: StyleWithCSSVariable): CSSProperties {\r\n return style\r\n}\r\n\r\nexport function px(value: number): string {\r\n return `${value}px`\r\n}"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUO,SAAS,qBAAqB,OAA4C;AAC7E,SAAO;AACX;AAEO,SAAS,GAAG,OAAuB;AACtC,SAAO,GAAG;AACd;",
6
+ "names": []
7
+ }
@@ -1,4 +1,4 @@
1
- import { CSSProperties, HTMLAttributes, ReactNode } from "react";
1
+ import { CSSProperties, HTMLAttributes, Key, ReactNode } from "react";
2
2
  export interface FlowSizeData {
3
3
  /** 容器宽度 */
4
4
  width: number;
@@ -37,9 +37,13 @@ export interface FlowProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, "chil
37
37
  /** 源数据 */
38
38
  data: T[];
39
39
  /** 渲染 */
40
- render: (item: T, index: number, hidden: boolean) => ReactNode;
40
+ render: (item: T, index: number, arr: T[]) => ReactNode;
41
41
  /** key释放器,默认为 index */
42
- keyExactor?: (item: T, index: number) => string | number;
42
+ keyExactor?: (item: T, index: number, arr: T[]) => Key;
43
+ /** 容器类名 */
44
+ wrapperClassName?: string;
45
+ /** 容器样式 */
46
+ wrapperStyle?: CSSProperties;
43
47
  /** 容器类名 */
44
48
  containerClassName?: string;
45
49
  /** 容器样式 */
@@ -1,6 +1,9 @@
1
1
  "use client";
2
2
 
3
+ import { css } from "@emotion/css";
4
+ import { clsx } from "deepsea-tools";
3
5
  import { useEffect, useRef, useState } from "react";
6
+ import { px, styleWithCSSVariable } from "../utils";
4
7
  import { jsx as _jsx } from "react/jsx-runtime";
5
8
  export function getGapRange(gap) {
6
9
  if (typeof gap === "number") return [gap, gap];
@@ -28,11 +31,13 @@ export function Flow(props) {
28
31
  keyExactor,
29
32
  className,
30
33
  style,
31
- containerClassName,
32
- containerStyle,
34
+ wrapperClassName,
35
+ wrapperStyle,
33
36
  throttle,
34
37
  transitionDuration,
35
38
  onSizeChange,
39
+ containerClassName,
40
+ containerStyle,
36
41
  ...rest
37
42
  } = props;
38
43
  const [minColumnGap, maxColumnGap] = getGapRange(columnGap);
@@ -98,33 +103,46 @@ export function Flow(props) {
98
103
  }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows]);
99
104
  return /*#__PURE__*/_jsx("div", {
100
105
  ref: ele,
101
- className: className,
102
- style: {
103
- position: "relative",
104
- boxSizing: "border-box",
105
- height,
106
- ...style
107
- },
106
+ className: clsx(css`
107
+ position: relative;
108
+ height: var(--height);
109
+ overflow: hidden;
110
+ `, className),
111
+ style: styleWithCSSVariable({
112
+ "--height": px(height)
113
+ }),
108
114
  ...rest,
109
- children: showItems && data.map((item, index) => /*#__PURE__*/_jsx("div", {
110
- className: containerClassName,
111
- style: {
112
- position: "absolute",
113
- width: itemWidth,
114
- height: itemHeight,
115
- transition: transitionDuration !== null ? `all ${transitionDuration ?? 400}ms` : undefined,
116
- ...getPosition(index)
117
- },
115
+ children: showItems && data.map((item, index, arr) => /*#__PURE__*/_jsx("div", {
116
+ className: clsx(css`
117
+ position: absolute;
118
+ width: var(--width);
119
+ height: var(--height);
120
+ transition: var(--transition);
121
+ left: 0;
122
+ top: 0;
123
+ transform: translate(var(--left), var(--top));
124
+ `, wrapperClassName),
125
+ style: styleWithCSSVariable({
126
+ "--width": px(itemWidth),
127
+ "--height": px(itemHeight),
128
+ "--transition": transitionDuration === null ? "none" : `all ${transitionDuration || 400}ms`,
129
+ "--left": px(getPosition(index).left),
130
+ "--top": px(getPosition(index).top),
131
+ ...wrapperStyle
132
+ }),
118
133
  children: /*#__PURE__*/_jsx("div", {
119
- style: {
120
- width: itemWidth,
121
- height: itemHeight,
122
- display: maxRows && index >= maxRows * columnCount ? "none" : "block",
134
+ className: clsx(css`
135
+ width: 100%;
136
+ height: 100%;
137
+ display: var(--display);
138
+ `, containerClassName),
139
+ style: styleWithCSSVariable({
140
+ "--display": getHidden(index) ? "none" : "block",
123
141
  ...containerStyle
124
- },
125
- children: render(item, index, getHidden(index))
142
+ }),
143
+ children: render(item, index, arr)
126
144
  })
127
- }, keyExactor ? keyExactor(item, index) : index))
145
+ }, keyExactor ? keyExactor(item, index, arr) : index))
128
146
  });
129
147
  }
130
148
  //# sourceMappingURL=Flow.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","useRef","useState","jsx","_jsx","getGapRange","gap","Array","isArray","getGapCountAndSize","width","itemWidth","minGap","maxGap","count","Math","floor","averageGap","Flow","props","itemHeight","columnGap","rowGap","maxRows","data","render","keyExactor","className","style","containerClassName","containerStyle","throttle","transitionDuration","onSizeChange","rest","minColumnGap","maxColumnGap","setWidth","columnCount","setColumnCount","columnGapSize","setColumnGapSize","showItems","setShowItems","ele","contentRows","ceil","length","contentShownRows","min","height","getPosition","index","y","x","left","top","getHidden","timeout","observer","ResizeObserver","entries","clearTimeout","task","contentRect","newColumnCount","newColumnGapSize","window","setTimeout","observe","current","disconnect","rowCount","overflow","itemCount","ref","position","boxSizing","children","map","item","transition","undefined","display"],"sources":["../../../src/components/Flow.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { CSSProperties, HTMLAttributes, ReactNode, useEffect, useRef, useState } from \"react\"\r\n\r\nexport interface FlowSizeData {\r\n /** 容器宽度 */\r\n width: number\r\n /** 容器高度 */\r\n height: number\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap: number\r\n /** 列数 */\r\n columnCount: number\r\n /** 行间距 */\r\n rowGap: number\r\n /** 行数 */\r\n rowCount: number\r\n /** 元素格数 */\r\n itemCount: number\r\n /** 最大行数 */\r\n maxRows: number | null\r\n /** 是否有元素被隐藏 */\r\n overflow: boolean\r\n}\r\n\r\nexport interface FlowProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap?: number | null | (number | null)[]\r\n /** 行间距 */\r\n rowGap?: number\r\n /** 最大行数 */\r\n maxRows?: number | null\r\n /** 源数据 */\r\n data: T[]\r\n /** 渲染 */\r\n render: (item: T, index: number, hidden: boolean) => ReactNode\r\n /** key释放器,默认为 index */\r\n keyExactor?: (item: T, index: number) => string | number\r\n /** 容器类名 */\r\n containerClassName?: string\r\n /** 容器样式 */\r\n containerStyle?: CSSProperties\r\n /** 节流时间,单位毫秒,默认200ms,传入 null 不节流 */\r\n throttle?: number | null\r\n /** 动画时间,单位毫秒,默认400ms,传入 null 不展示动画 */\r\n transitionDuration?: number | null\r\n /** 变化的回调函数 */\r\n onSizeChange?: (sizeData: FlowSizeData) => void\r\n}\r\n\r\nexport function getGapRange(gap?: undefined | number | null | (number | null)[]): [number, number | null] {\r\n if (typeof gap === \"number\") return [gap, gap]\r\n if (Array.isArray(gap)) return [gap[0] || 0, gap[1]]\r\n return [0, null]\r\n}\r\n\r\nexport function getGapCountAndSize(width: number, itemWidth: number, minGap: number, maxGap: number | null): [number, number] {\r\n const count = Math.floor((width + minGap) / (itemWidth + minGap)) || 1\r\n if (count === 1) return [count, 0]\r\n const averageGap = (width - itemWidth * count) / (count - 1)\r\n if (averageGap < minGap) return [count, minGap]\r\n if (maxGap !== null && averageGap > maxGap) return [count, maxGap]\r\n return [count, averageGap]\r\n}\r\n\r\ninterface Position {\r\n left: number\r\n top: number\r\n}\r\n\r\n/** 自适应浮动组件 */\r\nexport function Flow<T>(props: FlowProps<T>) {\r\n const { itemWidth, itemHeight, columnGap, rowGap = 0, maxRows, data, render, keyExactor, className, style, containerClassName, containerStyle, throttle, transitionDuration, onSizeChange, ...rest } = props\r\n const [minColumnGap, maxColumnGap] = getGapRange(columnGap)\r\n const [width, setWidth] = useState(0)\r\n const [columnCount, setColumnCount] = useState(1)\r\n const [columnGapSize, setColumnGapSize] = useState(minColumnGap)\r\n const [showItems, setShowItems] = useState(false)\r\n const ele = useRef<HTMLDivElement>(null)\r\n const contentRows = Math.ceil(data.length / columnCount)\r\n const contentShownRows = typeof maxRows === \"number\" ? Math.min(contentRows, maxRows) : contentRows\r\n const height = contentShownRows > 0 ? contentShownRows * (itemHeight + rowGap) - rowGap : 0\r\n\r\n function getPosition(index: number): Position {\r\n const y = Math.floor(index / columnCount)\r\n const x = index - y * columnCount\r\n return {\r\n left: x * (itemWidth + columnGapSize),\r\n top: y * (itemHeight + rowGap)\r\n }\r\n }\r\n\r\n function getHidden(index: number) {\r\n if (typeof maxRows !== \"number\") return false\r\n return index >= maxRows * columnCount\r\n }\r\n\r\n useEffect(() => {\r\n let timeout: number\r\n const observer = new ResizeObserver(entries => {\r\n clearTimeout(timeout)\r\n function task() {\r\n const { width } = entries[0].contentRect\r\n const [newColumnCount, newColumnGapSize] = getGapCountAndSize(width, itemWidth, minColumnGap, maxColumnGap)\r\n setShowItems(true)\r\n setWidth(width)\r\n setColumnCount(newColumnCount)\r\n setColumnGapSize(newColumnGapSize)\r\n }\r\n if (throttle === null) {\r\n task()\r\n } else {\r\n timeout = window.setTimeout(task, throttle || 200)\r\n }\r\n })\r\n observer.observe(ele.current!)\r\n\r\n return () => {\r\n observer.disconnect()\r\n }\r\n }, [itemWidth, throttle, columnGap])\r\n\r\n useEffect(() => {\r\n onSizeChange?.({ width, height, itemWidth, itemHeight, columnGap: columnGapSize, columnCount, rowGap, rowCount: contentShownRows, overflow: data.length > contentShownRows * columnCount, itemCount: data.length, maxRows: maxRows ?? null })\r\n }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows])\r\n\r\n return (\r\n <div ref={ele} className={className} style={{ position: \"relative\", boxSizing: \"border-box\", height, ...style }} {...rest}>\r\n {showItems &&\r\n data.map((item, index) => (\r\n <div\r\n key={keyExactor ? keyExactor(item, index) : index}\r\n className={containerClassName}\r\n style={{\r\n position: \"absolute\",\r\n width: itemWidth,\r\n height: itemHeight,\r\n transition: transitionDuration !== null ? `all ${transitionDuration ?? 400}ms` : undefined,\r\n ...getPosition(index)\r\n }}>\r\n <div style={{ width: itemWidth, height: itemHeight, display: maxRows && index >= maxRows * columnCount ? \"none\" : \"block\", ...containerStyle }}>{render(item, index, getHidden(index))}</div>\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n}\r\n"],"mappings":"AAAA,YAAY;;AAEZ,SAAmDA,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAwD7F,OAAO,SAASC,WAAWA,CAACC,GAAmD,EAA2B;EACtG,IAAI,OAAOA,GAAG,KAAK,QAAQ,EAAE,OAAO,CAACA,GAAG,EAAEA,GAAG,CAAC;EAC9C,IAAIC,KAAK,CAACC,OAAO,CAACF,GAAG,CAAC,EAAE,OAAO,CAACA,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAEA,GAAG,CAAC,CAAC,CAAC,CAAC;EACpD,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC;AACpB;AAEA,OAAO,SAASG,kBAAkBA,CAACC,KAAa,EAAEC,SAAiB,EAAEC,MAAc,EAAEC,MAAqB,EAAoB;EAC1H,MAAMC,KAAK,GAAGC,IAAI,CAACC,KAAK,CAAC,CAACN,KAAK,GAAGE,MAAM,KAAKD,SAAS,GAAGC,MAAM,CAAC,CAAC,IAAI,CAAC;EACtE,IAAIE,KAAK,KAAK,CAAC,EAAE,OAAO,CAACA,KAAK,EAAE,CAAC,CAAC;EAClC,MAAMG,UAAU,GAAG,CAACP,KAAK,GAAGC,SAAS,GAAGG,KAAK,KAAKA,KAAK,GAAG,CAAC,CAAC;EAC5D,IAAIG,UAAU,GAAGL,MAAM,EAAE,OAAO,CAACE,KAAK,EAAEF,MAAM,CAAC;EAC/C,IAAIC,MAAM,KAAK,IAAI,IAAII,UAAU,GAAGJ,MAAM,EAAE,OAAO,CAACC,KAAK,EAAED,MAAM,CAAC;EAClE,OAAO,CAACC,KAAK,EAAEG,UAAU,CAAC;AAC9B;AAOA;AACA,OAAO,SAASC,IAAIA,CAAIC,KAAmB,EAAE;EACzC,MAAM;IAAER,SAAS;IAAES,UAAU;IAAEC,SAAS;IAAEC,MAAM,GAAG,CAAC;IAAEC,OAAO;IAAEC,IAAI;IAAEC,MAAM;IAAEC,UAAU;IAAEC,SAAS;IAAEC,KAAK;IAAEC,kBAAkB;IAAEC,cAAc;IAAEC,QAAQ;IAAEC,kBAAkB;IAAEC,YAAY;IAAE,GAAGC;EAAK,CAAC,GAAGf,KAAK;EAC5M,MAAM,CAACgB,YAAY,EAAEC,YAAY,CAAC,GAAG/B,WAAW,CAACgB,SAAS,CAAC;EAC3D,MAAM,CAACX,KAAK,EAAE2B,QAAQ,CAAC,GAAGnC,QAAQ,CAAC,CAAC,CAAC;EACrC,MAAM,CAACoC,WAAW,EAAEC,cAAc,CAAC,GAAGrC,QAAQ,CAAC,CAAC,CAAC;EACjD,MAAM,CAACsC,aAAa,EAAEC,gBAAgB,CAAC,GAAGvC,QAAQ,CAACiC,YAAY,CAAC;EAChE,MAAM,CAACO,SAAS,EAAEC,YAAY,CAAC,GAAGzC,QAAQ,CAAC,KAAK,CAAC;EACjD,MAAM0C,GAAG,GAAG3C,MAAM,CAAiB,IAAI,CAAC;EACxC,MAAM4C,WAAW,GAAG9B,IAAI,CAAC+B,IAAI,CAACtB,IAAI,CAACuB,MAAM,GAAGT,WAAW,CAAC;EACxD,MAAMU,gBAAgB,GAAG,OAAOzB,OAAO,KAAK,QAAQ,GAAGR,IAAI,CAACkC,GAAG,CAACJ,WAAW,EAAEtB,OAAO,CAAC,GAAGsB,WAAW;EACnG,MAAMK,MAAM,GAAGF,gBAAgB,GAAG,CAAC,GAAGA,gBAAgB,IAAI5B,UAAU,GAAGE,MAAM,CAAC,GAAGA,MAAM,GAAG,CAAC;EAE3F,SAAS6B,WAAWA,CAACC,KAAa,EAAY;IAC1C,MAAMC,CAAC,GAAGtC,IAAI,CAACC,KAAK,CAACoC,KAAK,GAAGd,WAAW,CAAC;IACzC,MAAMgB,CAAC,GAAGF,KAAK,GAAGC,CAAC,GAAGf,WAAW;IACjC,OAAO;MACHiB,IAAI,EAAED,CAAC,IAAI3C,SAAS,GAAG6B,aAAa,CAAC;MACrCgB,GAAG,EAAEH,CAAC,IAAIjC,UAAU,GAAGE,MAAM;IACjC,CAAC;EACL;EAEA,SAASmC,SAASA,CAACL,KAAa,EAAE;IAC9B,IAAI,OAAO7B,OAAO,KAAK,QAAQ,EAAE,OAAO,KAAK;IAC7C,OAAO6B,KAAK,IAAI7B,OAAO,GAAGe,WAAW;EACzC;EAEAtC,SAAS,CAAC,MAAM;IACZ,IAAI0D,OAAe;IACnB,MAAMC,QAAQ,GAAG,IAAIC,cAAc,CAACC,OAAO,IAAI;MAC3CC,YAAY,CAACJ,OAAO,CAAC;MACrB,SAASK,IAAIA,CAAA,EAAG;QACZ,MAAM;UAAErD;QAAM,CAAC,GAAGmD,OAAO,CAAC,CAAC,CAAC,CAACG,WAAW;QACxC,MAAM,CAACC,cAAc,EAAEC,gBAAgB,CAAC,GAAGzD,kBAAkB,CAACC,KAAK,EAAEC,SAAS,EAAEwB,YAAY,EAAEC,YAAY,CAAC;QAC3GO,YAAY,CAAC,IAAI,CAAC;QAClBN,QAAQ,CAAC3B,KAAK,CAAC;QACf6B,cAAc,CAAC0B,cAAc,CAAC;QAC9BxB,gBAAgB,CAACyB,gBAAgB,CAAC;MACtC;MACA,IAAInC,QAAQ,KAAK,IAAI,EAAE;QACnBgC,IAAI,CAAC,CAAC;MACV,CAAC,MAAM;QACHL,OAAO,GAAGS,MAAM,CAACC,UAAU,CAACL,IAAI,EAAEhC,QAAQ,IAAI,GAAG,CAAC;MACtD;IACJ,CAAC,CAAC;IACF4B,QAAQ,CAACU,OAAO,CAACzB,GAAG,CAAC0B,OAAQ,CAAC;IAE9B,OAAO,MAAM;MACTX,QAAQ,CAACY,UAAU,CAAC,CAAC;IACzB,CAAC;EACL,CAAC,EAAE,CAAC5D,SAAS,EAAEoB,QAAQ,EAAEV,SAAS,CAAC,CAAC;EAEpCrB,SAAS,CAAC,MAAM;IACZiC,YAAY,GAAG;MAAEvB,KAAK;MAAEwC,MAAM;MAAEvC,SAAS;MAAES,UAAU;MAAEC,SAAS,EAAEmB,aAAa;MAAEF,WAAW;MAAEhB,MAAM;MAAEkD,QAAQ,EAAExB,gBAAgB;MAAEyB,QAAQ,EAAEjD,IAAI,CAACuB,MAAM,GAAGC,gBAAgB,GAAGV,WAAW;MAAEoC,SAAS,EAAElD,IAAI,CAACuB,MAAM;MAAExB,OAAO,EAAEA,OAAO,IAAI;IAAK,CAAC,CAAC;EACjP,CAAC,EAAE,CAACb,KAAK,EAAEwC,MAAM,EAAEV,aAAa,EAAEF,WAAW,EAAEhB,MAAM,EAAE0B,gBAAgB,EAAExB,IAAI,CAACuB,MAAM,EAAEpC,SAAS,EAAES,UAAU,EAAEG,OAAO,CAAC,CAAC;EAEtH,oBACInB,IAAA;IAAKuE,GAAG,EAAE/B,GAAI;IAACjB,SAAS,EAAEA,SAAU;IAACC,KAAK,EAAE;MAAEgD,QAAQ,EAAE,UAAU;MAAEC,SAAS,EAAE,YAAY;MAAE3B,MAAM;MAAE,GAAGtB;IAAM,CAAE;IAAA,GAAKM,IAAI;IAAA4C,QAAA,EACpHpC,SAAS,IACNlB,IAAI,CAACuD,GAAG,CAAC,CAACC,IAAI,EAAE5B,KAAK,kBACjBhD,IAAA;MAEIuB,SAAS,EAAEE,kBAAmB;MAC9BD,KAAK,EAAE;QACHgD,QAAQ,EAAE,UAAU;QACpBlE,KAAK,EAAEC,SAAS;QAChBuC,MAAM,EAAE9B,UAAU;QAClB6D,UAAU,EAAEjD,kBAAkB,KAAK,IAAI,GAAI,OAAMA,kBAAkB,IAAI,GAAI,IAAG,GAAGkD,SAAS;QAC1F,GAAG/B,WAAW,CAACC,KAAK;MACxB,CAAE;MAAA0B,QAAA,eACF1E,IAAA;QAAKwB,KAAK,EAAE;UAAElB,KAAK,EAAEC,SAAS;UAAEuC,MAAM,EAAE9B,UAAU;UAAE+D,OAAO,EAAE5D,OAAO,IAAI6B,KAAK,IAAI7B,OAAO,GAAGe,WAAW,GAAG,MAAM,GAAG,OAAO;UAAE,GAAGR;QAAe,CAAE;QAAAgD,QAAA,EAAErD,MAAM,CAACuD,IAAI,EAAE5B,KAAK,EAAEK,SAAS,CAACL,KAAK,CAAC;MAAC,CAAM;IAAC,GATxL1B,UAAU,GAAGA,UAAU,CAACsD,IAAI,EAAE5B,KAAK,CAAC,GAAGA,KAU3C,CACR;EAAC,CACL,CAAC;AAEd"}
1
+ {"version":3,"names":["css","clsx","useEffect","useRef","useState","px","styleWithCSSVariable","jsx","_jsx","getGapRange","gap","Array","isArray","getGapCountAndSize","width","itemWidth","minGap","maxGap","count","Math","floor","averageGap","Flow","props","itemHeight","columnGap","rowGap","maxRows","data","render","keyExactor","className","style","wrapperClassName","wrapperStyle","throttle","transitionDuration","onSizeChange","containerClassName","containerStyle","rest","minColumnGap","maxColumnGap","setWidth","columnCount","setColumnCount","columnGapSize","setColumnGapSize","showItems","setShowItems","ele","contentRows","ceil","length","contentShownRows","min","height","getPosition","index","y","x","left","top","getHidden","timeout","observer","ResizeObserver","entries","clearTimeout","task","contentRect","newColumnCount","newColumnGapSize","window","setTimeout","observe","current","disconnect","rowCount","overflow","itemCount","ref","children","map","item","arr"],"sources":["../../../src/components/Flow.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { css } from \"@emotion/css\"\r\nimport { clsx } from \"deepsea-tools\"\r\nimport { CSSProperties, HTMLAttributes, Key, ReactNode, useEffect, useRef, useState } from \"react\"\r\nimport { px, styleWithCSSVariable } from \"../utils\"\r\n\r\nexport interface FlowSizeData {\r\n /** 容器宽度 */\r\n width: number\r\n /** 容器高度 */\r\n height: number\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap: number\r\n /** 列数 */\r\n columnCount: number\r\n /** 行间距 */\r\n rowGap: number\r\n /** 行数 */\r\n rowCount: number\r\n /** 元素格数 */\r\n itemCount: number\r\n /** 最大行数 */\r\n maxRows: number | null\r\n /** 是否有元素被隐藏 */\r\n overflow: boolean\r\n}\r\n\r\nexport interface FlowProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap?: number | null | (number | null)[]\r\n /** 行间距 */\r\n rowGap?: number\r\n /** 最大行数 */\r\n maxRows?: number | null\r\n /** 源数据 */\r\n data: T[]\r\n /** 渲染 */\r\n render: (item: T, index: number, arr: T[]) => ReactNode\r\n /** key释放器,默认为 index */\r\n keyExactor?: (item: T, index: number, arr: T[]) => Key\r\n /** 容器类名 */\r\n wrapperClassName?: string\r\n /** 容器样式 */\r\n wrapperStyle?: CSSProperties\r\n /** 容器类名 */\r\n containerClassName?: string\r\n /** 容器样式 */\r\n containerStyle?: CSSProperties\r\n /** 节流时间,单位毫秒,默认200ms,传入 null 不节流 */\r\n throttle?: number | null\r\n /** 动画时间,单位毫秒,默认400ms,传入 null 不展示动画 */\r\n transitionDuration?: number | null\r\n /** 变化的回调函数 */\r\n onSizeChange?: (sizeData: FlowSizeData) => void\r\n}\r\n\r\nexport function getGapRange(gap?: undefined | number | null | (number | null)[]): [number, number | null] {\r\n if (typeof gap === \"number\") return [gap, gap]\r\n if (Array.isArray(gap)) return [gap[0] || 0, gap[1]]\r\n return [0, null]\r\n}\r\n\r\nexport function getGapCountAndSize(width: number, itemWidth: number, minGap: number, maxGap: number | null): [number, number] {\r\n const count = Math.floor((width + minGap) / (itemWidth + minGap)) || 1\r\n if (count === 1) return [count, 0]\r\n const averageGap = (width - itemWidth * count) / (count - 1)\r\n if (averageGap < minGap) return [count, minGap]\r\n if (maxGap !== null && averageGap > maxGap) return [count, maxGap]\r\n return [count, averageGap]\r\n}\r\n\r\ninterface Position {\r\n left: number\r\n top: number\r\n}\r\n\r\n/** 自适应浮动组件 */\r\nexport function Flow<T>(props: FlowProps<T>) {\r\n const { itemWidth, itemHeight, columnGap, rowGap = 0, maxRows, data, render, keyExactor, className, style, wrapperClassName, wrapperStyle, throttle, transitionDuration, onSizeChange, containerClassName, containerStyle, ...rest } = props\r\n const [minColumnGap, maxColumnGap] = getGapRange(columnGap)\r\n const [width, setWidth] = useState(0)\r\n const [columnCount, setColumnCount] = useState(1)\r\n const [columnGapSize, setColumnGapSize] = useState(minColumnGap)\r\n const [showItems, setShowItems] = useState(false)\r\n const ele = useRef<HTMLDivElement>(null)\r\n const contentRows = Math.ceil(data.length / columnCount)\r\n const contentShownRows = typeof maxRows === \"number\" ? Math.min(contentRows, maxRows) : contentRows\r\n const height = contentShownRows > 0 ? contentShownRows * (itemHeight + rowGap) - rowGap : 0\r\n\r\n function getPosition(index: number): Position {\r\n const y = Math.floor(index / columnCount)\r\n const x = index - y * columnCount\r\n return {\r\n left: x * (itemWidth + columnGapSize),\r\n top: y * (itemHeight + rowGap)\r\n }\r\n }\r\n\r\n function getHidden(index: number) {\r\n if (typeof maxRows !== \"number\") return false\r\n return index >= maxRows * columnCount\r\n }\r\n\r\n useEffect(() => {\r\n let timeout: number\r\n const observer = new ResizeObserver(entries => {\r\n clearTimeout(timeout)\r\n function task() {\r\n const { width } = entries[0].contentRect\r\n const [newColumnCount, newColumnGapSize] = getGapCountAndSize(width, itemWidth, minColumnGap, maxColumnGap)\r\n setShowItems(true)\r\n setWidth(width)\r\n setColumnCount(newColumnCount)\r\n setColumnGapSize(newColumnGapSize)\r\n }\r\n if (throttle === null) {\r\n task()\r\n } else {\r\n timeout = window.setTimeout(task, throttle || 200)\r\n }\r\n })\r\n observer.observe(ele.current!)\r\n\r\n return () => {\r\n observer.disconnect()\r\n }\r\n }, [itemWidth, throttle, columnGap])\r\n\r\n useEffect(() => {\r\n onSizeChange?.({ width, height, itemWidth, itemHeight, columnGap: columnGapSize, columnCount, rowGap, rowCount: contentShownRows, overflow: data.length > contentShownRows * columnCount, itemCount: data.length, maxRows: maxRows ?? null })\r\n }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows])\r\n\r\n return (\r\n <div\r\n ref={ele}\r\n className={clsx(\r\n css`\r\n position: relative;\r\n height: var(--height);\r\n overflow: hidden;\r\n `,\r\n className\r\n )}\r\n style={styleWithCSSVariable({ \"--height\": px(height) })}\r\n {...rest}>\r\n {showItems &&\r\n data.map((item, index, arr) => (\r\n <div\r\n key={keyExactor ? keyExactor(item, index, arr) : index}\r\n className={clsx(\r\n css`\r\n position: absolute;\r\n width: var(--width);\r\n height: var(--height);\r\n transition: var(--transition);\r\n left: 0;\r\n top: 0;\r\n transform: translate(var(--left), var(--top));\r\n `,\r\n wrapperClassName\r\n )}\r\n style={styleWithCSSVariable({\r\n \"--width\": px(itemWidth),\r\n \"--height\": px(itemHeight),\r\n \"--transition\": transitionDuration === null ? \"none\" : `all ${transitionDuration || 400}ms`,\r\n \"--left\": px(getPosition(index).left),\r\n \"--top\": px(getPosition(index).top),\r\n ...wrapperStyle\r\n })}>\r\n <div\r\n className={clsx(\r\n css`\r\n width: 100%;\r\n height: 100%;\r\n display: var(--display);\r\n `,\r\n containerClassName\r\n )}\r\n style={styleWithCSSVariable({ \"--display\": getHidden(index) ? \"none\" : \"block\", ...containerStyle })}>\r\n {render(item, index, arr)}\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n}\r\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { MediaHTMLAttributes } from "react";
2
+ export interface HlsPlayerProps extends Omit<MediaHTMLAttributes<HTMLVideoElement>, "src"> {
3
+ src: string;
4
+ }
5
+ declare const HlsPlayer: import("react").ForwardRefExoticComponent<HlsPlayerProps & import("react").RefAttributes<HTMLVideoElement>>;
6
+ export default HlsPlayer;
@@ -0,0 +1,39 @@
1
+ "use client";
2
+
3
+ import Hls from "hls.js";
4
+ import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const HlsPlayer = /*#__PURE__*/forwardRef((props, ref) => {
7
+ const {
8
+ src,
9
+ ...rest
10
+ } = props;
11
+ const video = useRef(null);
12
+ useImperativeHandle(ref, () => video.current, []);
13
+ useEffect(() => {
14
+ const {
15
+ current: player
16
+ } = video;
17
+ if (!player || !src) return;
18
+ if (player.canPlayType("application/vnd.apple.mpegurl")) {
19
+ player.src = src;
20
+ player.play();
21
+ return;
22
+ }
23
+ if (Hls.isSupported()) {
24
+ const hls = new Hls();
25
+ hls.loadSource(src);
26
+ hls.attachMedia(player);
27
+ player.play();
28
+ return () => {
29
+ hls.destroy();
30
+ };
31
+ }
32
+ }, [src]);
33
+ return /*#__PURE__*/_jsx("video", {
34
+ ref: video,
35
+ ...rest
36
+ });
37
+ });
38
+ export default HlsPlayer;
39
+ //# sourceMappingURL=HlsPlayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Hls","forwardRef","useEffect","useImperativeHandle","useRef","jsx","_jsx","HlsPlayer","props","ref","src","rest","video","current","player","canPlayType","play","isSupported","hls","loadSource","attachMedia","destroy"],"sources":["../../../src/components/HlsPlayer.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport Hls from \"hls.js\"\r\nimport { MediaHTMLAttributes, forwardRef, useEffect, useImperativeHandle, useRef } from \"react\"\r\n\r\nexport interface HlsPlayerProps extends Omit<MediaHTMLAttributes<HTMLVideoElement>, \"src\"> {\r\n src: string\r\n}\r\n\r\nconst HlsPlayer = forwardRef<HTMLVideoElement, HlsPlayerProps>((props, ref) => {\r\n const { src, ...rest } = props\r\n const video = useRef<HTMLVideoElement>(null)\r\n\r\n useImperativeHandle(ref, () => video.current!, [])\r\n\r\n useEffect(() => {\r\n const { current: player } = video\r\n if (!player || !src) return\r\n if (player.canPlayType(\"application/vnd.apple.mpegurl\")) {\r\n player.src = src\r\n player.play()\r\n return\r\n }\r\n if (Hls.isSupported()) {\r\n const hls = new Hls()\r\n hls.loadSource(src)\r\n hls.attachMedia(player)\r\n player.play()\r\n return () => {\r\n hls.destroy()\r\n }\r\n }\r\n }, [src])\r\n\r\n return <video ref={video} {...rest} />\r\n})\r\n\r\nexport default HlsPlayer\r\n"],"mappings":"AAAA,YAAY;;AAEZ,OAAOA,GAAG,MAAM,QAAQ;AACxB,SAA8BC,UAAU,EAAEC,SAAS,EAAEC,mBAAmB,EAAEC,MAAM,QAAQ,OAAO;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAM/F,MAAMC,SAAS,gBAAGN,UAAU,CAAmC,CAACO,KAAK,EAAEC,GAAG,KAAK;EAC3E,MAAM;IAAEC,GAAG;IAAE,GAAGC;EAAK,CAAC,GAAGH,KAAK;EAC9B,MAAMI,KAAK,GAAGR,MAAM,CAAmB,IAAI,CAAC;EAE5CD,mBAAmB,CAACM,GAAG,EAAE,MAAMG,KAAK,CAACC,OAAQ,EAAE,EAAE,CAAC;EAElDX,SAAS,CAAC,MAAM;IACZ,MAAM;MAAEW,OAAO,EAAEC;IAAO,CAAC,GAAGF,KAAK;IACjC,IAAI,CAACE,MAAM,IAAI,CAACJ,GAAG,EAAE;IACrB,IAAII,MAAM,CAACC,WAAW,CAAC,+BAA+B,CAAC,EAAE;MACrDD,MAAM,CAACJ,GAAG,GAAGA,GAAG;MAChBI,MAAM,CAACE,IAAI,CAAC,CAAC;MACb;IACJ;IACA,IAAIhB,GAAG,CAACiB,WAAW,CAAC,CAAC,EAAE;MACnB,MAAMC,GAAG,GAAG,IAAIlB,GAAG,CAAC,CAAC;MACrBkB,GAAG,CAACC,UAAU,CAACT,GAAG,CAAC;MACnBQ,GAAG,CAACE,WAAW,CAACN,MAAM,CAAC;MACvBA,MAAM,CAACE,IAAI,CAAC,CAAC;MACb,OAAO,MAAM;QACTE,GAAG,CAACG,OAAO,CAAC,CAAC;MACjB,CAAC;IACL;EACJ,CAAC,EAAE,CAACX,GAAG,CAAC,CAAC;EAET,oBAAOJ,IAAA;IAAOG,GAAG,EAAEG,KAAM;IAAA,GAAKD;EAAI,CAAG,CAAC;AAC1C,CAAC,CAAC;AAEF,eAAeJ,SAAS"}
@@ -4,12 +4,13 @@ import { css } from "@emotion/css";
4
4
  import { clsx } from "deepsea-tools";
5
5
  import { forwardRef } from "react";
6
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
- const Skeleton = /*#__PURE__*/forwardRef(props => {
7
+ const Skeleton = /*#__PURE__*/forwardRef((props, ref) => {
8
8
  const {
9
9
  className,
10
10
  ...rest
11
11
  } = props;
12
12
  return /*#__PURE__*/_jsx("div", {
13
+ ref: ref,
13
14
  className: clsx(css`
14
15
  @keyframes shimmer {
15
16
  0% {
@@ -1 +1 @@
1
- {"version":3,"names":["css","clsx","forwardRef","jsx","_jsx","Skeleton","props","className","rest"],"sources":["../../../src/components/Skeleton.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { css } from \"@emotion/css\"\r\nimport { clsx } from \"deepsea-tools\"\r\nimport { forwardRef, HTMLAttributes } from \"react\"\r\n\r\nconst Skeleton = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(props => {\r\n const { className, ...rest } = props\r\n\r\n return (\r\n <div\r\n className={clsx(\r\n css`\r\n @keyframes shimmer {\r\n 0% {\r\n background-position: -400px 0px;\r\n }\r\n 100% {\r\n background-position: 400px 0px;\r\n }\r\n }\r\n\r\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.067) 8%, rgba(0, 0, 0, 0.133) 18%, rgba(0, 0, 0, 0.067) 33%);\r\n animation-duration: 1s;\r\n animation-fill-mode: forwards;\r\n animation-iteration-count: infinite;\r\n animation-name: shimmer;\r\n animation-timing-function: linear;\r\n background-size: 800px 104px;\r\n `,\r\n className\r\n )}\r\n {...rest}\r\n />\r\n )\r\n})\r\n\r\nexport default Skeleton\r\n"],"mappings":"AAAA,YAAY;;AAEZ,SAASA,GAAG,QAAQ,cAAc;AAClC,SAASC,IAAI,QAAQ,eAAe;AACpC,SAASC,UAAU,QAAwB,OAAO;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAElD,MAAMC,QAAQ,gBAAGH,UAAU,CAAiDI,KAAK,IAAI;EACjF,MAAM;IAAEC,SAAS;IAAE,GAAGC;EAAK,CAAC,GAAGF,KAAK;EAEpC,oBACIF,IAAA;IACIG,SAAS,EAAEN,IAAI,CACXD,GAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,EACDO,SACJ,CAAE;IAAA,GACEC;EAAI,CACX,CAAC;AAEV,CAAC,CAAC;AAEF,eAAeH,QAAQ"}
1
+ {"version":3,"names":["css","clsx","forwardRef","jsx","_jsx","Skeleton","props","ref","className","rest"],"sources":["../../../src/components/Skeleton.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { css } from \"@emotion/css\"\r\nimport { clsx } from \"deepsea-tools\"\r\nimport { forwardRef, HTMLAttributes } from \"react\"\r\n\r\nconst Skeleton = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>((props, ref) => {\r\n const { className, ...rest } = props\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n className={clsx(\r\n css`\r\n @keyframes shimmer {\r\n 0% {\r\n background-position: -400px 0px;\r\n }\r\n 100% {\r\n background-position: 400px 0px;\r\n }\r\n }\r\n\r\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.067) 8%, rgba(0, 0, 0, 0.133) 18%, rgba(0, 0, 0, 0.067) 33%);\r\n animation-duration: 1s;\r\n animation-fill-mode: forwards;\r\n animation-iteration-count: infinite;\r\n animation-name: shimmer;\r\n animation-timing-function: linear;\r\n background-size: 800px 104px;\r\n `,\r\n className\r\n )}\r\n {...rest}\r\n />\r\n )\r\n})\r\n\r\nexport default Skeleton\r\n"],"mappings":"AAAA,YAAY;;AAEZ,SAASA,GAAG,QAAQ,cAAc;AAClC,SAASC,IAAI,QAAQ,eAAe;AACpC,SAASC,UAAU,QAAwB,OAAO;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAElD,MAAMC,QAAQ,gBAAGH,UAAU,CAAiD,CAACI,KAAK,EAAEC,GAAG,KAAK;EACxF,MAAM;IAAEC,SAAS;IAAE,GAAGC;EAAK,CAAC,GAAGH,KAAK;EAEpC,oBACIF,IAAA;IACIG,GAAG,EAAEA,GAAI;IACTC,SAAS,EAAEP,IAAI,CACXD,GAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,EACDQ,SACJ,CAAE;IAAA,GACEC;EAAI,CACX,CAAC;AAEV,CAAC,CAAC;AAEF,eAAeJ,QAAQ"}
@@ -3,6 +3,7 @@ export * from "./components/AutoScroll";
3
3
  export * from "./components/AutoSizeTextarea";
4
4
  export * from "./components/CircleText";
5
5
  export * from "./components/Flow";
6
+ export * from "./components/HlsPlayer";
6
7
  export * from "./components/InputFile";
7
8
  export * from "./components/LoopSwiper";
8
9
  export * from "./components/Ring";
package/dist/esm/index.js CHANGED
@@ -3,6 +3,7 @@ export * from "./components/AutoScroll";
3
3
  export * from "./components/AutoSizeTextarea";
4
4
  export * from "./components/CircleText";
5
5
  export * from "./components/Flow";
6
+ export * from "./components/HlsPlayer";
6
7
  export * from "./components/InputFile";
7
8
  export * from "./components/LoopSwiper";
8
9
  export * from "./components/Ring";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["../../src/index.tsx"],"sourcesContent":["export * from \"./components/AutoFit\"\r\nexport * from \"./components/AutoScroll\"\r\nexport * from \"./components/AutoSizeTextarea\"\r\nexport * from \"./components/CircleText\"\r\nexport * from \"./components/Flow\"\r\nexport * from \"./components/InputFile\"\r\nexport * from \"./components/LoopSwiper\"\r\nexport * from \"./components/Ring\"\r\nexport * from \"./components/Scroll\"\r\nexport * from \"./components/SectionRing\"\r\nexport * from \"./components/Skeleton\"\r\nexport * from \"./components/TransitionBox\"\r\nexport * from \"./components/TransitionNum\"\r\nexport * from \"./components/Trapezium\"\r\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}
1
+ {"version":3,"names":[],"sources":["../../src/index.tsx"],"sourcesContent":["export * from \"./components/AutoFit\"\r\nexport * from \"./components/AutoScroll\"\r\nexport * from \"./components/AutoSizeTextarea\"\r\nexport * from \"./components/CircleText\"\r\nexport * from \"./components/Flow\"\r\nexport * from \"./components/HlsPlayer\"\r\nexport * from \"./components/InputFile\"\r\nexport * from \"./components/LoopSwiper\"\r\nexport * from \"./components/Ring\"\r\nexport * from \"./components/Scroll\"\r\nexport * from \"./components/SectionRing\"\r\nexport * from \"./components/Skeleton\"\r\nexport * from \"./components/TransitionBox\"\r\nexport * from \"./components/TransitionNum\"\r\nexport * from \"./components/Trapezium\"\r\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}
@@ -0,0 +1,8 @@
1
+ import { CSSProperties } from "react";
2
+ export type CSSVariableName = `--${string}`;
3
+ export type CSSVariableValue = string | number;
4
+ export interface StyleWithCSSVariable extends CSSProperties {
5
+ [X: CSSVariableName]: CSSVariableValue;
6
+ }
7
+ export declare function styleWithCSSVariable(style: StyleWithCSSVariable): CSSProperties;
8
+ export declare function px(value: number): string;
@@ -0,0 +1,7 @@
1
+ export function styleWithCSSVariable(style) {
2
+ return style;
3
+ }
4
+ export function px(value) {
5
+ return `${value}px`;
6
+ }
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["styleWithCSSVariable","style","px","value"],"sources":["../../../src/utils/index.ts"],"sourcesContent":["import { CSSProperties } from \"react\"\r\n\r\nexport type CSSVariableName = `--${string}`\r\n\r\nexport type CSSVariableValue = string | number\r\n\r\nexport interface StyleWithCSSVariable extends CSSProperties {\r\n [X: CSSVariableName]: CSSVariableValue\r\n}\r\n\r\nexport function styleWithCSSVariable(style: StyleWithCSSVariable): CSSProperties {\r\n return style\r\n}\r\n\r\nexport function px(value: number): string {\r\n return `${value}px`\r\n}"],"mappings":"AAUA,OAAO,SAASA,oBAAoBA,CAACC,KAA2B,EAAiB;EAC7E,OAAOA,KAAK;AAChB;AAEA,OAAO,SAASC,EAAEA,CAACC,KAAa,EAAU;EACtC,OAAQ,GAAEA,KAAM,IAAG;AACvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepsea-components",
3
- "version": "3.0.0",
3
+ "version": "3.0.2-beta.20240527145411",
4
4
  "description": "格数科技自用组件库",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -33,6 +33,7 @@
33
33
  "@emotion/css": "^11.11.2",
34
34
  "ahooks": "^3.7.11",
35
35
  "deepsea-tools": "npm:deepsea-tools@latest",
36
+ "hls.js": "^1.5.8",
36
37
  "smooth-scrollbar": "^8.8.4",
37
38
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
38
39
  },
@@ -41,6 +42,6 @@
41
42
  "father": "^4.4.1"
42
43
  },
43
44
  "peerDependencies": {
44
- "react": ">=16.8.0"
45
+ "react": "^18.3.1"
45
46
  }
46
- }
47
+ }
@@ -1,6 +1,9 @@
1
1
  "use client"
2
2
 
3
- import { CSSProperties, HTMLAttributes, ReactNode, useEffect, useRef, useState } from "react"
3
+ import { css } from "@emotion/css"
4
+ import { clsx } from "deepsea-tools"
5
+ import { CSSProperties, HTMLAttributes, Key, ReactNode, useEffect, useRef, useState } from "react"
6
+ import { px, styleWithCSSVariable } from "../utils"
4
7
 
5
8
  export interface FlowSizeData {
6
9
  /** 容器宽度 */
@@ -41,9 +44,13 @@ export interface FlowProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, "chil
41
44
  /** 源数据 */
42
45
  data: T[]
43
46
  /** 渲染 */
44
- render: (item: T, index: number, hidden: boolean) => ReactNode
47
+ render: (item: T, index: number, arr: T[]) => ReactNode
45
48
  /** key释放器,默认为 index */
46
- keyExactor?: (item: T, index: number) => string | number
49
+ keyExactor?: (item: T, index: number, arr: T[]) => Key
50
+ /** 容器类名 */
51
+ wrapperClassName?: string
52
+ /** 容器样式 */
53
+ wrapperStyle?: CSSProperties
47
54
  /** 容器类名 */
48
55
  containerClassName?: string
49
56
  /** 容器样式 */
@@ -78,7 +85,7 @@ interface Position {
78
85
 
79
86
  /** 自适应浮动组件 */
80
87
  export function Flow<T>(props: FlowProps<T>) {
81
- const { itemWidth, itemHeight, columnGap, rowGap = 0, maxRows, data, render, keyExactor, className, style, containerClassName, containerStyle, throttle, transitionDuration, onSizeChange, ...rest } = props
88
+ const { itemWidth, itemHeight, columnGap, rowGap = 0, maxRows, data, render, keyExactor, className, style, wrapperClassName, wrapperStyle, throttle, transitionDuration, onSizeChange, containerClassName, containerStyle, ...rest } = props
82
89
  const [minColumnGap, maxColumnGap] = getGapRange(columnGap)
83
90
  const [width, setWidth] = useState(0)
84
91
  const [columnCount, setColumnCount] = useState(1)
@@ -133,20 +140,54 @@ export function Flow<T>(props: FlowProps<T>) {
133
140
  }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows])
134
141
 
135
142
  return (
136
- <div ref={ele} className={className} style={{ position: "relative", boxSizing: "border-box", height, ...style }} {...rest}>
143
+ <div
144
+ ref={ele}
145
+ className={clsx(
146
+ css`
147
+ position: relative;
148
+ height: var(--height);
149
+ overflow: hidden;
150
+ `,
151
+ className
152
+ )}
153
+ style={styleWithCSSVariable({ "--height": px(height) })}
154
+ {...rest}>
137
155
  {showItems &&
138
- data.map((item, index) => (
156
+ data.map((item, index, arr) => (
139
157
  <div
140
- key={keyExactor ? keyExactor(item, index) : index}
141
- className={containerClassName}
142
- style={{
143
- position: "absolute",
144
- width: itemWidth,
145
- height: itemHeight,
146
- transition: transitionDuration !== null ? `all ${transitionDuration ?? 400}ms` : undefined,
147
- ...getPosition(index)
148
- }}>
149
- <div style={{ width: itemWidth, height: itemHeight, display: maxRows && index >= maxRows * columnCount ? "none" : "block", ...containerStyle }}>{render(item, index, getHidden(index))}</div>
158
+ key={keyExactor ? keyExactor(item, index, arr) : index}
159
+ className={clsx(
160
+ css`
161
+ position: absolute;
162
+ width: var(--width);
163
+ height: var(--height);
164
+ transition: var(--transition);
165
+ left: 0;
166
+ top: 0;
167
+ transform: translate(var(--left), var(--top));
168
+ `,
169
+ wrapperClassName
170
+ )}
171
+ style={styleWithCSSVariable({
172
+ "--width": px(itemWidth),
173
+ "--height": px(itemHeight),
174
+ "--transition": transitionDuration === null ? "none" : `all ${transitionDuration || 400}ms`,
175
+ "--left": px(getPosition(index).left),
176
+ "--top": px(getPosition(index).top),
177
+ ...wrapperStyle
178
+ })}>
179
+ <div
180
+ className={clsx(
181
+ css`
182
+ width: 100%;
183
+ height: 100%;
184
+ display: var(--display);
185
+ `,
186
+ containerClassName
187
+ )}
188
+ style={styleWithCSSVariable({ "--display": getHidden(index) ? "none" : "block", ...containerStyle })}>
189
+ {render(item, index, arr)}
190
+ </div>
150
191
  </div>
151
192
  ))}
152
193
  </div>
@@ -0,0 +1,38 @@
1
+ "use client"
2
+
3
+ import Hls from "hls.js"
4
+ import { MediaHTMLAttributes, forwardRef, useEffect, useImperativeHandle, useRef } from "react"
5
+
6
+ export interface HlsPlayerProps extends Omit<MediaHTMLAttributes<HTMLVideoElement>, "src"> {
7
+ src: string
8
+ }
9
+
10
+ const HlsPlayer = forwardRef<HTMLVideoElement, HlsPlayerProps>((props, ref) => {
11
+ const { src, ...rest } = props
12
+ const video = useRef<HTMLVideoElement>(null)
13
+
14
+ useImperativeHandle(ref, () => video.current!, [])
15
+
16
+ useEffect(() => {
17
+ const { current: player } = video
18
+ if (!player || !src) return
19
+ if (player.canPlayType("application/vnd.apple.mpegurl")) {
20
+ player.src = src
21
+ player.play()
22
+ return
23
+ }
24
+ if (Hls.isSupported()) {
25
+ const hls = new Hls()
26
+ hls.loadSource(src)
27
+ hls.attachMedia(player)
28
+ player.play()
29
+ return () => {
30
+ hls.destroy()
31
+ }
32
+ }
33
+ }, [src])
34
+
35
+ return <video ref={video} {...rest} />
36
+ })
37
+
38
+ export default HlsPlayer
@@ -4,11 +4,12 @@ import { css } from "@emotion/css"
4
4
  import { clsx } from "deepsea-tools"
5
5
  import { forwardRef, HTMLAttributes } from "react"
6
6
 
7
- const Skeleton = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(props => {
7
+ const Skeleton = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>((props, ref) => {
8
8
  const { className, ...rest } = props
9
9
 
10
10
  return (
11
11
  <div
12
+ ref={ref}
12
13
  className={clsx(
13
14
  css`
14
15
  @keyframes shimmer {
package/src/index.tsx CHANGED
@@ -3,6 +3,7 @@ export * from "./components/AutoScroll"
3
3
  export * from "./components/AutoSizeTextarea"
4
4
  export * from "./components/CircleText"
5
5
  export * from "./components/Flow"
6
+ export * from "./components/HlsPlayer"
6
7
  export * from "./components/InputFile"
7
8
  export * from "./components/LoopSwiper"
8
9
  export * from "./components/Ring"
@@ -0,0 +1,17 @@
1
+ import { CSSProperties } from "react"
2
+
3
+ export type CSSVariableName = `--${string}`
4
+
5
+ export type CSSVariableValue = string | number
6
+
7
+ export interface StyleWithCSSVariable extends CSSProperties {
8
+ [X: CSSVariableName]: CSSVariableValue
9
+ }
10
+
11
+ export function styleWithCSSVariable(style: StyleWithCSSVariable): CSSProperties {
12
+ return style
13
+ }
14
+
15
+ export function px(value: number): string {
16
+ return `${value}px`
17
+ }