@gcsa/console-react 0.1.2 → 0.1.3
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/dist/GcsaCascader.js +19 -18
- package/dist/GcsaCascader.js.map +1 -1
- package/dist/GcsaPopover.d.ts +3 -1
- package/dist/GcsaPopover.js +30 -29
- package/dist/GcsaPopover.js.map +1 -1
- package/dist/GcsaTransfer.js +72 -57
- package/dist/GcsaTransfer.js.map +1 -1
- package/dist/GcsaUpload.js +1 -1
- package/dist/GcsaUpload.js.map +1 -1
- package/dist/icons/iconNames.d.ts +2 -2
- package/dist/icons/iconNames.js +1 -0
- package/dist/icons/iconNames.js.map +1 -1
- package/dist/icons/registry.d.ts +1 -1
- package/dist/icons/registry.js +38 -35
- package/dist/icons/registry.js.map +1 -1
- package/dist/icons/svg/result-empty.svg.js +12 -2
- package/dist/icons/svg/result-empty.svg.js.map +1 -1
- package/dist/icons/svg/upload.svg.js +10 -0
- package/dist/icons/svg/upload.svg.js.map +1 -0
- package/dist/icons/svg/users.svg.js.map +1 -1
- package/dist/style.css +223 -140
- package/package.json +3 -3
- package/src/GcsaCascader.tsx +1 -0
- package/src/GcsaPopover.tsx +4 -1
- package/src/GcsaTransfer.tsx +41 -13
- package/src/GcsaUpload.tsx +1 -1
- package/src/icons/iconNames.ts +1 -0
- package/src/icons/registry.ts +3 -1
- package/src/icons/svg/result-empty.svg +11 -1
- package/src/icons/svg/upload.svg +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gcsa/console-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "GCSA console UI — React components (Ark UI + TanStack + GCSA styles)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"@tanstack/react-form": "^1.12.2",
|
|
35
35
|
"@tanstack/react-table": "^8.21.3",
|
|
36
36
|
"zod": "^3.24.4",
|
|
37
|
-
"@gcsa/console-
|
|
38
|
-
"@gcsa/console-
|
|
37
|
+
"@gcsa/console-core": "0.1.3",
|
|
38
|
+
"@gcsa/console-styles": "0.1.3"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"react": "^18.0.0 || ^19.0.0",
|
package/src/GcsaCascader.tsx
CHANGED
package/src/GcsaPopover.tsx
CHANGED
|
@@ -22,6 +22,8 @@ export type GcsaPopoverProps = {
|
|
|
22
22
|
/** 受控开关;不传则为非受控 */
|
|
23
23
|
open?: boolean;
|
|
24
24
|
onOpenChange?: (open: boolean) => void;
|
|
25
|
+
/** 启用 size middleware,写入 --reference-width */
|
|
26
|
+
fitViewport?: boolean;
|
|
25
27
|
/** 预设尺寸;与 minWidth / maxWidth / width 可同时使用,inline 优先生效 */
|
|
26
28
|
size?: GcsaPopoverSize;
|
|
27
29
|
/** 面板宽度,如 560 或 '560px' */
|
|
@@ -46,6 +48,7 @@ export function GcsaPopover({
|
|
|
46
48
|
gutter = 8,
|
|
47
49
|
open,
|
|
48
50
|
onOpenChange,
|
|
51
|
+
fitViewport = false,
|
|
49
52
|
size = 'default',
|
|
50
53
|
width,
|
|
51
54
|
minWidth,
|
|
@@ -107,7 +110,7 @@ export function GcsaPopover({
|
|
|
107
110
|
open={resolvedOpen}
|
|
108
111
|
lazyMount
|
|
109
112
|
unmountOnExit
|
|
110
|
-
positioning={createGcsaPopupPositioning({ placement, gutter })}
|
|
113
|
+
positioning={createGcsaPopupPositioning({ placement, gutter, fitViewport })}
|
|
111
114
|
onOpenChange={details => handleOpenChange(details.open)}
|
|
112
115
|
>
|
|
113
116
|
<Popover.Trigger asChild>{triggerNode}</Popover.Trigger>
|
package/src/GcsaTransfer.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { useMemo, useState } from 'react';
|
|
1
|
+
import { useMemo, useState, type KeyboardEvent } from 'react';
|
|
2
2
|
import type { GcsaTransferOption } from '@gcsa/console-core';
|
|
3
|
+
import { GcsaCheckbox } from './GcsaCheckbox';
|
|
3
4
|
import { GcsaInput } from './GcsaInput';
|
|
4
5
|
import { useGcsaLocaleMessages } from './hooks/useGcsaLocale';
|
|
5
6
|
|
|
@@ -29,6 +30,7 @@ export function GcsaTransfer({
|
|
|
29
30
|
const [targetSelected, setTargetSelected] = useState<string[]>([]);
|
|
30
31
|
const [sourceQuery, setSourceQuery] = useState('');
|
|
31
32
|
const [targetQuery, setTargetQuery] = useState('');
|
|
33
|
+
|
|
32
34
|
const availableItems = useMemo(
|
|
33
35
|
() =>
|
|
34
36
|
options.filter(
|
|
@@ -38,6 +40,7 @@ export function GcsaTransfer({
|
|
|
38
40
|
),
|
|
39
41
|
[options, sourceQuery, value]
|
|
40
42
|
);
|
|
43
|
+
|
|
41
44
|
const targetItems = useMemo(
|
|
42
45
|
() =>
|
|
43
46
|
options.filter(
|
|
@@ -47,18 +50,28 @@ export function GcsaTransfer({
|
|
|
47
50
|
),
|
|
48
51
|
[options, targetQuery, value]
|
|
49
52
|
);
|
|
53
|
+
|
|
50
54
|
const update = (next: string[]) => {
|
|
51
55
|
onValueChange?.(next);
|
|
52
56
|
onChange?.(next);
|
|
53
57
|
setSourceSelected([]);
|
|
54
58
|
setTargetSelected([]);
|
|
55
59
|
};
|
|
56
|
-
|
|
60
|
+
|
|
61
|
+
const setSelected = (key: string, side: 'source' | 'target', checked: boolean) => {
|
|
62
|
+
const setter = side === 'source' ? setSourceSelected : setTargetSelected;
|
|
63
|
+
setter(current => {
|
|
64
|
+
if (checked) return current.includes(key) ? current : [...current, key];
|
|
65
|
+
return current.filter(item => item !== key);
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const onItemActivate = (item: GcsaTransferOption, side: 'source' | 'target') => {
|
|
70
|
+
if (disabled || item.disabled) return;
|
|
57
71
|
const current = side === 'source' ? sourceSelected : targetSelected;
|
|
58
|
-
|
|
59
|
-
if (side === 'source') setSourceSelected(next);
|
|
60
|
-
else setTargetSelected(next);
|
|
72
|
+
setSelected(item.value, side, !current.includes(item.value));
|
|
61
73
|
};
|
|
74
|
+
|
|
62
75
|
const panel = (items: GcsaTransferOption[], title: string, side: 'source' | 'target') => (
|
|
63
76
|
<section className="gcsa-transfer__panel" aria-label={title}>
|
|
64
77
|
<header className="gcsa-transfer__header">
|
|
@@ -77,21 +90,35 @@ export function GcsaTransfer({
|
|
|
77
90
|
{items.length ? (
|
|
78
91
|
items.map(item => {
|
|
79
92
|
const selected = (side === 'source' ? sourceSelected : targetSelected).includes(item.value);
|
|
93
|
+
const itemDisabled = disabled || Boolean(item.disabled);
|
|
94
|
+
const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
|
|
95
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
onItemActivate(item, side);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const onRowClick = () => onItemActivate(item, side);
|
|
80
101
|
return (
|
|
81
|
-
<
|
|
102
|
+
<div
|
|
82
103
|
key={item.value}
|
|
83
|
-
type="button"
|
|
84
104
|
className={`gcsa-transfer__item gcsa-focus-ring${selected ? ' gcsa-transfer__item--selected' : ''}`}
|
|
85
|
-
disabled={disabled || item.disabled}
|
|
86
105
|
role="option"
|
|
106
|
+
tabIndex={itemDisabled ? -1 : 0}
|
|
87
107
|
aria-selected={selected}
|
|
88
|
-
|
|
108
|
+
aria-disabled={itemDisabled || undefined}
|
|
109
|
+
onClick={onRowClick}
|
|
110
|
+
onKeyDown={onKeyDown}
|
|
89
111
|
>
|
|
90
|
-
<span className="gcsa-transfer__check"
|
|
91
|
-
|
|
112
|
+
<span className="gcsa-transfer__check-wrap" onClick={event => event.stopPropagation()}>
|
|
113
|
+
<GcsaCheckbox
|
|
114
|
+
checked={selected}
|
|
115
|
+
disabled={itemDisabled}
|
|
116
|
+
ariaLabel={item.label}
|
|
117
|
+
onCheckedChange={checked => setSelected(item.value, side, checked)}
|
|
118
|
+
/>
|
|
92
119
|
</span>
|
|
93
|
-
<span>{item.label}</span>
|
|
94
|
-
</
|
|
120
|
+
<span className="gcsa-transfer__label">{item.label}</span>
|
|
121
|
+
</div>
|
|
95
122
|
);
|
|
96
123
|
})
|
|
97
124
|
) : (
|
|
@@ -100,6 +127,7 @@ export function GcsaTransfer({
|
|
|
100
127
|
</div>
|
|
101
128
|
</section>
|
|
102
129
|
);
|
|
130
|
+
|
|
103
131
|
return (
|
|
104
132
|
<div className={`gcsa-transfer${disabled ? ' gcsa-transfer--disabled' : ''}`}>
|
|
105
133
|
{panel(availableItems, resolvedSourceTitle, 'source')}
|
package/src/GcsaUpload.tsx
CHANGED
|
@@ -152,7 +152,7 @@ export function GcsaUpload({
|
|
|
152
152
|
onDrop={onDrop}
|
|
153
153
|
>
|
|
154
154
|
<span className="gcsa-upload__icon" aria-hidden="true">
|
|
155
|
-
<GcsaIcon name="
|
|
155
|
+
<GcsaIcon name="upload" />
|
|
156
156
|
</span>
|
|
157
157
|
<span className="gcsa-upload__title">{resolvedButtonLabel}</span>
|
|
158
158
|
{resolvedHint ? <p className="gcsa-upload__hint">{resolvedHint}</p> : null}
|
package/src/icons/iconNames.ts
CHANGED
package/src/icons/registry.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { GCSA_ICON_NAMES, type GcsaIconName } from './iconNames';
|
|
2
2
|
import chevronLeftSvg from './svg/chevron-left.svg?raw';
|
|
3
3
|
import menuSvg from './svg/menu.svg?raw';
|
|
4
|
+
import uploadSvg from './svg/upload.svg?raw';
|
|
4
5
|
|
|
5
6
|
const svgModules = import.meta.glob('./svg/*.svg', {
|
|
6
7
|
query: '?raw',
|
|
@@ -22,7 +23,8 @@ const registry = {
|
|
|
22
23
|
Object.entries(svgModules).map(([path, svg]) => [toIconKey(fileStem(path)), svg])
|
|
23
24
|
),
|
|
24
25
|
menu: menuSvg,
|
|
25
|
-
chevronLeft: chevronLeftSvg
|
|
26
|
+
chevronLeft: chevronLeftSvg,
|
|
27
|
+
upload: uploadSvg
|
|
26
28
|
} as Record<GcsaIconName, string>;
|
|
27
29
|
|
|
28
30
|
for (const name of GCSA_ICON_NAMES) {
|
|
@@ -1 +1,11 @@
|
|
|
1
|
-
<svg viewBox="0 0
|
|
1
|
+
<svg width="66" height="66" viewBox="0 0 66 66" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<ellipse cx="33" cy="53" rx="33" ry="8" fill="#00BBCC" fill-opacity="0.1"/>
|
|
3
|
+
<path d="M35 19.5L12 26V49L35 47.5V19.5Z" fill="#00BBCC" fill-opacity="0.3"/>
|
|
4
|
+
<path d="M55 46.5V25L35 19.5V42L55 46.5Z" fill="#00BBCC" fill-opacity="0.4"/>
|
|
5
|
+
<path d="M54.4179 7.58906L57 9.00955L54.4106 10.4173L52.9909 13L51.5821 10.4109L49 8.99045L51.5894 7.5827L53.0091 5L54.4179 7.58906Z" fill="#00BBCC" fill-opacity="0.4"/>
|
|
6
|
+
<path d="M32 56.0806V32L55 25V48L32 56.0806Z" fill="#7CDBE4"/>
|
|
7
|
+
<path d="M32 56.0806V32L12 26V49L32 56.0806Z" fill="#97E3EA"/>
|
|
8
|
+
<path d="M25 7.5L35 19.5L12 26L2 14L25 7.5Z" fill="#CCF1F5"/>
|
|
9
|
+
<circle cx="35" cy="17.5" r="9" fill="#00BBCC"/>
|
|
10
|
+
<path d="M34.4 19.875V18.625H35C36.02 18.625 36.8 17.8125 36.8 16.75V16.125C36.8 15.0625 36.02 14.25 35 14.25C33.98 14.25 33.2 15.0625 33.2 16.125V16.75H32V16.125C32 14.375 33.32 13 35 13C36.68 13 38 14.375 38 16.125V16.75C38 18.25 36.98 19.5 35.6 19.8125V21.125H34.4V19.875ZM34.4 21.75H35.6V23H34.4V21.75Z" fill="white"/>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
2
|
+
<path d="M32.5 20.2C31.4 15.7 27.5 12.5 22.8 12.5C18.6 12.5 15 15 13.5 18.6C10 19.1 7.5 22.1 7.5 25.7C7.5 29.6 10.7 32.8 14.6 32.8H32.2C35.6 32.8 38.5 30 38.5 26.5C38.5 23.3 35.9 20.7 32.5 20.2Z" stroke="currentColor" stroke-width="1.75" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M24 22.5V36" stroke="currentColor" stroke-width="1.75" stroke-linecap="round"/>
|
|
4
|
+
<path d="M19.5 27L24 22.5L28.5 27" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|