@gcsa/console-react 0.1.2 → 0.1.4

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,117 +1,126 @@
1
- import { jsxs as o, jsx as e, Fragment as k } from "react/jsx-runtime";
2
- import { useRef as w, useMemo as z } from "react";
3
- import { createListCollection as R } from "@ark-ui/react/collection";
4
- import { Select as t } from "@ark-ui/react/select";
5
- import { Portal as j } from "@ark-ui/react/portal";
6
- import { formatGcsaLocaleMessage as E, createGcsaPopupPositioning as F, gcsaControlSizeClass as O } from "@gcsa/console-core";
7
- import { GcsaIcon as P } from "./GcsaIcon.js";
8
- import { useGcsaLocaleMessages as $ } from "./hooks/useGcsaLocale.js";
9
- import { useGcsaPopupZIndex as B } from "./hooks/useGcsaPopupZIndex.js";
10
- import { useGcsaComponentSize as Z } from "./hooks/useGcsaComponentSize.js";
11
- import { preserveDrawerScrollFrom as q } from "./utils/preserveDrawerScroll.js";
12
- function C({
13
- collection: r,
1
+ import { jsxs as r, jsx as e, Fragment as j } from "react/jsx-runtime";
2
+ import { useRef as B, useState as E, useMemo as z } from "react";
3
+ import { createListCollection as F } from "@ark-ui/react/collection";
4
+ import { Select as s } from "@ark-ui/react/select";
5
+ import { Portal as O } from "@ark-ui/react/portal";
6
+ import { formatGcsaLocaleMessage as W, createGcsaPopupPositioning as Z, gcsaControlSizeClass as q } from "@gcsa/console-core";
7
+ import { GcsaIcon as b } from "./GcsaIcon.js";
8
+ import { useGcsaLocaleMessages as A } from "./hooks/useGcsaLocale.js";
9
+ import { useGcsaPopupZIndex as J } from "./hooks/useGcsaPopupZIndex.js";
10
+ import { useGcsaComponentSize as K } from "./hooks/useGcsaComponentSize.js";
11
+ import { preserveDrawerScrollFrom as Q } from "./utils/preserveDrawerScroll.js";
12
+ function P({
13
+ collection: i,
14
14
  contentStyle: c,
15
- showListHint: u,
16
- listHintText: g,
17
- empty: n,
18
- emptyText: d
15
+ showListHint: d,
16
+ listHintText: h,
17
+ empty: o,
18
+ emptyText: p
19
19
  }) {
20
- return /* @__PURE__ */ e(t.Content, { className: "gcsa-select-content gcsa-ui-surface", style: c, children: n ? /* @__PURE__ */ e("div", { className: "gcsa-select-empty", role: "status", children: /* @__PURE__ */ e("span", { className: "gcsa-select-empty__text", children: d }) }) : /* @__PURE__ */ o(k, { children: [
21
- /* @__PURE__ */ e(t.List, { className: "gcsa-select-list", children: r.group().map(([l, i]) => /* @__PURE__ */ o(t.ItemGroup, { className: "gcsa-select-group", children: [
22
- l ? /* @__PURE__ */ e(t.ItemGroupLabel, { className: "gcsa-select-group__label", children: l }) : null,
23
- i.map((a) => /* @__PURE__ */ o(t.Item, { item: a, className: "gcsa-select-item", children: [
24
- /* @__PURE__ */ e(t.ItemText, { className: "gcsa-select-item__text", children: a.label }),
25
- /* @__PURE__ */ e(t.ItemIndicator, { className: "gcsa-select-item__check", children: /* @__PURE__ */ e(P, { name: "check", size: "sm", className: "gcsa-select-item__check-icon" }) })
26
- ] }, a.value))
20
+ return /* @__PURE__ */ e(s.Content, { className: "gcsa-select-content gcsa-ui-surface", style: c, children: o ? /* @__PURE__ */ e("div", { className: "gcsa-select-empty", role: "status", children: /* @__PURE__ */ e("span", { className: "gcsa-select-empty__text", children: p }) }) : /* @__PURE__ */ r(j, { children: [
21
+ /* @__PURE__ */ e(s.List, { className: "gcsa-select-list", children: i.group().map(([l, a]) => /* @__PURE__ */ r(s.ItemGroup, { className: "gcsa-select-group", children: [
22
+ l ? /* @__PURE__ */ e(s.ItemGroupLabel, { className: "gcsa-select-group__label", children: l }) : null,
23
+ a.map((n) => /* @__PURE__ */ r(s.Item, { item: n, className: "gcsa-select-item", children: [
24
+ /* @__PURE__ */ e(s.ItemText, { className: "gcsa-select-item__text", children: n.label }),
25
+ /* @__PURE__ */ e(s.ItemIndicator, { className: "gcsa-select-item__check", children: /* @__PURE__ */ e(b, { name: "check", size: "sm", className: "gcsa-select-item__check-icon" }) })
26
+ ] }, n.value))
27
27
  ] }, l || "default")) }),
28
- u ? /* @__PURE__ */ e("div", { className: "gcsa-select-hint", children: g }) : null
28
+ d ? /* @__PURE__ */ e("div", { className: "gcsa-select-hint", children: h }) : null
29
29
  ] }) });
30
30
  }
31
- function se({
32
- value: r,
31
+ function ie({
32
+ value: i,
33
33
  options: c,
34
- placeholder: u,
35
- invalid: g,
36
- placement: n = "bottom-start",
37
- listMaxHeight: d = 280,
34
+ placeholder: d,
35
+ invalid: h,
36
+ placement: o = "bottom-start",
37
+ listMaxHeight: p = 280,
38
38
  listHintThreshold: l = 16,
39
- groupOrder: i,
40
- portalled: a = !0,
41
- sameWidth: f = !0,
42
- size: b,
43
- onValueChange: p
39
+ groupOrder: a,
40
+ portalled: n = !0,
41
+ sameWidth: m = !0,
42
+ size: L,
43
+ onValueChange: f
44
44
  }) {
45
- const N = w(null), L = Z(b), x = $(), { zIndex: m, onOpenChange: D } = B(), y = c.some((s) => s.group), h = z(
46
- () => R({
45
+ const N = B(null), [g, M] = E(), D = K(L), y = A(), { zIndex: u, onOpenChange: H } = J(), S = c.some((t) => t.group), x = z(
46
+ () => F({
47
47
  items: c,
48
- itemToValue: (s) => s.value,
49
- itemToString: (s) => s.label,
50
- isItemDisabled: (s) => s.disabled ?? !1,
51
- ...y ? {
52
- groupBy: (s) => s.group ?? "",
53
- groupSort: i ?? "asc"
48
+ itemToValue: (t) => t.value,
49
+ itemToString: (t) => t.label,
50
+ isItemDisabled: (t) => t.disabled ?? !1,
51
+ ...S ? {
52
+ groupBy: (t) => t.group ?? "",
53
+ groupSort: a ?? "asc"
54
54
  } : {}
55
55
  }),
56
- [c, y, i]
57
- ), H = r == null ? [] : [r], v = c.length >= l, S = E(x.selectListHint, { count: c.length }), _ = x.emptyDefault, I = c.length === 0, G = {
58
- "--gcsa-select-list-max-height": `${d}px`,
59
- ...m == null ? {} : { zIndex: m }
60
- }, T = m == null ? void 0 : { zIndex: m }, M = z(
61
- () => F({ placement: n, sameWidth: f, gutter: 4 }),
62
- [n, f]
56
+ [c, S, a]
57
+ ), R = () => {
58
+ var C;
59
+ const t = (C = N.current) == null ? void 0 : C.getBoundingClientRect().width;
60
+ t && M(Math.round(t));
61
+ }, k = i == null ? [] : [i], v = c.length >= l, _ = W(y.selectListHint, { count: c.length }), I = y.emptyDefault, G = c.length === 0, T = {
62
+ "--gcsa-select-list-max-height": `${p}px`,
63
+ ...u == null ? {} : { zIndex: u },
64
+ ...m && g != null ? {
65
+ width: g,
66
+ minWidth: g,
67
+ "--reference-width": `${g}px`
68
+ } : {}
69
+ }, w = u == null ? void 0 : { zIndex: u }, $ = z(
70
+ () => Z({ placement: o, sameWidth: m, gutter: 4 }),
71
+ [o, m]
63
72
  );
64
- return /* @__PURE__ */ o(
65
- t.Root,
73
+ return /* @__PURE__ */ r(
74
+ s.Root,
66
75
  {
67
- collection: h,
68
- value: H,
69
- positioning: M,
76
+ collection: x,
77
+ value: k,
78
+ positioning: $,
70
79
  lazyMount: !0,
71
80
  unmountOnExit: !0,
72
- onOpenChange: (s) => {
73
- D(s.open), q(N.current);
81
+ onOpenChange: (t) => {
82
+ t.open && m && R(), H(t.open), Q(N.current);
74
83
  },
75
- onValueChange: (s) => p == null ? void 0 : p(s.value[0] ?? ""),
84
+ onValueChange: (t) => f == null ? void 0 : f(t.value[0] ?? ""),
76
85
  children: [
77
- /* @__PURE__ */ e(t.Control, { ref: N, className: "gcsa-select-control", children: /* @__PURE__ */ o(
78
- t.Trigger,
86
+ /* @__PURE__ */ e(s.Control, { ref: N, className: "gcsa-select-control", children: /* @__PURE__ */ r(
87
+ s.Trigger,
79
88
  {
80
- className: `gcsa-select-trigger gcsa-focus-ring ${O("gcsa-select-trigger", L)}`,
81
- "data-invalid": g || void 0,
89
+ className: `gcsa-select-trigger gcsa-focus-ring ${q("gcsa-select-trigger", D)}`,
90
+ "data-invalid": h || void 0,
82
91
  children: [
83
- /* @__PURE__ */ e(t.ValueText, { className: "gcsa-select-value", placeholder: u }),
84
- /* @__PURE__ */ e(t.Indicator, { className: "gcsa-select-indicator", "aria-hidden": "true", children: /* @__PURE__ */ e(P, { name: "chevronDown", className: "gcsa-select-indicator__icon" }) })
92
+ /* @__PURE__ */ e(s.ValueText, { className: "gcsa-select-value", placeholder: d }),
93
+ /* @__PURE__ */ e(s.Indicator, { className: "gcsa-select-indicator", "aria-hidden": "true", children: /* @__PURE__ */ e(b, { name: "chevronDown", className: "gcsa-select-indicator__icon" }) })
85
94
  ]
86
95
  }
87
96
  ) }),
88
- a ? /* @__PURE__ */ e(j, { children: /* @__PURE__ */ e(t.Positioner, { style: T, children: /* @__PURE__ */ e(
89
- C,
97
+ n ? /* @__PURE__ */ e(O, { children: /* @__PURE__ */ e(s.Positioner, { style: w, children: /* @__PURE__ */ e(
98
+ P,
90
99
  {
91
- collection: h,
92
- contentStyle: G,
100
+ collection: x,
101
+ contentStyle: T,
93
102
  showListHint: v,
94
- listHintText: S,
95
- empty: I,
96
- emptyText: _
103
+ listHintText: _,
104
+ empty: G,
105
+ emptyText: I
97
106
  }
98
- ) }) }) : /* @__PURE__ */ e(t.Positioner, { style: T, children: /* @__PURE__ */ e(
99
- C,
107
+ ) }) }) : /* @__PURE__ */ e(s.Positioner, { style: w, children: /* @__PURE__ */ e(
108
+ P,
100
109
  {
101
- collection: h,
102
- contentStyle: G,
110
+ collection: x,
111
+ contentStyle: T,
103
112
  showListHint: v,
104
- listHintText: S,
105
- empty: I,
106
- emptyText: _
113
+ listHintText: _,
114
+ empty: G,
115
+ emptyText: I
107
116
  }
108
117
  ) }),
109
- /* @__PURE__ */ e(t.HiddenSelect, {})
118
+ /* @__PURE__ */ e(s.HiddenSelect, {})
110
119
  ]
111
120
  }
112
121
  );
113
122
  }
114
123
  export {
115
- se as GcsaSelect
124
+ ie as GcsaSelect
116
125
  };
117
126
  //# sourceMappingURL=GcsaSelect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GcsaSelect.js","sources":["../src/GcsaSelect.tsx"],"sourcesContent":["import { useMemo, useRef, type CSSProperties } from 'react';\nimport { createListCollection } from '@ark-ui/react/collection';\nimport { Select } from '@ark-ui/react/select';\nimport { Portal } from '@ark-ui/react/portal';\nimport type { GcsaPopupPlacement, GcsaSelectOption, GcsaSelectSize } from '@gcsa/console-core';\nimport { createGcsaPopupPositioning, formatGcsaLocaleMessage, gcsaControlSizeClass } from '@gcsa/console-core';\nimport { GcsaIcon } from './GcsaIcon';\nimport { useGcsaLocaleMessages } from './hooks/useGcsaLocale';\nimport { useGcsaPopupZIndex } from './hooks/useGcsaPopupZIndex';\nimport { useGcsaComponentSize } from './hooks/useGcsaComponentSize';\nimport { preserveDrawerScrollFrom } from './utils/preserveDrawerScroll';\n\nexport type GcsaSelectPlacement = GcsaPopupPlacement;\n\nexport type GcsaSelectProps = {\n value: string;\n options: GcsaSelectOption[];\n placeholder?: string;\n invalid?: boolean;\n /** 下拉相对触发器的初始方位 */\n placement?: GcsaSelectPlacement;\n listMaxHeight?: number;\n listHintThreshold?: number;\n groupOrder?: string[];\n /** 是否挂载到 body;嵌套浮层(如 DatePicker 内)应设为 false */\n portalled?: boolean;\n /** 下拉面板是否与触发器同宽 */\n sameWidth?: boolean;\n size?: GcsaSelectSize;\n onValueChange?: (value: string) => void;\n};\n\nfunction SelectContent({\n collection,\n contentStyle,\n showListHint,\n listHintText,\n empty,\n emptyText\n}: {\n collection: ReturnType<typeof createListCollection<GcsaSelectOption>>;\n contentStyle: CSSProperties;\n showListHint: boolean;\n listHintText: string;\n empty: boolean;\n emptyText: string;\n}) {\n return (\n <Select.Content className=\"gcsa-select-content gcsa-ui-surface\" style={contentStyle}>\n {empty ? (\n <div className=\"gcsa-select-empty\" role=\"status\">\n <span className=\"gcsa-select-empty__text\">{emptyText}</span>\n </div>\n ) : (\n <>\n <Select.List className=\"gcsa-select-list\">\n {collection.group().map(([groupLabel, groupItems]) => (\n <Select.ItemGroup key={groupLabel || 'default'} className=\"gcsa-select-group\">\n {groupLabel ? (\n <Select.ItemGroupLabel className=\"gcsa-select-group__label\">\n {groupLabel}\n </Select.ItemGroupLabel>\n ) : null}\n {groupItems.map(opt => (\n <Select.Item key={opt.value} item={opt} className=\"gcsa-select-item\">\n <Select.ItemText className=\"gcsa-select-item__text\">{opt.label}</Select.ItemText>\n <Select.ItemIndicator className=\"gcsa-select-item__check\">\n <GcsaIcon name=\"check\" size=\"sm\" className=\"gcsa-select-item__check-icon\" />\n </Select.ItemIndicator>\n </Select.Item>\n ))}\n </Select.ItemGroup>\n ))}\n </Select.List>\n {showListHint ? <div className=\"gcsa-select-hint\">{listHintText}</div> : null}\n </>\n )}\n </Select.Content>\n );\n}\n\nexport function GcsaSelect({\n value,\n options,\n placeholder,\n invalid,\n placement = 'bottom-start',\n listMaxHeight = 280,\n listHintThreshold = 16,\n groupOrder,\n portalled = true,\n sameWidth = true,\n size,\n onValueChange\n}: GcsaSelectProps) {\n const controlRef = useRef<HTMLDivElement>(null);\n const resolvedSize = useGcsaComponentSize(size);\n const messages = useGcsaLocaleMessages();\n const { zIndex, onOpenChange } = useGcsaPopupZIndex();\n const hasGroups = options.some(item => item.group);\n\n const collection = useMemo(\n () =>\n createListCollection({\n items: options,\n itemToValue: item => item.value,\n itemToString: item => item.label,\n isItemDisabled: item => item.disabled ?? false,\n ...(hasGroups\n ? {\n groupBy: (item: GcsaSelectOption) => item.group ?? '',\n groupSort: groupOrder ?? ('asc' as const)\n }\n : {})\n }),\n [options, hasGroups, groupOrder]\n );\n\n const selectedValue = value == null ? [] : [value];\n const showListHint = options.length >= listHintThreshold;\n const listHintText = formatGcsaLocaleMessage(messages.selectListHint, { count: options.length });\n const emptyText = messages.emptyDefault;\n const isEmpty = options.length === 0;\n const contentStyle = {\n '--gcsa-select-list-max-height': `${listMaxHeight}px`,\n ...(zIndex == null ? {} : { zIndex })\n } as CSSProperties;\n const positionerStyle = zIndex == null ? undefined : ({ zIndex } as CSSProperties);\n const positioning = useMemo(\n () => createGcsaPopupPositioning({ placement, sameWidth, gutter: 4 }),\n [placement, sameWidth]\n );\n\n return (\n <Select.Root\n collection={collection}\n value={selectedValue}\n positioning={positioning}\n lazyMount\n unmountOnExit\n onOpenChange={details => {\n onOpenChange(details.open);\n preserveDrawerScrollFrom(controlRef.current);\n }}\n onValueChange={details => onValueChange?.(details.value[0] ?? '')}\n >\n <Select.Control ref={controlRef} className=\"gcsa-select-control\">\n <Select.Trigger\n className={`gcsa-select-trigger gcsa-focus-ring ${gcsaControlSizeClass('gcsa-select-trigger', resolvedSize)}`}\n data-invalid={invalid || undefined}\n >\n <Select.ValueText className=\"gcsa-select-value\" placeholder={placeholder} />\n <Select.Indicator className=\"gcsa-select-indicator\" aria-hidden=\"true\">\n <GcsaIcon name=\"chevronDown\" className=\"gcsa-select-indicator__icon\" />\n </Select.Indicator>\n </Select.Trigger>\n </Select.Control>\n {portalled ? (\n <Portal>\n <Select.Positioner style={positionerStyle}>\n <SelectContent\n collection={collection}\n contentStyle={contentStyle}\n showListHint={showListHint}\n listHintText={listHintText}\n empty={isEmpty}\n emptyText={emptyText}\n />\n </Select.Positioner>\n </Portal>\n ) : (\n <Select.Positioner style={positionerStyle}>\n <SelectContent\n collection={collection}\n contentStyle={contentStyle}\n showListHint={showListHint}\n listHintText={listHintText}\n empty={isEmpty}\n emptyText={emptyText}\n />\n </Select.Positioner>\n )}\n <Select.HiddenSelect />\n </Select.Root>\n );\n}\n"],"names":["SelectContent","collection","contentStyle","showListHint","listHintText","empty","emptyText","jsx","Select","jsxs","Fragment","groupLabel","groupItems","opt","GcsaIcon","GcsaSelect","value","options","placeholder","invalid","placement","listMaxHeight","listHintThreshold","groupOrder","portalled","sameWidth","size","onValueChange","controlRef","useRef","resolvedSize","useGcsaComponentSize","messages","useGcsaLocaleMessages","zIndex","onOpenChange","useGcsaPopupZIndex","hasGroups","item","useMemo","createListCollection","selectedValue","formatGcsaLocaleMessage","isEmpty","positionerStyle","positioning","createGcsaPopupPositioning","details","preserveDrawerScrollFrom","gcsaControlSizeClass","Portal"],"mappings":";;;;;;;;;;;AAgCA,SAASA,EAAc;AAAA,EACrB,YAAAC;AAAA,EACA,cAAAC;AAAA,EACA,cAAAC;AAAA,EACA,cAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AACF,GAOG;AACD,SACE,gBAAAC,EAACC,EAAO,SAAP,EAAe,WAAU,uCAAsC,OAAON,GACpE,UAAAG,IACC,gBAAAE,EAAC,OAAA,EAAI,WAAU,qBAAoB,MAAK,UACtC,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,2BAA2B,UAAAD,EAAA,CAAU,EAAA,CACvD,IAEA,gBAAAG,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAH,EAACC,EAAO,MAAP,EAAY,WAAU,oBACpB,UAAAP,EAAW,QAAQ,IAAI,CAAC,CAACU,GAAYC,CAAU,MAC9C,gBAAAH,EAACD,EAAO,WAAP,EAA+C,WAAU,qBACvD,UAAA;AAAA,MAAAG,sBACEH,EAAO,gBAAP,EAAsB,WAAU,4BAC9B,aACH,IACE;AAAA,MACHI,EAAW,IAAI,CAAAC,MACd,gBAAAJ,EAACD,EAAO,MAAP,EAA4B,MAAMK,GAAK,WAAU,oBAChD,UAAA;AAAA,QAAA,gBAAAN,EAACC,EAAO,UAAP,EAAgB,WAAU,0BAA0B,YAAI,OAAM;AAAA,QAC/D,gBAAAD,EAACC,EAAO,eAAP,EAAqB,WAAU,2BAC9B,UAAA,gBAAAD,EAACO,GAAA,EAAS,MAAK,SAAQ,MAAK,MAAK,WAAU,gCAA+B,EAAA,CAC5E;AAAA,MAAA,EAAA,GAJgBD,EAAI,KAKtB,CACD;AAAA,IAAA,EAAA,GAboBF,KAAc,SAcrC,CACD,GACH;AAAA,IACCR,IAAe,gBAAAI,EAAC,OAAA,EAAI,WAAU,oBAAoB,aAAa,IAAS;AAAA,EAAA,EAAA,CAC3E,EAAA,CAEJ;AAEJ;AAEO,SAASQ,GAAW;AAAA,EACzB,OAAAC;AAAA,EACA,SAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,eAAAC,IAAgB;AAAA,EAChB,mBAAAC,IAAoB;AAAA,EACpB,YAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,WAAAC,IAAY;AAAA,EACZ,MAAAC;AAAA,EACA,eAAAC;AACF,GAAoB;AAClB,QAAMC,IAAaC,EAAuB,IAAI,GACxCC,IAAeC,EAAqBL,CAAI,GACxCM,IAAWC,EAAA,GACX,EAAE,QAAAC,GAAQ,cAAAC,EAAA,IAAiBC,EAAA,GAC3BC,IAAYpB,EAAQ,KAAK,CAAAqB,MAAQA,EAAK,KAAK,GAE3CrC,IAAasC;AAAA,IACjB,MACEC,EAAqB;AAAA,MACnB,OAAOvB;AAAA,MACP,aAAa,OAAQqB,EAAK;AAAA,MAC1B,cAAc,OAAQA,EAAK;AAAA,MAC3B,gBAAgB,CAAAA,MAAQA,EAAK,YAAY;AAAA,MACzC,GAAID,IACA;AAAA,QACE,SAAS,CAACC,MAA2BA,EAAK,SAAS;AAAA,QACnD,WAAWf,KAAe;AAAA,MAAA,IAE5B,CAAA;AAAA,IAAC,CACN;AAAA,IACH,CAACN,GAASoB,GAAWd,CAAU;AAAA,EAAA,GAG3BkB,IAAgBzB,KAAS,OAAO,CAAA,IAAK,CAACA,CAAK,GAC3Cb,IAAec,EAAQ,UAAUK,GACjClB,IAAesC,EAAwBV,EAAS,gBAAgB,EAAE,OAAOf,EAAQ,QAAQ,GACzFX,IAAY0B,EAAS,cACrBW,IAAU1B,EAAQ,WAAW,GAC7Bf,IAAe;AAAA,IACnB,iCAAiC,GAAGmB,CAAa;AAAA,IACjD,GAAIa,KAAU,OAAO,CAAA,IAAK,EAAE,QAAAA,EAAA;AAAA,EAAO,GAE/BU,IAAkBV,KAAU,OAAO,SAAa,EAAE,QAAAA,EAAA,GAClDW,IAAcN;AAAA,IAClB,MAAMO,EAA2B,EAAE,WAAA1B,GAAW,WAAAK,GAAW,QAAQ,GAAG;AAAA,IACpE,CAACL,GAAWK,CAAS;AAAA,EAAA;AAGvB,SACE,gBAAAhB;AAAA,IAACD,EAAO;AAAA,IAAP;AAAA,MACC,YAAAP;AAAA,MACA,OAAOwC;AAAA,MACP,aAAAI;AAAA,MACA,WAAS;AAAA,MACT,eAAa;AAAA,MACb,cAAc,CAAAE,MAAW;AACvB,QAAAZ,EAAaY,EAAQ,IAAI,GACzBC,EAAyBpB,EAAW,OAAO;AAAA,MAC7C;AAAA,MACA,eAAe,CAAAmB,MAAWpB,KAAA,gBAAAA,EAAgBoB,EAAQ,MAAM,CAAC,KAAK;AAAA,MAE9D,UAAA;AAAA,QAAA,gBAAAxC,EAACC,EAAO,SAAP,EAAe,KAAKoB,GAAY,WAAU,uBACzC,UAAA,gBAAAnB;AAAA,UAACD,EAAO;AAAA,UAAP;AAAA,YACC,WAAW,uCAAuCyC,EAAqB,uBAAuBnB,CAAY,CAAC;AAAA,YAC3G,gBAAcX,KAAW;AAAA,YAEzB,UAAA;AAAA,cAAA,gBAAAZ,EAACC,EAAO,WAAP,EAAiB,WAAU,qBAAoB,aAAAU,GAA0B;AAAA,cAC1E,gBAAAX,EAACC,EAAO,WAAP,EAAiB,WAAU,yBAAwB,eAAY,QAC9D,UAAA,gBAAAD,EAACO,GAAA,EAAS,MAAK,eAAc,WAAU,+BAA8B,EAAA,CACvE;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA,GAEJ;AAAA,QACCU,sBACE0B,GAAA,EACC,UAAA,gBAAA3C,EAACC,EAAO,YAAP,EAAkB,OAAOoC,GACxB,UAAA,gBAAArC;AAAA,UAACP;AAAA,UAAA;AAAA,YACC,YAAAC;AAAA,YACA,cAAAC;AAAA,YACA,cAAAC;AAAA,YACA,cAAAC;AAAA,YACA,OAAOuC;AAAA,YACP,WAAArC;AAAA,UAAA;AAAA,QAAA,GAEJ,GACF,IAEA,gBAAAC,EAACC,EAAO,YAAP,EAAkB,OAAOoC,GACxB,UAAA,gBAAArC;AAAA,UAACP;AAAA,UAAA;AAAA,YACC,YAAAC;AAAA,YACA,cAAAC;AAAA,YACA,cAAAC;AAAA,YACA,cAAAC;AAAA,YACA,OAAOuC;AAAA,YACP,WAAArC;AAAA,UAAA;AAAA,QAAA,GAEJ;AAAA,QAEF,gBAAAC,EAACC,EAAO,cAAP,CAAA,CAAoB;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG3B;"}
1
+ {"version":3,"file":"GcsaSelect.js","sources":["../src/GcsaSelect.tsx"],"sourcesContent":["import { useMemo, useRef, useState, type CSSProperties } from 'react';\nimport { createListCollection } from '@ark-ui/react/collection';\nimport { Select } from '@ark-ui/react/select';\nimport { Portal } from '@ark-ui/react/portal';\nimport type { GcsaPopupPlacement, GcsaSelectOption, GcsaSelectSize } from '@gcsa/console-core';\nimport { createGcsaPopupPositioning, formatGcsaLocaleMessage, gcsaControlSizeClass } from '@gcsa/console-core';\nimport { GcsaIcon } from './GcsaIcon';\nimport { useGcsaLocaleMessages } from './hooks/useGcsaLocale';\nimport { useGcsaPopupZIndex } from './hooks/useGcsaPopupZIndex';\nimport { useGcsaComponentSize } from './hooks/useGcsaComponentSize';\nimport { preserveDrawerScrollFrom } from './utils/preserveDrawerScroll';\n\nexport type GcsaSelectPlacement = GcsaPopupPlacement;\n\nexport type GcsaSelectProps = {\n value: string;\n options: GcsaSelectOption[];\n placeholder?: string;\n invalid?: boolean;\n /** 下拉相对触发器的初始方位 */\n placement?: GcsaSelectPlacement;\n listMaxHeight?: number;\n listHintThreshold?: number;\n groupOrder?: string[];\n /** 是否挂载到 body;嵌套浮层(如 DatePicker 内)应设为 false */\n portalled?: boolean;\n /** 下拉面板是否与触发器同宽 */\n sameWidth?: boolean;\n size?: GcsaSelectSize;\n onValueChange?: (value: string) => void;\n};\n\nfunction SelectContent({\n collection,\n contentStyle,\n showListHint,\n listHintText,\n empty,\n emptyText\n}: {\n collection: ReturnType<typeof createListCollection<GcsaSelectOption>>;\n contentStyle: CSSProperties;\n showListHint: boolean;\n listHintText: string;\n empty: boolean;\n emptyText: string;\n}) {\n return (\n <Select.Content className=\"gcsa-select-content gcsa-ui-surface\" style={contentStyle}>\n {empty ? (\n <div className=\"gcsa-select-empty\" role=\"status\">\n <span className=\"gcsa-select-empty__text\">{emptyText}</span>\n </div>\n ) : (\n <>\n <Select.List className=\"gcsa-select-list\">\n {collection.group().map(([groupLabel, groupItems]) => (\n <Select.ItemGroup key={groupLabel || 'default'} className=\"gcsa-select-group\">\n {groupLabel ? (\n <Select.ItemGroupLabel className=\"gcsa-select-group__label\">\n {groupLabel}\n </Select.ItemGroupLabel>\n ) : null}\n {groupItems.map(opt => (\n <Select.Item key={opt.value} item={opt} className=\"gcsa-select-item\">\n <Select.ItemText className=\"gcsa-select-item__text\">{opt.label}</Select.ItemText>\n <Select.ItemIndicator className=\"gcsa-select-item__check\">\n <GcsaIcon name=\"check\" size=\"sm\" className=\"gcsa-select-item__check-icon\" />\n </Select.ItemIndicator>\n </Select.Item>\n ))}\n </Select.ItemGroup>\n ))}\n </Select.List>\n {showListHint ? <div className=\"gcsa-select-hint\">{listHintText}</div> : null}\n </>\n )}\n </Select.Content>\n );\n}\n\nexport function GcsaSelect({\n value,\n options,\n placeholder,\n invalid,\n placement = 'bottom-start',\n listMaxHeight = 280,\n listHintThreshold = 16,\n groupOrder,\n portalled = true,\n sameWidth = true,\n size,\n onValueChange\n}: GcsaSelectProps) {\n const controlRef = useRef<HTMLDivElement>(null);\n const [triggerWidth, setTriggerWidth] = useState<number | undefined>();\n const resolvedSize = useGcsaComponentSize(size);\n const messages = useGcsaLocaleMessages();\n const { zIndex, onOpenChange } = useGcsaPopupZIndex();\n const hasGroups = options.some(item => item.group);\n\n const collection = useMemo(\n () =>\n createListCollection({\n items: options,\n itemToValue: item => item.value,\n itemToString: item => item.label,\n isItemDisabled: item => item.disabled ?? false,\n ...(hasGroups\n ? {\n groupBy: (item: GcsaSelectOption) => item.group ?? '',\n groupSort: groupOrder ?? ('asc' as const)\n }\n : {})\n }),\n [options, hasGroups, groupOrder]\n );\n\n const syncTriggerWidth = () => {\n const width = controlRef.current?.getBoundingClientRect().width;\n if (width) {\n setTriggerWidth(Math.round(width));\n }\n };\n\n const selectedValue = value == null ? [] : [value];\n const showListHint = options.length >= listHintThreshold;\n const listHintText = formatGcsaLocaleMessage(messages.selectListHint, { count: options.length });\n const emptyText = messages.emptyDefault;\n const isEmpty = options.length === 0;\n const contentStyle = {\n '--gcsa-select-list-max-height': `${listMaxHeight}px`,\n ...(zIndex == null ? {} : { zIndex }),\n ...(sameWidth && triggerWidth != null\n ? {\n width: triggerWidth,\n minWidth: triggerWidth,\n '--reference-width': `${triggerWidth}px`\n }\n : {})\n } as CSSProperties;\n const positionerStyle = zIndex == null ? undefined : ({ zIndex } as CSSProperties);\n const positioning = useMemo(\n () => createGcsaPopupPositioning({ placement, sameWidth, gutter: 4 }),\n [placement, sameWidth]\n );\n\n return (\n <Select.Root\n collection={collection}\n value={selectedValue}\n positioning={positioning}\n lazyMount\n unmountOnExit\n onOpenChange={details => {\n if (details.open && sameWidth) {\n syncTriggerWidth();\n }\n onOpenChange(details.open);\n preserveDrawerScrollFrom(controlRef.current);\n }}\n onValueChange={details => onValueChange?.(details.value[0] ?? '')}\n >\n <Select.Control ref={controlRef} className=\"gcsa-select-control\">\n <Select.Trigger\n className={`gcsa-select-trigger gcsa-focus-ring ${gcsaControlSizeClass('gcsa-select-trigger', resolvedSize)}`}\n data-invalid={invalid || undefined}\n >\n <Select.ValueText className=\"gcsa-select-value\" placeholder={placeholder} />\n <Select.Indicator className=\"gcsa-select-indicator\" aria-hidden=\"true\">\n <GcsaIcon name=\"chevronDown\" className=\"gcsa-select-indicator__icon\" />\n </Select.Indicator>\n </Select.Trigger>\n </Select.Control>\n {portalled ? (\n <Portal>\n <Select.Positioner style={positionerStyle}>\n <SelectContent\n collection={collection}\n contentStyle={contentStyle}\n showListHint={showListHint}\n listHintText={listHintText}\n empty={isEmpty}\n emptyText={emptyText}\n />\n </Select.Positioner>\n </Portal>\n ) : (\n <Select.Positioner style={positionerStyle}>\n <SelectContent\n collection={collection}\n contentStyle={contentStyle}\n showListHint={showListHint}\n listHintText={listHintText}\n empty={isEmpty}\n emptyText={emptyText}\n />\n </Select.Positioner>\n )}\n <Select.HiddenSelect />\n </Select.Root>\n );\n}\n"],"names":["SelectContent","collection","contentStyle","showListHint","listHintText","empty","emptyText","jsx","Select","jsxs","Fragment","groupLabel","groupItems","opt","GcsaIcon","GcsaSelect","value","options","placeholder","invalid","placement","listMaxHeight","listHintThreshold","groupOrder","portalled","sameWidth","size","onValueChange","controlRef","useRef","triggerWidth","setTriggerWidth","useState","resolvedSize","useGcsaComponentSize","messages","useGcsaLocaleMessages","zIndex","onOpenChange","useGcsaPopupZIndex","hasGroups","item","useMemo","createListCollection","syncTriggerWidth","width","_a","selectedValue","formatGcsaLocaleMessage","isEmpty","positionerStyle","positioning","createGcsaPopupPositioning","details","preserveDrawerScrollFrom","gcsaControlSizeClass","Portal"],"mappings":"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"}
@@ -1,76 +1,91 @@
1
- import { jsxs as i, jsx as s } from "react/jsx-runtime";
2
- import { useState as g, useMemo as T } from "react";
3
- import { GcsaInput as k } from "./GcsaInput.js";
4
- import { useGcsaLocaleMessages as $ } from "./hooks/useGcsaLocale.js";
5
- function z({
6
- options: u,
7
- value: t = [],
8
- sourceTitle: y,
9
- targetTitle: L,
10
- disabled: l = !1,
11
- onValueChange: m,
12
- onChange: _
1
+ import { jsxs as u, jsx as s } from "react/jsx-runtime";
2
+ import { useState as h, useMemo as L } from "react";
3
+ import { GcsaCheckbox as j } from "./GcsaCheckbox.js";
4
+ import { GcsaInput as K } from "./GcsaInput.js";
5
+ import { useGcsaLocaleMessages as P } from "./hooks/useGcsaLocale.js";
6
+ function F({
7
+ options: f,
8
+ value: n = [],
9
+ sourceTitle: C,
10
+ targetTitle: x,
11
+ disabled: o = !1,
12
+ onValueChange: p,
13
+ onChange: m
13
14
  }) {
14
- const c = $(), w = y ?? c.transferSourceTitle, x = L ?? c.transferTargetTitle, [d, b] = g([]), [f, N] = g([]), [h, M] = g(""), [p, Q] = g(""), G = T(
15
- () => u.filter(
16
- (e) => !t.includes(e.value) && e.label.toLowerCase().includes(h.trim().toLowerCase())
15
+ const i = P(), I = C ?? i.transferSourceTitle, D = x ?? i.transferTargetTitle, [g, N] = h([]), [_, k] = h([]), [b, G] = h(""), [v, M] = h(""), Q = L(
16
+ () => f.filter(
17
+ (e) => !n.includes(e.value) && e.label.toLowerCase().includes(b.trim().toLowerCase())
17
18
  ),
18
- [u, h, t]
19
- ), I = T(
20
- () => u.filter(
21
- (e) => t.includes(e.value) && e.label.toLowerCase().includes(p.trim().toLowerCase())
19
+ [f, b, n]
20
+ ), R = L(
21
+ () => f.filter(
22
+ (e) => n.includes(e.value) && e.label.toLowerCase().includes(v.trim().toLowerCase())
22
23
  ),
23
- [u, p, t]
24
- ), v = (e) => {
25
- m == null || m(e), _ == null || _(e), b([]), N([]);
26
- }, j = (e, n) => {
27
- const r = n === "source" ? d : f, a = r.includes(e) ? r.filter((o) => o !== e) : [...r, e];
28
- n === "source" ? b(a) : N(a);
29
- }, S = (e, n, r) => /* @__PURE__ */ i("section", { className: "gcsa-transfer__panel", "aria-label": n, children: [
30
- /* @__PURE__ */ i("header", { className: "gcsa-transfer__header", children: [
31
- /* @__PURE__ */ s("span", { children: n }),
24
+ [f, v, n]
25
+ ), S = (e) => {
26
+ p == null || p(e), m == null || m(e), N([]), k([]);
27
+ }, w = (e, t, a) => {
28
+ (t === "source" ? N : k)((c) => a ? c.includes(e) ? c : [...c, e] : c.filter((d) => d !== e));
29
+ }, y = (e, t) => {
30
+ if (o || e.disabled) return;
31
+ const a = t === "source" ? g : _;
32
+ w(e.value, t, !a.includes(e.value));
33
+ }, T = (e, t, a) => /* @__PURE__ */ u("section", { className: "gcsa-transfer__panel", "aria-label": t, children: [
34
+ /* @__PURE__ */ u("header", { className: "gcsa-transfer__header", children: [
35
+ /* @__PURE__ */ s("span", { children: t }),
32
36
  /* @__PURE__ */ s("span", { children: e.length })
33
37
  ] }),
34
38
  /* @__PURE__ */ s("div", { className: "gcsa-transfer__search", children: /* @__PURE__ */ s(
35
- k,
39
+ K,
36
40
  {
37
- value: r === "source" ? h : p,
38
- placeholder: c.searchPlaceholder,
39
- disabled: l,
40
- onValueChange: r === "source" ? M : Q
41
+ value: a === "source" ? b : v,
42
+ placeholder: i.searchPlaceholder,
43
+ disabled: o,
44
+ onValueChange: a === "source" ? G : M
41
45
  }
42
46
  ) }),
43
- /* @__PURE__ */ s("div", { className: "gcsa-transfer__list", role: "listbox", "aria-multiselectable": "true", children: e.length ? e.map((a) => {
44
- const o = (r === "source" ? d : f).includes(a.value);
45
- return /* @__PURE__ */ i(
46
- "button",
47
+ /* @__PURE__ */ s("div", { className: "gcsa-transfer__list", role: "listbox", "aria-multiselectable": "true", children: e.length ? e.map((r) => {
48
+ const c = (a === "source" ? g : _).includes(r.value), d = o || !!r.disabled;
49
+ return /* @__PURE__ */ u(
50
+ "div",
47
51
  {
48
- type: "button",
49
- className: `gcsa-transfer__item gcsa-focus-ring${o ? " gcsa-transfer__item--selected" : ""}`,
50
- disabled: l || a.disabled,
52
+ className: `gcsa-transfer__item gcsa-focus-ring${c ? " gcsa-transfer__item--selected" : ""}`,
51
53
  role: "option",
52
- "aria-selected": o,
53
- onClick: () => j(a.value, r),
54
+ tabIndex: d ? -1 : 0,
55
+ "aria-selected": c,
56
+ "aria-disabled": d || void 0,
57
+ onClick: () => y(r, a),
58
+ onKeyDown: (l) => {
59
+ (l.key === "Enter" || l.key === " ") && (l.preventDefault(), y(r, a));
60
+ },
54
61
  children: [
55
- /* @__PURE__ */ s("span", { className: "gcsa-transfer__check", "aria-hidden": "true", children: o ? "✓" : "" }),
56
- /* @__PURE__ */ s("span", { children: a.label })
62
+ /* @__PURE__ */ s("span", { className: "gcsa-transfer__check-wrap", onClick: (l) => l.stopPropagation(), children: /* @__PURE__ */ s(
63
+ j,
64
+ {
65
+ checked: c,
66
+ disabled: d,
67
+ ariaLabel: r.label,
68
+ onCheckedChange: (l) => w(r.value, a, l)
69
+ }
70
+ ) }),
71
+ /* @__PURE__ */ s("span", { className: "gcsa-transfer__label", children: r.label })
57
72
  ]
58
73
  },
59
- a.value
74
+ r.value
60
75
  );
61
- }) : /* @__PURE__ */ s("span", { className: "gcsa-transfer__empty", children: c.noOptions }) })
76
+ }) : /* @__PURE__ */ s("span", { className: "gcsa-transfer__empty", children: i.noOptions }) })
62
77
  ] });
63
- return /* @__PURE__ */ i("div", { className: `gcsa-transfer${l ? " gcsa-transfer--disabled" : ""}`, children: [
64
- S(G, w, "source"),
65
- /* @__PURE__ */ i("div", { className: "gcsa-transfer__actions", children: [
78
+ return /* @__PURE__ */ u("div", { className: `gcsa-transfer${o ? " gcsa-transfer--disabled" : ""}`, children: [
79
+ T(Q, I, "source"),
80
+ /* @__PURE__ */ u("div", { className: "gcsa-transfer__actions", children: [
66
81
  /* @__PURE__ */ s(
67
82
  "button",
68
83
  {
69
84
  type: "button",
70
85
  className: "gcsa-transfer__action gcsa-focus-ring",
71
- disabled: l || !d.length,
72
- "aria-label": c.transferMoveRight,
73
- onClick: () => v([...t, ...d]),
86
+ disabled: o || !g.length,
87
+ "aria-label": i.transferMoveRight,
88
+ onClick: () => S([...n, ...g]),
74
89
  children: "›"
75
90
  }
76
91
  ),
@@ -79,17 +94,17 @@ function z({
79
94
  {
80
95
  type: "button",
81
96
  className: "gcsa-transfer__action gcsa-focus-ring",
82
- disabled: l || !f.length,
83
- "aria-label": c.transferMoveLeft,
84
- onClick: () => v(t.filter((e) => !f.includes(e))),
97
+ disabled: o || !_.length,
98
+ "aria-label": i.transferMoveLeft,
99
+ onClick: () => S(n.filter((e) => !_.includes(e))),
85
100
  children: "‹"
86
101
  }
87
102
  )
88
103
  ] }),
89
- S(I, x, "target")
104
+ T(R, D, "target")
90
105
  ] });
91
106
  }
92
107
  export {
93
- z as GcsaTransfer
108
+ F as GcsaTransfer
94
109
  };
95
110
  //# sourceMappingURL=GcsaTransfer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GcsaTransfer.js","sources":["../src/GcsaTransfer.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport type { GcsaTransferOption } from '@gcsa/console-core';\nimport { GcsaInput } from './GcsaInput';\nimport { useGcsaLocaleMessages } from './hooks/useGcsaLocale';\n\nexport type GcsaTransferProps = {\n options: GcsaTransferOption[];\n value?: string[];\n sourceTitle?: string;\n targetTitle?: string;\n disabled?: boolean;\n onValueChange?: (keys: string[]) => void;\n onChange?: (keys: string[]) => void;\n};\n\nexport function GcsaTransfer({\n options,\n value = [],\n sourceTitle,\n targetTitle,\n disabled = false,\n onValueChange,\n onChange\n}: GcsaTransferProps) {\n const messages = useGcsaLocaleMessages();\n const resolvedSourceTitle = sourceTitle ?? messages.transferSourceTitle;\n const resolvedTargetTitle = targetTitle ?? messages.transferTargetTitle;\n const [sourceSelected, setSourceSelected] = useState<string[]>([]);\n const [targetSelected, setTargetSelected] = useState<string[]>([]);\n const [sourceQuery, setSourceQuery] = useState('');\n const [targetQuery, setTargetQuery] = useState('');\n const availableItems = useMemo(\n () =>\n options.filter(\n item =>\n !value.includes(item.value) &&\n item.label.toLowerCase().includes(sourceQuery.trim().toLowerCase())\n ),\n [options, sourceQuery, value]\n );\n const targetItems = useMemo(\n () =>\n options.filter(\n item =>\n value.includes(item.value) &&\n item.label.toLowerCase().includes(targetQuery.trim().toLowerCase())\n ),\n [options, targetQuery, value]\n );\n const update = (next: string[]) => {\n onValueChange?.(next);\n onChange?.(next);\n setSourceSelected([]);\n setTargetSelected([]);\n };\n const toggle = (key: string, side: 'source' | 'target') => {\n const current = side === 'source' ? sourceSelected : targetSelected;\n const next = current.includes(key) ? current.filter(item => item !== key) : [...current, key];\n if (side === 'source') setSourceSelected(next);\n else setTargetSelected(next);\n };\n const panel = (items: GcsaTransferOption[], title: string, side: 'source' | 'target') => (\n <section className=\"gcsa-transfer__panel\" aria-label={title}>\n <header className=\"gcsa-transfer__header\">\n <span>{title}</span>\n <span>{items.length}</span>\n </header>\n <div className=\"gcsa-transfer__search\">\n <GcsaInput\n value={side === 'source' ? sourceQuery : targetQuery}\n placeholder={messages.searchPlaceholder}\n disabled={disabled}\n onValueChange={side === 'source' ? setSourceQuery : setTargetQuery}\n />\n </div>\n <div className=\"gcsa-transfer__list\" role=\"listbox\" aria-multiselectable=\"true\">\n {items.length ? (\n items.map(item => {\n const selected = (side === 'source' ? sourceSelected : targetSelected).includes(item.value);\n return (\n <button\n key={item.value}\n type=\"button\"\n className={`gcsa-transfer__item gcsa-focus-ring${selected ? ' gcsa-transfer__item--selected' : ''}`}\n disabled={disabled || item.disabled}\n role=\"option\"\n aria-selected={selected}\n onClick={() => toggle(item.value, side)}\n >\n <span className=\"gcsa-transfer__check\" aria-hidden=\"true\">\n {selected ? '✓' : ''}\n </span>\n <span>{item.label}</span>\n </button>\n );\n })\n ) : (\n <span className=\"gcsa-transfer__empty\">{messages.noOptions}</span>\n )}\n </div>\n </section>\n );\n return (\n <div className={`gcsa-transfer${disabled ? ' gcsa-transfer--disabled' : ''}`}>\n {panel(availableItems, resolvedSourceTitle, 'source')}\n <div className=\"gcsa-transfer__actions\">\n <button\n type=\"button\"\n className=\"gcsa-transfer__action gcsa-focus-ring\"\n disabled={disabled || !sourceSelected.length}\n aria-label={messages.transferMoveRight}\n onClick={() => update([...value, ...sourceSelected])}\n >\n ›\n </button>\n <button\n type=\"button\"\n className=\"gcsa-transfer__action gcsa-focus-ring\"\n disabled={disabled || !targetSelected.length}\n aria-label={messages.transferMoveLeft}\n onClick={() => update(value.filter(key => !targetSelected.includes(key)))}\n >\n ‹\n </button>\n </div>\n {panel(targetItems, resolvedTargetTitle, 'target')}\n </div>\n );\n}\n"],"names":["GcsaTransfer","options","value","sourceTitle","targetTitle","disabled","onValueChange","onChange","messages","useGcsaLocaleMessages","resolvedSourceTitle","resolvedTargetTitle","sourceSelected","setSourceSelected","useState","targetSelected","setTargetSelected","sourceQuery","setSourceQuery","targetQuery","setTargetQuery","availableItems","useMemo","item","targetItems","update","next","toggle","key","side","current","panel","items","title","jsxs","jsx","GcsaInput","selected"],"mappings":"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"}
1
+ {"version":3,"file":"GcsaTransfer.js","sources":["../src/GcsaTransfer.tsx"],"sourcesContent":["import { useMemo, useState, type KeyboardEvent } from 'react';\nimport type { GcsaTransferOption } from '@gcsa/console-core';\nimport { GcsaCheckbox } from './GcsaCheckbox';\nimport { GcsaInput } from './GcsaInput';\nimport { useGcsaLocaleMessages } from './hooks/useGcsaLocale';\n\nexport type GcsaTransferProps = {\n options: GcsaTransferOption[];\n value?: string[];\n sourceTitle?: string;\n targetTitle?: string;\n disabled?: boolean;\n onValueChange?: (keys: string[]) => void;\n onChange?: (keys: string[]) => void;\n};\n\nexport function GcsaTransfer({\n options,\n value = [],\n sourceTitle,\n targetTitle,\n disabled = false,\n onValueChange,\n onChange\n}: GcsaTransferProps) {\n const messages = useGcsaLocaleMessages();\n const resolvedSourceTitle = sourceTitle ?? messages.transferSourceTitle;\n const resolvedTargetTitle = targetTitle ?? messages.transferTargetTitle;\n const [sourceSelected, setSourceSelected] = useState<string[]>([]);\n const [targetSelected, setTargetSelected] = useState<string[]>([]);\n const [sourceQuery, setSourceQuery] = useState('');\n const [targetQuery, setTargetQuery] = useState('');\n\n const availableItems = useMemo(\n () =>\n options.filter(\n item =>\n !value.includes(item.value) &&\n item.label.toLowerCase().includes(sourceQuery.trim().toLowerCase())\n ),\n [options, sourceQuery, value]\n );\n\n const targetItems = useMemo(\n () =>\n options.filter(\n item =>\n value.includes(item.value) &&\n item.label.toLowerCase().includes(targetQuery.trim().toLowerCase())\n ),\n [options, targetQuery, value]\n );\n\n const update = (next: string[]) => {\n onValueChange?.(next);\n onChange?.(next);\n setSourceSelected([]);\n setTargetSelected([]);\n };\n\n const setSelected = (key: string, side: 'source' | 'target', checked: boolean) => {\n const setter = side === 'source' ? setSourceSelected : setTargetSelected;\n setter(current => {\n if (checked) return current.includes(key) ? current : [...current, key];\n return current.filter(item => item !== key);\n });\n };\n\n const onItemActivate = (item: GcsaTransferOption, side: 'source' | 'target') => {\n if (disabled || item.disabled) return;\n const current = side === 'source' ? sourceSelected : targetSelected;\n setSelected(item.value, side, !current.includes(item.value));\n };\n\n const panel = (items: GcsaTransferOption[], title: string, side: 'source' | 'target') => (\n <section className=\"gcsa-transfer__panel\" aria-label={title}>\n <header className=\"gcsa-transfer__header\">\n <span>{title}</span>\n <span>{items.length}</span>\n </header>\n <div className=\"gcsa-transfer__search\">\n <GcsaInput\n value={side === 'source' ? sourceQuery : targetQuery}\n placeholder={messages.searchPlaceholder}\n disabled={disabled}\n onValueChange={side === 'source' ? setSourceQuery : setTargetQuery}\n />\n </div>\n <div className=\"gcsa-transfer__list\" role=\"listbox\" aria-multiselectable=\"true\">\n {items.length ? (\n items.map(item => {\n const selected = (side === 'source' ? sourceSelected : targetSelected).includes(item.value);\n const itemDisabled = disabled || Boolean(item.disabled);\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onItemActivate(item, side);\n }\n };\n const onRowClick = () => onItemActivate(item, side);\n return (\n <div\n key={item.value}\n className={`gcsa-transfer__item gcsa-focus-ring${selected ? ' gcsa-transfer__item--selected' : ''}`}\n role=\"option\"\n tabIndex={itemDisabled ? -1 : 0}\n aria-selected={selected}\n aria-disabled={itemDisabled || undefined}\n onClick={onRowClick}\n onKeyDown={onKeyDown}\n >\n <span className=\"gcsa-transfer__check-wrap\" onClick={event => event.stopPropagation()}>\n <GcsaCheckbox\n checked={selected}\n disabled={itemDisabled}\n ariaLabel={item.label}\n onCheckedChange={checked => setSelected(item.value, side, checked)}\n />\n </span>\n <span className=\"gcsa-transfer__label\">{item.label}</span>\n </div>\n );\n })\n ) : (\n <span className=\"gcsa-transfer__empty\">{messages.noOptions}</span>\n )}\n </div>\n </section>\n );\n\n return (\n <div className={`gcsa-transfer${disabled ? ' gcsa-transfer--disabled' : ''}`}>\n {panel(availableItems, resolvedSourceTitle, 'source')}\n <div className=\"gcsa-transfer__actions\">\n <button\n type=\"button\"\n className=\"gcsa-transfer__action gcsa-focus-ring\"\n disabled={disabled || !sourceSelected.length}\n aria-label={messages.transferMoveRight}\n onClick={() => update([...value, ...sourceSelected])}\n >\n ›\n </button>\n <button\n type=\"button\"\n className=\"gcsa-transfer__action gcsa-focus-ring\"\n disabled={disabled || !targetSelected.length}\n aria-label={messages.transferMoveLeft}\n onClick={() => update(value.filter(key => !targetSelected.includes(key)))}\n >\n ‹\n </button>\n </div>\n {panel(targetItems, resolvedTargetTitle, 'target')}\n </div>\n );\n}\n"],"names":["GcsaTransfer","options","value","sourceTitle","targetTitle","disabled","onValueChange","onChange","messages","useGcsaLocaleMessages","resolvedSourceTitle","resolvedTargetTitle","sourceSelected","setSourceSelected","useState","targetSelected","setTargetSelected","sourceQuery","setSourceQuery","targetQuery","setTargetQuery","availableItems","useMemo","item","targetItems","update","next","setSelected","key","side","checked","current","onItemActivate","panel","items","title","jsxs","jsx","GcsaInput","selected","itemDisabled","event","GcsaCheckbox"],"mappings":"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"}
@@ -97,7 +97,7 @@ function sa({
97
97
  onDragLeave: () => v(!1),
98
98
  onDrop: Y,
99
99
  children: [
100
- /* @__PURE__ */ t("span", { className: "gcsa-upload__icon", "aria-hidden": "true", children: /* @__PURE__ */ t(C, { name: "plus" }) }),
100
+ /* @__PURE__ */ t("span", { className: "gcsa-upload__icon", "aria-hidden": "true", children: /* @__PURE__ */ t(C, { name: "upload" }) }),
101
101
  /* @__PURE__ */ t("span", { className: "gcsa-upload__title", children: q }),
102
102
  k ? /* @__PURE__ */ t("p", { className: "gcsa-upload__hint", children: k }) : null
103
103
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"GcsaUpload.js","sources":["../src/GcsaUpload.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { GcsaIcon } from './GcsaIcon';\nimport { useGcsaLocaleMessages } from './hooks/useGcsaLocale';\n\nexport type GcsaUploadProps = {\n files?: File[];\n accept?: string;\n multiple?: boolean;\n disabled?: boolean;\n buttonLabel?: string;\n hint?: string;\n maxCount?: number;\n maxSize?: number;\n drag?: boolean;\n directory?: boolean;\n dragLabel?: string;\n uploadingLabel?: string;\n uploadErrorLabel?: string;\n upload?: (file: File, onProgress?: (percent: number) => void) => Promise<void> | void;\n retryLabel?: string;\n onProgress?: (file: File, percent: number) => void;\n onUploadStart?: (file: File) => void;\n onUploadSuccess?: (file: File) => void;\n onUploadError?: (file: File, error: unknown) => void;\n className?: string;\n onFilesChange?: (files: File[]) => void;\n};\n\nexport function GcsaUpload({\n files = [],\n accept,\n multiple = false,\n disabled,\n buttonLabel,\n hint,\n maxCount,\n className,\n onFilesChange,\n maxSize,\n drag = false,\n directory = false,\n dragLabel,\n uploadingLabel,\n uploadErrorLabel,\n upload,\n retryLabel,\n onProgress,\n onUploadStart,\n onUploadSuccess,\n onUploadError\n}: GcsaUploadProps) {\n const messages = useGcsaLocaleMessages();\n const resolvedButtonLabel = buttonLabel ?? messages.uploadSelectFile;\n const resolvedDragLabel = dragLabel ?? messages.uploadDragHint;\n const resolvedUploadingLabel = uploadingLabel ?? messages.uploadUploading;\n const resolvedUploadErrorLabel = uploadErrorLabel ?? messages.uploadFailed;\n const resolvedRetryLabel = retryLabel ?? messages.uploadRetry;\n const resolvedHint = hint || (drag ? resolvedDragLabel : undefined);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const [dragging, setDragging] = useState(false);\n const [statuses, setStatuses] = useState<Map<File, 'uploading' | 'success' | 'error'>>(new Map());\n const [progress, setProgress] = useState<Map<File, number>>(new Map());\n\n function openPicker() {\n inputRef.current?.click();\n }\n\n function onNativeChange(event: React.ChangeEvent<HTMLInputElement>) {\n const picked = Array.from(event.target.files ?? []);\n event.target.value = '';\n if (!picked.length) return;\n\n acceptFiles(picked);\n }\n\n function acceptFiles(picked: File[]) {\n const valid = maxSize == null ? picked : picked.filter(file => file.size <= maxSize);\n let next = multiple ? [...files, ...valid] : valid.slice(0, 1);\n if (maxCount != null) next = next.slice(0, maxCount);\n onFilesChange?.(next);\n if (upload) next.filter(file => valid.includes(file)).forEach(uploadFile);\n }\n\n function onDragEnter(event: React.DragEvent<HTMLDivElement>) {\n event.preventDefault();\n if (!drag || disabled) return;\n setDragging(true);\n }\n\n function onDrop(event: React.DragEvent<HTMLDivElement>) {\n event.preventDefault();\n setDragging(false);\n if (!drag || disabled) return;\n acceptFiles(Array.from(event.dataTransfer.files));\n }\n\n async function uploadFile(file: File) {\n if (!upload) return;\n setStatuses(current => new Map(current).set(file, 'uploading'));\n setProgress(current => new Map(current).set(file, 0));\n onUploadStart?.(file);\n try {\n await upload(file, percent => {\n const next = Math.max(0, Math.min(100, Math.round(percent)));\n setProgress(current => new Map(current).set(file, next));\n onProgress?.(file, next);\n });\n setStatuses(current => new Map(current).set(file, 'success'));\n setProgress(current => new Map(current).set(file, 100));\n onUploadSuccess?.(file);\n } catch (error) {\n setStatuses(current => new Map(current).set(file, 'error'));\n onUploadError?.(file, error);\n }\n }\n\n function removeAt(index: number) {\n onFilesChange?.(files.filter((_, i) => i !== index));\n }\n\n function formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n }\n\n return (\n <div\n className={`gcsa-upload${disabled ? ' gcsa-upload--disabled' : ''}${dragging ? ' gcsa-upload--dragging' : ''}${className ? ` ${className}` : ''}`}\n >\n <input\n ref={inputRef}\n type=\"file\"\n className=\"gcsa-upload__native\"\n accept={accept}\n multiple={multiple}\n {...(directory ? { webkitdirectory: '' } : {})}\n disabled={disabled}\n onChange={onNativeChange}\n />\n <div\n className=\"gcsa-upload__dropzone\"\n role=\"button\"\n tabIndex={0}\n onClick={openPicker}\n onKeyDown={event => {\n if (event.key === 'Enter' || event.key === ' ') openPicker();\n }}\n onDragEnter={onDragEnter}\n onDragOver={onDragEnter}\n onDragLeave={() => setDragging(false)}\n onDrop={onDrop}\n >\n <span className=\"gcsa-upload__icon\" aria-hidden=\"true\">\n <GcsaIcon name=\"plus\" />\n </span>\n <span className=\"gcsa-upload__title\">{resolvedButtonLabel}</span>\n {resolvedHint ? <p className=\"gcsa-upload__hint\">{resolvedHint}</p> : null}\n </div>\n {files.length > 0 ? (\n <ul className=\"gcsa-upload__list\">\n {files.map((file, index) => (\n <li key={`${file.name}-${index}`} className=\"gcsa-upload__item\">\n <span className=\"gcsa-upload__name\">{file.name}</span>\n <span className=\"gcsa-upload__size\">{formatSize(file.size)}</span>\n {statuses.get(file) === 'uploading' ? (\n <span className=\"gcsa-upload__status\" role=\"status\">\n {resolvedUploadingLabel} {progress.get(file) ?? 0}%\n </span>\n ) : null}\n {statuses.get(file) === 'error' ? (\n <span className=\"gcsa-upload__status gcsa-upload__status--error\" role=\"alert\">\n {resolvedUploadErrorLabel}\n </span>\n ) : null}\n {statuses.get(file) === 'uploading' ? (\n <div className=\"gcsa-upload__progress\" aria-hidden=\"true\">\n <span style={{ width: `${progress.get(file) ?? 0}%` }} />\n </div>\n ) : null}\n {statuses.get(file) === 'error' ? (\n <button\n type=\"button\"\n className=\"gcsa-upload__retry gcsa-focus-ring\"\n disabled={disabled}\n onClick={() => uploadFile(file)}\n >\n {resolvedRetryLabel}\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"gcsa-upload__remove gcsa-focus-ring\"\n disabled={disabled}\n aria-label={messages.uploadRemoveFile}\n onClick={() => removeAt(index)}\n >\n {messages.remove}\n </button>\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n );\n}\n"],"names":["GcsaUpload","files","accept","multiple","disabled","buttonLabel","hint","maxCount","className","onFilesChange","maxSize","drag","directory","dragLabel","uploadingLabel","uploadErrorLabel","upload","retryLabel","onProgress","onUploadStart","onUploadSuccess","onUploadError","messages","useGcsaLocaleMessages","resolvedButtonLabel","resolvedDragLabel","resolvedUploadingLabel","resolvedUploadErrorLabel","resolvedRetryLabel","resolvedHint","inputRef","useRef","dragging","setDragging","useState","statuses","setStatuses","progress","setProgress","openPicker","_a","onNativeChange","event","picked","acceptFiles","valid","file","next","uploadFile","onDragEnter","onDrop","current","percent","error","removeAt","index","_","i","formatSize","bytes","jsxs","jsx","GcsaIcon"],"mappings":"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"}
1
+ {"version":3,"file":"GcsaUpload.js","sources":["../src/GcsaUpload.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { GcsaIcon } from './GcsaIcon';\nimport { useGcsaLocaleMessages } from './hooks/useGcsaLocale';\n\nexport type GcsaUploadProps = {\n files?: File[];\n accept?: string;\n multiple?: boolean;\n disabled?: boolean;\n buttonLabel?: string;\n hint?: string;\n maxCount?: number;\n maxSize?: number;\n drag?: boolean;\n directory?: boolean;\n dragLabel?: string;\n uploadingLabel?: string;\n uploadErrorLabel?: string;\n upload?: (file: File, onProgress?: (percent: number) => void) => Promise<void> | void;\n retryLabel?: string;\n onProgress?: (file: File, percent: number) => void;\n onUploadStart?: (file: File) => void;\n onUploadSuccess?: (file: File) => void;\n onUploadError?: (file: File, error: unknown) => void;\n className?: string;\n onFilesChange?: (files: File[]) => void;\n};\n\nexport function GcsaUpload({\n files = [],\n accept,\n multiple = false,\n disabled,\n buttonLabel,\n hint,\n maxCount,\n className,\n onFilesChange,\n maxSize,\n drag = false,\n directory = false,\n dragLabel,\n uploadingLabel,\n uploadErrorLabel,\n upload,\n retryLabel,\n onProgress,\n onUploadStart,\n onUploadSuccess,\n onUploadError\n}: GcsaUploadProps) {\n const messages = useGcsaLocaleMessages();\n const resolvedButtonLabel = buttonLabel ?? messages.uploadSelectFile;\n const resolvedDragLabel = dragLabel ?? messages.uploadDragHint;\n const resolvedUploadingLabel = uploadingLabel ?? messages.uploadUploading;\n const resolvedUploadErrorLabel = uploadErrorLabel ?? messages.uploadFailed;\n const resolvedRetryLabel = retryLabel ?? messages.uploadRetry;\n const resolvedHint = hint || (drag ? resolvedDragLabel : undefined);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const [dragging, setDragging] = useState(false);\n const [statuses, setStatuses] = useState<Map<File, 'uploading' | 'success' | 'error'>>(new Map());\n const [progress, setProgress] = useState<Map<File, number>>(new Map());\n\n function openPicker() {\n inputRef.current?.click();\n }\n\n function onNativeChange(event: React.ChangeEvent<HTMLInputElement>) {\n const picked = Array.from(event.target.files ?? []);\n event.target.value = '';\n if (!picked.length) return;\n\n acceptFiles(picked);\n }\n\n function acceptFiles(picked: File[]) {\n const valid = maxSize == null ? picked : picked.filter(file => file.size <= maxSize);\n let next = multiple ? [...files, ...valid] : valid.slice(0, 1);\n if (maxCount != null) next = next.slice(0, maxCount);\n onFilesChange?.(next);\n if (upload) next.filter(file => valid.includes(file)).forEach(uploadFile);\n }\n\n function onDragEnter(event: React.DragEvent<HTMLDivElement>) {\n event.preventDefault();\n if (!drag || disabled) return;\n setDragging(true);\n }\n\n function onDrop(event: React.DragEvent<HTMLDivElement>) {\n event.preventDefault();\n setDragging(false);\n if (!drag || disabled) return;\n acceptFiles(Array.from(event.dataTransfer.files));\n }\n\n async function uploadFile(file: File) {\n if (!upload) return;\n setStatuses(current => new Map(current).set(file, 'uploading'));\n setProgress(current => new Map(current).set(file, 0));\n onUploadStart?.(file);\n try {\n await upload(file, percent => {\n const next = Math.max(0, Math.min(100, Math.round(percent)));\n setProgress(current => new Map(current).set(file, next));\n onProgress?.(file, next);\n });\n setStatuses(current => new Map(current).set(file, 'success'));\n setProgress(current => new Map(current).set(file, 100));\n onUploadSuccess?.(file);\n } catch (error) {\n setStatuses(current => new Map(current).set(file, 'error'));\n onUploadError?.(file, error);\n }\n }\n\n function removeAt(index: number) {\n onFilesChange?.(files.filter((_, i) => i !== index));\n }\n\n function formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n }\n\n return (\n <div\n className={`gcsa-upload${disabled ? ' gcsa-upload--disabled' : ''}${dragging ? ' gcsa-upload--dragging' : ''}${className ? ` ${className}` : ''}`}\n >\n <input\n ref={inputRef}\n type=\"file\"\n className=\"gcsa-upload__native\"\n accept={accept}\n multiple={multiple}\n {...(directory ? { webkitdirectory: '' } : {})}\n disabled={disabled}\n onChange={onNativeChange}\n />\n <div\n className=\"gcsa-upload__dropzone\"\n role=\"button\"\n tabIndex={0}\n onClick={openPicker}\n onKeyDown={event => {\n if (event.key === 'Enter' || event.key === ' ') openPicker();\n }}\n onDragEnter={onDragEnter}\n onDragOver={onDragEnter}\n onDragLeave={() => setDragging(false)}\n onDrop={onDrop}\n >\n <span className=\"gcsa-upload__icon\" aria-hidden=\"true\">\n <GcsaIcon name=\"upload\" />\n </span>\n <span className=\"gcsa-upload__title\">{resolvedButtonLabel}</span>\n {resolvedHint ? <p className=\"gcsa-upload__hint\">{resolvedHint}</p> : null}\n </div>\n {files.length > 0 ? (\n <ul className=\"gcsa-upload__list\">\n {files.map((file, index) => (\n <li key={`${file.name}-${index}`} className=\"gcsa-upload__item\">\n <span className=\"gcsa-upload__name\">{file.name}</span>\n <span className=\"gcsa-upload__size\">{formatSize(file.size)}</span>\n {statuses.get(file) === 'uploading' ? (\n <span className=\"gcsa-upload__status\" role=\"status\">\n {resolvedUploadingLabel} {progress.get(file) ?? 0}%\n </span>\n ) : null}\n {statuses.get(file) === 'error' ? (\n <span className=\"gcsa-upload__status gcsa-upload__status--error\" role=\"alert\">\n {resolvedUploadErrorLabel}\n </span>\n ) : null}\n {statuses.get(file) === 'uploading' ? (\n <div className=\"gcsa-upload__progress\" aria-hidden=\"true\">\n <span style={{ width: `${progress.get(file) ?? 0}%` }} />\n </div>\n ) : null}\n {statuses.get(file) === 'error' ? (\n <button\n type=\"button\"\n className=\"gcsa-upload__retry gcsa-focus-ring\"\n disabled={disabled}\n onClick={() => uploadFile(file)}\n >\n {resolvedRetryLabel}\n </button>\n ) : null}\n <button\n type=\"button\"\n className=\"gcsa-upload__remove gcsa-focus-ring\"\n disabled={disabled}\n aria-label={messages.uploadRemoveFile}\n onClick={() => removeAt(index)}\n >\n {messages.remove}\n </button>\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n );\n}\n"],"names":["GcsaUpload","files","accept","multiple","disabled","buttonLabel","hint","maxCount","className","onFilesChange","maxSize","drag","directory","dragLabel","uploadingLabel","uploadErrorLabel","upload","retryLabel","onProgress","onUploadStart","onUploadSuccess","onUploadError","messages","useGcsaLocaleMessages","resolvedButtonLabel","resolvedDragLabel","resolvedUploadingLabel","resolvedUploadErrorLabel","resolvedRetryLabel","resolvedHint","inputRef","useRef","dragging","setDragging","useState","statuses","setStatuses","progress","setProgress","openPicker","_a","onNativeChange","event","picked","acceptFiles","valid","file","next","uploadFile","onDragEnter","onDrop","current","percent","error","removeAt","index","_","i","formatSize","bytes","jsxs","jsx","GcsaIcon"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /** 导航侧栏图标 — 与 @gcsa/console-core GcsaNavItem.iconKey 对齐 */
2
2
  export declare const GCSA_NAV_ICON_NAMES: readonly ["dashboard", "alert", "assets", "settings", "users", "chat"];
3
3
  /** 组件内部 UI 图标(文件名 kebab-case → 注册为 camelCase key) */
4
- export declare const GCSA_UI_ICON_NAMES: readonly ["chevronDown", "chevronUp", "chevronLeft", "chevronRight", "check", "close", "menu", "plus", "resultEmpty"];
5
- export declare const GCSA_ICON_NAMES: readonly ["dashboard", "alert", "assets", "settings", "users", "chat", "chevronDown", "chevronUp", "chevronLeft", "chevronRight", "check", "close", "menu", "plus", "resultEmpty"];
4
+ export declare const GCSA_UI_ICON_NAMES: readonly ["chevronDown", "chevronUp", "chevronLeft", "chevronRight", "check", "close", "menu", "plus", "upload", "resultEmpty"];
5
+ export declare const GCSA_ICON_NAMES: readonly ["dashboard", "alert", "assets", "settings", "users", "chat", "chevronDown", "chevronUp", "chevronLeft", "chevronRight", "check", "close", "menu", "plus", "upload", "resultEmpty"];
6
6
  export type GcsaNavIconName = (typeof GCSA_NAV_ICON_NAMES)[number];
7
7
  export type GcsaIconName = (typeof GCSA_ICON_NAMES)[number];
@@ -14,6 +14,7 @@ const e = [
14
14
  "close",
15
15
  "menu",
16
16
  "plus",
17
+ "upload",
17
18
  "resultEmpty"
18
19
  ], t = [...e, ...s];
19
20
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"iconNames.js","sources":["../../src/icons/iconNames.ts"],"sourcesContent":["/** 导航侧栏图标 — 与 @gcsa/console-core GcsaNavItem.iconKey 对齐 */\nexport const GCSA_NAV_ICON_NAMES = [\n 'dashboard',\n 'alert',\n 'assets',\n 'settings',\n 'users',\n 'chat'\n] as const;\n\n/** 组件内部 UI 图标(文件名 kebab-case → 注册为 camelCase key) */\nexport const GCSA_UI_ICON_NAMES = [\n 'chevronDown',\n 'chevronUp',\n 'chevronLeft',\n 'chevronRight',\n 'check',\n 'close',\n 'menu',\n 'plus',\n 'resultEmpty'\n] as const;\n\nexport const GCSA_ICON_NAMES = [...GCSA_NAV_ICON_NAMES, ...GCSA_UI_ICON_NAMES] as const;\n\nexport type GcsaNavIconName = (typeof GCSA_NAV_ICON_NAMES)[number];\nexport type GcsaIconName = (typeof GCSA_ICON_NAMES)[number];\n"],"names":["GCSA_NAV_ICON_NAMES","GCSA_UI_ICON_NAMES","GCSA_ICON_NAMES"],"mappings":"AACO,MAAMA,IAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAGaC,IAAqB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEaC,IAAkB,CAAC,GAAGF,GAAqB,GAAGC,CAAkB;"}
1
+ {"version":3,"file":"iconNames.js","sources":["../../src/icons/iconNames.ts"],"sourcesContent":["/** 导航侧栏图标 — 与 @gcsa/console-core GcsaNavItem.iconKey 对齐 */\nexport const GCSA_NAV_ICON_NAMES = [\n 'dashboard',\n 'alert',\n 'assets',\n 'settings',\n 'users',\n 'chat'\n] as const;\n\n/** 组件内部 UI 图标(文件名 kebab-case → 注册为 camelCase key) */\nexport const GCSA_UI_ICON_NAMES = [\n 'chevronDown',\n 'chevronUp',\n 'chevronLeft',\n 'chevronRight',\n 'check',\n 'close',\n 'menu',\n 'plus',\n 'upload',\n 'resultEmpty'\n] as const;\n\nexport const GCSA_ICON_NAMES = [...GCSA_NAV_ICON_NAMES, ...GCSA_UI_ICON_NAMES] as const;\n\nexport type GcsaNavIconName = (typeof GCSA_NAV_ICON_NAMES)[number];\nexport type GcsaIconName = (typeof GCSA_ICON_NAMES)[number];\n"],"names":["GCSA_NAV_ICON_NAMES","GCSA_UI_ICON_NAMES","GCSA_ICON_NAMES"],"mappings":"AACO,MAAMA,IAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAGaC,IAAqB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAEaC,IAAkB,CAAC,GAAGF,GAAqB,GAAGC,CAAkB;"}