@publishfx/publish-components 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
- # @moonton/publish-components
1
+ # @publishfx/publish-components
2
2
 
3
3
  A React UI component library for the Publish platform, built with React, TypeScript, and styled-components.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- pnpm add @moonton/publish-components
8
+ pnpm add @publishfx/publish-components
9
9
  # or
10
- npm install @moonton/publish-components
10
+ npm install @publishfx/publish-components
11
11
  # or
12
- yarn add @moonton/publish-components
12
+ yarn add @publishfx/publish-components
13
13
  ```
14
14
 
15
15
  ## Peer Dependencies
@@ -31,7 +31,7 @@ pnpm add react react-dom
31
31
  A customizable button component with predefined action types and icons.
32
32
 
33
33
  ```jsx
34
- import { ActionButton, ActionButtonType } from '@moonton/publish-components';
34
+ import { ActionButton, ActionButtonType } from '@publishfx/publish-components';
35
35
 
36
36
  function App() {
37
37
  return (
@@ -63,7 +63,7 @@ function App() {
63
63
  A high-performance data table component with column resizing, sorting, pagination, and advanced formatting features.
64
64
 
65
65
  ```jsx
66
- import { PerformanceTable, PerformanceTableColumn } from '@moonton/publish-components';
66
+ import { PerformanceTable, PerformanceTableColumn } from '@publishfx/publish-components';
67
67
 
68
68
  const columns: PerformanceTableColumn[] = [
69
69
  {
@@ -120,7 +120,7 @@ function App() {
120
120
  Sticky positioning components for creating sticky headers, sidebars, and other elements.
121
121
 
122
122
  ```jsx
123
- import { Sticky, StickyContainer } from '@moonton/publish-components';
123
+ import { Sticky, StickyContainer } from '@publishfx/publish-components';
124
124
 
125
125
  function App() {
126
126
  return (
@@ -149,7 +149,7 @@ import {
149
149
  IconUpload,
150
150
  IconSearch,
151
151
  // ... and more
152
- } from '@moonton/publish-components';
152
+ } from '@publishfx/publish-components';
153
153
 
154
154
  function App() {
155
155
  return (
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import { TimePickerSelectProps, TimeOption, TimeInterval, GenerateTimeOptionsConfig } from "./interface";
3
+ /**
4
+ * 生成时间选项
5
+ * @param config 配置
6
+ * @returns 时间选项列表
7
+ */
8
+ export declare const generateTimeOptions: (config?: GenerateTimeOptionsConfig) => TimeOption[];
9
+ /**
10
+ * 默认时间选项(00:00 - 23:30,每30分钟一个)
11
+ */
12
+ export declare const defaultTimeOptions: TimeOption[];
13
+ /**
14
+ * 时间选择器组件
15
+ * 基于 Arco Design Select 封装,提供网格布局的时间选择
16
+ */
17
+ declare const TimePickerSelect: React.FC<TimePickerSelectProps>;
18
+ export default TimePickerSelect;
19
+ export type { TimePickerSelectProps, TimeOption, TimeInterval, GenerateTimeOptionsConfig, };
@@ -0,0 +1,168 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useMemo, useState } from "react";
3
+ import { Checkbox, Select } from "@arco-design/web-react";
4
+ import index_module from "./index.module.js";
5
+ const Option = Select.Option;
6
+ const generateTimeOptions = (config = {})=>{
7
+ const { startHour = 0, endHour = 23, interval = 30, format = "HH:mm" } = config;
8
+ const options = [];
9
+ for(let hour = startHour; hour <= endHour; hour++)for(let minute = 0; minute < 60; minute += interval){
10
+ const timeValue = 60 * hour + minute;
11
+ const label = format.replace("HH", hour.toString().padStart(2, "0")).replace("mm", minute.toString().padStart(2, "0"));
12
+ options.push({
13
+ label,
14
+ value: timeValue
15
+ });
16
+ }
17
+ return options;
18
+ };
19
+ const defaultTimeOptions = generateTimeOptions({
20
+ interval: 30
21
+ });
22
+ const TimePickerSelect = (props)=>{
23
+ const { options = defaultTimeOptions, value: controlledValue, defaultValue = [], onChange, placeholder = "请选择时间", disabled = false, className = "", style, dropdownClassName = "", dropdownStyle, maxTagCount = 4, showSelectAll = true, selectAllText = "全选", clearText = "清空", label, columnCount = 6 } = props;
24
+ const [internalValue, setInternalValue] = useState(defaultValue);
25
+ const isControlled = void 0 !== controlledValue;
26
+ const currentValue = isControlled ? controlledValue : internalValue;
27
+ const isAllSelected = useMemo(()=>{
28
+ const enabledOptions = options.filter((opt)=>!opt.disabled);
29
+ return enabledOptions.length > 0 && enabledOptions.every((opt)=>currentValue.includes(opt.value));
30
+ }, [
31
+ currentValue,
32
+ options
33
+ ]);
34
+ const isIndeterminate = useMemo(()=>currentValue.length > 0 && !isAllSelected, [
35
+ currentValue,
36
+ isAllSelected,
37
+ options
38
+ ]);
39
+ const handleChange = useCallback((newValue)=>{
40
+ const normalizedValue = Array.isArray(newValue) ? newValue : void 0 !== newValue ? [
41
+ newValue
42
+ ] : [];
43
+ const selectedOptions = options.filter((opt)=>normalizedValue.includes(opt.value));
44
+ if (!isControlled) setInternalValue(normalizedValue);
45
+ onChange?.(normalizedValue, selectedOptions);
46
+ }, [
47
+ onChange,
48
+ isControlled,
49
+ options
50
+ ]);
51
+ const handleSelectAll = useCallback(()=>{
52
+ const enabledOptions = options.filter((opt)=>!opt.disabled);
53
+ const allValues = enabledOptions.map((opt)=>opt.value);
54
+ isAllSelected ? handleChange([]) : handleChange(allValues);
55
+ }, [
56
+ handleChange,
57
+ isAllSelected,
58
+ options
59
+ ]);
60
+ const handleClear = useCallback(()=>{
61
+ handleChange([]);
62
+ }, [
63
+ handleChange
64
+ ]);
65
+ const renderDropdownHeader = useCallback(()=>{
66
+ if (!showSelectAll) return null;
67
+ return /*#__PURE__*/ jsxs("div", {
68
+ className: index_module.dropdownHeader,
69
+ children: [
70
+ /*#__PURE__*/ jsx("div", {
71
+ className: index_module.selectAll,
72
+ children: /*#__PURE__*/ jsx(Checkbox, {
73
+ checked: isAllSelected,
74
+ indeterminate: isIndeterminate,
75
+ onChange: handleSelectAll,
76
+ children: /*#__PURE__*/ jsx("span", {
77
+ className: index_module.selectAllText,
78
+ children: selectAllText
79
+ })
80
+ })
81
+ }),
82
+ /*#__PURE__*/ jsx("span", {
83
+ className: index_module.clearBtn,
84
+ onClick: handleClear,
85
+ children: clearText
86
+ })
87
+ ]
88
+ });
89
+ }, [
90
+ showSelectAll,
91
+ isAllSelected,
92
+ isIndeterminate,
93
+ selectAllText,
94
+ clearText,
95
+ handleSelectAll,
96
+ handleClear
97
+ ]);
98
+ const renderDropdownContent = useCallback((menu)=>/*#__PURE__*/ jsxs("div", {
99
+ className: index_module.dropdownContent,
100
+ style: dropdownStyle,
101
+ children: [
102
+ renderDropdownHeader(),
103
+ /*#__PURE__*/ jsx("div", {
104
+ className: index_module.optionsGrid,
105
+ style: {
106
+ gridTemplateColumns: `repeat(${columnCount}, 1fr)`
107
+ },
108
+ children: options.map((option)=>{
109
+ const isSelected = currentValue.includes(option.value);
110
+ return /*#__PURE__*/ jsx(Checkbox, {
111
+ checked: isSelected,
112
+ disabled: option.disabled,
113
+ onChange: ()=>{
114
+ if (option.disabled) return;
115
+ const newValue = isSelected ? currentValue.filter((v)=>v !== option.value) : [
116
+ ...currentValue,
117
+ option.value
118
+ ];
119
+ handleChange(newValue);
120
+ },
121
+ className: `${index_module.optionCheckbox} ${isSelected ? index_module.optionCheckboxSelected : ""} ${option.disabled ? index_module.optionCheckboxDisabled : ""}`,
122
+ children: /*#__PURE__*/ jsx("span", {
123
+ className: index_module.optionLabel,
124
+ children: option.label
125
+ })
126
+ }, option.value);
127
+ })
128
+ })
129
+ ]
130
+ }), [
131
+ options,
132
+ currentValue,
133
+ dropdownStyle,
134
+ columnCount,
135
+ renderDropdownHeader,
136
+ handleChange
137
+ ]);
138
+ return /*#__PURE__*/ jsxs("div", {
139
+ className: `${index_module.timePickerSelect_wrapper} ${className}`,
140
+ style: style,
141
+ children: [
142
+ label && /*#__PURE__*/ jsx("div", {
143
+ className: index_module.selectLabel,
144
+ children: label
145
+ }),
146
+ /*#__PURE__*/ jsx(Select, {
147
+ placeholder: placeholder,
148
+ disabled: disabled,
149
+ value: currentValue,
150
+ onChange: handleChange,
151
+ mode: "multiple",
152
+ maxTagCount: maxTagCount,
153
+ dropdownRender: renderDropdownContent,
154
+ triggerProps: {
155
+ className: `${index_module.dropdownPopup} ${dropdownClassName}`
156
+ },
157
+ className: index_module.timePickerSelect_select,
158
+ children: options.map((option)=>/*#__PURE__*/ jsx(Option, {
159
+ value: option.value,
160
+ disabled: option.disabled,
161
+ children: option.label
162
+ }, option.value))
163
+ })
164
+ ]
165
+ });
166
+ };
167
+ const src_TimePickerSelect = TimePickerSelect;
168
+ export { src_TimePickerSelect as default, defaultTimeOptions, generateTimeOptions };
@@ -0,0 +1,20 @@
1
+ import "./index_module.css";
2
+ const index_module = {
3
+ timePickerSelect_wrapper: "timePickerSelect_wrapper-ldzMK1",
4
+ timePickerSelectWrapper: "timePickerSelect_wrapper-ldzMK1",
5
+ selectLabel: "selectLabel-j8XQLR",
6
+ timePickerSelect_select: "timePickerSelect_select-xuD_LK",
7
+ timePickerSelectSelect: "timePickerSelect_select-xuD_LK",
8
+ dropdownPopup: "dropdownPopup-oUQ8vz",
9
+ dropdownContent: "dropdownContent-OfV283",
10
+ dropdownHeader: "dropdownHeader-nILpAL",
11
+ selectAll: "selectAll-H78Ezl",
12
+ selectAllText: "selectAllText-XhWUCP",
13
+ clearBtn: "clearBtn-aUkoKx",
14
+ optionsGrid: "optionsGrid-aFw9nI",
15
+ optionCheckbox: "optionCheckbox-FLZ7GF",
16
+ optionCheckboxSelected: "optionCheckboxSelected-FFTvH6",
17
+ optionCheckboxDisabled: "optionCheckboxDisabled-lcXcnC",
18
+ optionLabel: "optionLabel-KSY4BV"
19
+ };
20
+ export { index_module as default };
@@ -0,0 +1,234 @@
1
+ .timePickerSelect_wrapper-ldzMK1 {
2
+ flex-direction: column;
3
+ gap: 4px;
4
+ width: 100%;
5
+ min-width: 120px;
6
+ display: flex;
7
+ }
8
+
9
+ .selectLabel-j8XQLR {
10
+ color: #000000d9;
11
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif;
12
+ font-size: 14px;
13
+ font-weight: normal;
14
+ line-height: 1.57;
15
+ }
16
+
17
+ .timePickerSelect_select-xuD_LK {
18
+ width: 100%;
19
+ }
20
+
21
+ .timePickerSelect_select-xuD_LK .arco-select-view {
22
+ background-color: #fff;
23
+ border: 1px solid #d9d9d9;
24
+ border-radius: 2px;
25
+ min-height: 32px;
26
+ padding: 4px 12px;
27
+ transition: all .2s;
28
+ }
29
+
30
+ .timePickerSelect_select-xuD_LK .arco-select-view:hover {
31
+ border-color: #40a9ff;
32
+ }
33
+
34
+ .timePickerSelect_select-xuD_LK .arco-select-view-focused {
35
+ border-color: #1890ff;
36
+ box-shadow: 0 0 0 2px #1890ff33;
37
+ }
38
+
39
+ .timePickerSelect_select-xuD_LK .arco-select-view-disabled {
40
+ cursor: not-allowed;
41
+ background-color: #fafafa;
42
+ }
43
+
44
+ .timePickerSelect_select-xuD_LK .arco-select-view-selector {
45
+ flex-wrap: wrap;
46
+ align-items: center;
47
+ gap: 8px;
48
+ display: flex;
49
+ }
50
+
51
+ .timePickerSelect_select-xuD_LK .arco-select-view-placeholder {
52
+ color: #00000073;
53
+ font-size: 14px;
54
+ }
55
+
56
+ .timePickerSelect_select-xuD_LK .arco-select-arrow-icon {
57
+ color: #00000073;
58
+ font-size: 16px;
59
+ transition: transform .2s;
60
+ }
61
+
62
+ .timePickerSelect_select-xuD_LK .arco-select-open .arco-select-arrow-icon {
63
+ transform: rotate(180deg);
64
+ }
65
+
66
+ .timePickerSelect_select-xuD_LK .arco-tag {
67
+ color: #000000d9;
68
+ background-color: #fafafa;
69
+ border: 1px solid #d9d9d9;
70
+ border-radius: 2px;
71
+ align-items: center;
72
+ gap: 4px;
73
+ height: 24px;
74
+ padding: 0 8px;
75
+ font-size: 12px;
76
+ display: inline-flex;
77
+ }
78
+
79
+ .timePickerSelect_select-xuD_LK .arco-tag .arco-tag-content {
80
+ line-height: 1;
81
+ }
82
+
83
+ .timePickerSelect_select-xuD_LK .arco-tag .arco-tag-icon-hover {
84
+ color: #00000073;
85
+ justify-content: center;
86
+ align-items: center;
87
+ width: 12px;
88
+ height: 12px;
89
+ margin-left: 0;
90
+ transition: color .2s;
91
+ display: flex;
92
+ }
93
+
94
+ .timePickerSelect_select-xuD_LK .arco-tag .arco-tag-icon-hover:hover {
95
+ color: #000000a6;
96
+ }
97
+
98
+ .timePickerSelect_select-xuD_LK .arco-tag .arco-tag-icon-hover svg {
99
+ font-size: 12px;
100
+ }
101
+
102
+ .dropdownPopup-oUQ8vz .arco-select-popup {
103
+ box-shadow: none;
104
+ background: none;
105
+ border: none;
106
+ padding: 0;
107
+ }
108
+
109
+ .dropdownContent-OfV283 {
110
+ background-color: #fff;
111
+ border: 1px solid #d9d9d9;
112
+ border-radius: 2px;
113
+ min-width: 320px;
114
+ padding: 8px;
115
+ box-shadow: 0 2px 8px #0000001a;
116
+ }
117
+
118
+ .dropdownHeader-nILpAL {
119
+ border-bottom: 1px solid #fafafa;
120
+ justify-content: space-between;
121
+ align-items: center;
122
+ height: 32px;
123
+ margin-bottom: 8px;
124
+ padding-bottom: 8px;
125
+ display: flex;
126
+ }
127
+
128
+ .dropdownHeader-nILpAL .selectAll-H78Ezl {
129
+ cursor: pointer;
130
+ }
131
+
132
+ .dropdownHeader-nILpAL .selectAll-H78Ezl .arco-checkbox {
133
+ margin-right: 0;
134
+ }
135
+
136
+ .dropdownHeader-nILpAL .selectAll-H78Ezl .arco-checkbox-text {
137
+ margin-left: 4px;
138
+ }
139
+
140
+ .dropdownHeader-nILpAL .selectAll-H78Ezl .selectAllText-XhWUCP {
141
+ color: #1890ff;
142
+ font-size: 14px;
143
+ }
144
+
145
+ .dropdownHeader-nILpAL .clearBtn-aUkoKx {
146
+ color: #00000073;
147
+ cursor: pointer;
148
+ font-size: 14px;
149
+ transition: color .2s;
150
+ }
151
+
152
+ .dropdownHeader-nILpAL .clearBtn-aUkoKx:hover {
153
+ color: #1890ff;
154
+ }
155
+
156
+ .optionsGrid-aFw9nI {
157
+ gap: 8px;
158
+ max-height: 256px;
159
+ display: grid;
160
+ overflow-y: auto;
161
+ }
162
+
163
+ .optionCheckbox-FLZ7GF {
164
+ border-radius: 2px;
165
+ align-items: center;
166
+ height: 32px;
167
+ margin: 0;
168
+ padding: 0 4px;
169
+ transition: background-color .2s;
170
+ display: flex;
171
+ }
172
+
173
+ .optionCheckbox-FLZ7GF:hover {
174
+ background-color: #fafafa;
175
+ }
176
+
177
+ .optionCheckbox-FLZ7GF .arco-checkbox-inner {
178
+ border-color: #d9d9d9;
179
+ border-radius: 2px;
180
+ width: 16px;
181
+ height: 16px;
182
+ }
183
+
184
+ .optionCheckbox-FLZ7GF .arco-checkbox-inner:after {
185
+ border-width: 2px;
186
+ width: 5px;
187
+ height: 9px;
188
+ top: 46%;
189
+ left: 24%;
190
+ }
191
+
192
+ .optionCheckbox-FLZ7GF.optionCheckboxSelected-FFTvH6 .arco-checkbox-inner {
193
+ background-color: #1890ff;
194
+ border-color: #1890ff;
195
+ }
196
+
197
+ .optionCheckbox-FLZ7GF.optionCheckboxDisabled-lcXcnC {
198
+ opacity: .5;
199
+ cursor: not-allowed;
200
+ }
201
+
202
+ .optionCheckbox-FLZ7GF.optionCheckboxDisabled-lcXcnC .arco-checkbox-inner {
203
+ background-color: #fafafa;
204
+ border-color: #d9d9d9;
205
+ }
206
+
207
+ .optionCheckbox-FLZ7GF .arco-checkbox-text {
208
+ margin-left: 4px;
209
+ }
210
+
211
+ .optionLabel-KSY4BV {
212
+ color: #000000d9;
213
+ user-select: none;
214
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif;
215
+ font-size: 14px;
216
+ }
217
+
218
+ .optionsGrid-aFw9nI::-webkit-scrollbar {
219
+ width: 6px;
220
+ }
221
+
222
+ .optionsGrid-aFw9nI::-webkit-scrollbar-track {
223
+ background: none;
224
+ }
225
+
226
+ .optionsGrid-aFw9nI::-webkit-scrollbar-thumb {
227
+ background: #d9d9d9;
228
+ border-radius: 3px;
229
+ }
230
+
231
+ .optionsGrid-aFw9nI::-webkit-scrollbar-thumb:hover {
232
+ background: #00000073;
233
+ }
234
+
@@ -0,0 +1,65 @@
1
+ /**
2
+ * 时间选项
3
+ */
4
+ export interface TimeOption {
5
+ /** 选项标签 */
6
+ label: string;
7
+ /** 选项值 */
8
+ value: string | number;
9
+ /** 是否禁用 */
10
+ disabled?: boolean;
11
+ }
12
+ /**
13
+ * TimePickerSelect 组件属性
14
+ */
15
+ export interface TimePickerSelectProps {
16
+ /** 时间选项列表 */
17
+ options?: TimeOption[];
18
+ /** 选中的值(受控模式) */
19
+ value?: string[] | number[];
20
+ /** 默认选中的值(非受控模式) */
21
+ defaultValue?: string[] | number[];
22
+ /** 选中的值改变时的回调 */
23
+ onChange?: (value: string[] | number[], options: TimeOption[]) => void;
24
+ /** 占位符文本 */
25
+ placeholder?: string;
26
+ /** 是否禁用 */
27
+ disabled?: boolean;
28
+ /** 样式类名 */
29
+ className?: string;
30
+ /** 内联样式 */
31
+ style?: React.CSSProperties;
32
+ /** 下拉框样式类名 */
33
+ dropdownClassName?: string;
34
+ /** 下拉框样式 */
35
+ dropdownStyle?: React.CSSProperties;
36
+ /** 最多显示的标签数量 */
37
+ maxTagCount?: number;
38
+ /** 是否显示全选/清空 */
39
+ showSelectAll?: boolean;
40
+ /** 全选文本 */
41
+ selectAllText?: string;
42
+ /** 清空文本 */
43
+ clearText?: string;
44
+ /** 标签文本 */
45
+ label?: string;
46
+ /** 每行显示的选项数量 */
47
+ columnCount?: number;
48
+ }
49
+ /**
50
+ * 预设时间间隔(分钟)
51
+ */
52
+ export type TimeInterval = 15 | 30 | 60;
53
+ /**
54
+ * 生成时间选项的辅助函数配置
55
+ */
56
+ export interface GenerateTimeOptionsConfig {
57
+ /** 开始时间(小时,0-23) */
58
+ startHour?: number;
59
+ /** 结束时间(小时,0-23) */
60
+ endHour?: number;
61
+ /** 时间间隔(分钟) */
62
+ interval?: TimeInterval;
63
+ /** 时间格式 */
64
+ format?: string;
65
+ }
File without changes
package/dist/index.d.ts CHANGED
@@ -3,3 +3,5 @@ export type { ActionButtonProps, } from "./ActionButton/interface";
3
3
  export { default as ActionButton } from "./ActionButton";
4
4
  export { default as CompareChange } from "./CompareChange";
5
5
  export { Sticky, StickyContainer } from "./ReactSticky";
6
+ export { default as TimePickerSelect, generateTimeOptions, defaultTimeOptions, } from "./TimePickerSelect";
7
+ export type { TimePickerSelectProps, TimeOption, TimeInterval, GenerateTimeOptionsConfig, } from "./TimePickerSelect";
package/dist/index.js CHANGED
@@ -2,4 +2,5 @@ import { ActionButtonType } from "./ActionButton/interface.js";
2
2
  import ActionButton from "./ActionButton/index.js";
3
3
  import CompareChange from "./CompareChange/index.js";
4
4
  import { Sticky, StickyContainer } from "./ReactSticky/index.js";
5
- export { ActionButton, ActionButtonType, CompareChange, Sticky, StickyContainer };
5
+ import TimePickerSelect, { defaultTimeOptions, generateTimeOptions } from "./TimePickerSelect/index.js";
6
+ export { ActionButton, ActionButtonType, CompareChange, Sticky, StickyContainer, TimePickerSelect, defaultTimeOptions, generateTimeOptions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@publishfx/publish-components",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "A React UI component library for the Publish platform, including ActionButton component",
5
5
  "type": "module",
6
6
  "keywords": [