@sia.soul/sia-react-ui 0.1.3 → 0.1.5

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.
Files changed (44) hide show
  1. package/dist/{Select-CJJ5LQap.d.ts → Select-GiTHMScg.d.cts} +4 -5
  2. package/dist/{Select-CJJ5LQap.d.cts → Select-rtDktLYY.d.ts} +4 -5
  3. package/dist/chart.cjs +731 -707
  4. package/dist/chart.css +1 -1
  5. package/dist/chart.js +3 -2
  6. package/dist/{chunk-6VXOLMKZ.js → chunk-5ZTWY3PG.js} +18 -1
  7. package/dist/{chunk-2RRTDU3N.js → chunk-EJ23MVR6.js} +3 -18
  8. package/dist/chunk-EJDPRAU2.js +36 -0
  9. package/dist/{chunk-IMZT6VCU.js → chunk-IHTODT53.js} +8 -5
  10. package/dist/{chunk-R4OWKIXJ.js → chunk-MJUTLEEE.js} +20 -8
  11. package/dist/{chunk-OQLDEVCF.js → chunk-PX6BOFTW.js} +10 -3
  12. package/dist/{chunk-OAC7BSUR.js → chunk-R7BVDN3Q.js} +91 -43
  13. package/dist/{chunk-Q4XNFMUH.js → chunk-S2JAJCLN.js} +6 -4
  14. package/dist/{chunk-NZAT2RUM.js → chunk-WHARTF2I.js} +10 -1
  15. package/dist/{chunk-I342FGQY.js → chunk-Z3T6RDQP.js} +1 -1
  16. package/dist/{core-DFYheaoJ.d.ts → core-CBtbeAms.d.cts} +2 -1
  17. package/dist/{core-De2pRX5w.d.cts → core-D8BSMfHD.d.ts} +2 -1
  18. package/dist/core.cjs +275 -210
  19. package/dist/core.css +294 -41
  20. package/dist/core.d.cts +3 -2
  21. package/dist/core.d.ts +3 -2
  22. package/dist/core.js +6 -5
  23. package/dist/index.cjs +2709 -2434
  24. package/dist/index.css +295 -42
  25. package/dist/index.d.cts +23 -9
  26. package/dist/index.d.ts +23 -9
  27. package/dist/index.js +414 -224
  28. package/dist/markdown-editor.cjs +52 -20
  29. package/dist/markdown-editor.d.cts +3 -1
  30. package/dist/markdown-editor.d.ts +3 -1
  31. package/dist/markdown-editor.js +2 -1
  32. package/dist/rich-text-editor.cjs +884 -864
  33. package/dist/rich-text-editor.d.cts +3 -1
  34. package/dist/rich-text-editor.d.ts +3 -1
  35. package/dist/rich-text-editor.js +4 -3
  36. package/dist/{select-date-range-DOyG1DGp.d.ts → select-date-range-CQ1vmze_.d.ts} +7 -4
  37. package/dist/{select-date-range-UyYrHex6.d.cts → select-date-range-DRmGaEzP.d.cts} +7 -4
  38. package/dist/select-date-range.cjs +972 -903
  39. package/dist/select-date-range.d.cts +3 -2
  40. package/dist/select-date-range.d.ts +3 -2
  41. package/dist/select-date-range.js +4 -3
  42. package/dist/shared-DAYZvZVu.d.cts +5 -0
  43. package/dist/shared-DAYZvZVu.d.ts +5 -0
  44. package/package.json +1 -1
package/dist/chart.css CHANGED
@@ -791,7 +791,7 @@
791
791
  background: var(--sia-color-surface);
792
792
  border: 2px solid var(--sia-color-primary);
793
793
  border-radius: 4px;
794
- box-shadow: 0 1px 3px rgb(0 0 0 / 12%);
794
+ box-shadow: 0 1px 2px rgb(0 0 0 / 22%);
795
795
  pointer-events: auto;
796
796
  }
797
797
  .sia-chart-data-zoom input::-moz-range-thumb {
package/dist/chart.js CHANGED
@@ -56,9 +56,10 @@ import {
56
56
  smoothSvgPath,
57
57
  svgArcPath,
58
58
  transferCompositeValue
59
- } from "./chunk-I342FGQY.js";
60
- import "./chunk-NZAT2RUM.js";
59
+ } from "./chunk-Z3T6RDQP.js";
60
+ import "./chunk-WHARTF2I.js";
61
61
  import "./chunk-MBS2HXLZ.js";
62
+ import "./chunk-EJDPRAU2.js";
62
63
  export {
63
64
  BarChart,
64
65
  CHART_VIEWBOX_HEIGHT,
@@ -1,3 +1,7 @@
1
+ import {
2
+ useFloatingPlaceholder
3
+ } from "./chunk-EJDPRAU2.js";
4
+
1
5
  // src/components/MarkdownEditor.tsx
2
6
  import { useEffect, useRef, useState } from "react";
3
7
  import "vditor/dist/index.css";
@@ -214,6 +218,7 @@ function MarkdownEditor({
214
218
  onChange,
215
219
  mode = "wysiwyg",
216
220
  placeholder = "\u8BF7\u8F93\u5165 Markdown \u6B63\u6587",
221
+ placeholderMode,
217
222
  minHeight = 320,
218
223
  disabled = false,
219
224
  ariaLabel = "Markdown \u7F16\u8F91\u5668",
@@ -234,9 +239,14 @@ function MarkdownEditor({
234
239
  const smartMarkdownPasteRef = useRef(smartMarkdownPaste);
235
240
  const valueRef = useRef(value ?? defaultValue);
236
241
  const lastEmittedValueRef = useRef(value ?? defaultValue);
242
+ const [hasContent, setHasContent] = useState(Boolean((value ?? defaultValue).trim()));
243
+ const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: hasContent });
237
244
  const [ready, setReady] = useState(false);
238
245
  const [loadError, setLoadError] = useState("");
239
246
  const hasImageUpload = Boolean(onUploadImage);
247
+ useEffect(() => {
248
+ if (value !== void 0) setHasContent(Boolean(value.trim()));
249
+ }, [value]);
240
250
  onChangeRef.current = onChange;
241
251
  saveShortcutRef.current = saveShortcut;
242
252
  uploadImageRef.current = onUploadImage;
@@ -296,6 +306,7 @@ function MarkdownEditor({
296
306
  }
297
307
  } } : {},
298
308
  input: (markdown) => {
309
+ setHasContent(Boolean(markdown.trim()));
299
310
  lastEmittedValueRef.current = markdown;
300
311
  onChangeRef.current?.(markdown);
301
312
  },
@@ -364,11 +375,17 @@ function MarkdownEditor({
364
375
  return /* @__PURE__ */ jsxs(
365
376
  "div",
366
377
  {
367
- className: ["sia-markdown-editor", className].filter(Boolean).join(" "),
378
+ className: ["sia-markdown-editor", floating.className, disabled ? "is-disabled" : "", className].filter(Boolean).join(" "),
368
379
  style: editorStyle,
369
380
  "data-ready": ready ? "true" : "false",
370
381
  ...props,
382
+ onBlurCapture: (event) => {
383
+ props.onBlurCapture?.(event);
384
+ const current = editorRef.current?.getValue();
385
+ if (current !== void 0) setHasContent(Boolean(current.trim()));
386
+ },
371
387
  children: [
388
+ floating.label,
372
389
  /* @__PURE__ */ jsx("div", { ref: mountRef, className: "sia-markdown-editor__mount" }),
373
390
  !ready ? /* @__PURE__ */ jsx("div", { className: "sia-markdown-editor__loading", "aria-live": "polite", children: loadError || "\u6B63\u5728\u52A0\u8F7D\u7F16\u8F91\u5668\u2026" }) : null
374
391
  ]
@@ -568,8 +568,8 @@ var coreIconPaths = {
568
568
  /* @__PURE__ */ jsx2("path", { d: "M15 5.2a3.5 3.5 0 0 1 0 6.6M16.2 14.5c2.9.5 4.4 2.3 4.9 5.5" })
569
569
  ] }),
570
570
  settings: /* @__PURE__ */ jsxs2(Fragment2, { children: [
571
- /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3" }),
572
- /* @__PURE__ */ jsx2("path", { d: "M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6v.2h-4V21a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14H2.8v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1a1.7 1.7 0 0 0 1.9.3A1.7 1.7 0 0 0 10 3v-.2h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9 1.7 1.7 0 0 0 1.6 1h.2v4H21a1.7 1.7 0 0 0-1.6 1Z" })
571
+ /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3.5" }),
572
+ /* @__PURE__ */ jsx2("path", { d: "M10 4.8 10 2 14 2 14 4.8 15.68 5.49 17.66 3.51 20.49 6.34 18.51 8.32 19.2 10 22 10 22 14 19.2 14 18.51 15.68 20.49 17.66 17.66 20.49 15.68 18.51 14 19.2 14 22 10 22 10 19.2 8.32 18.51 6.34 20.49 3.51 17.66 5.49 15.68 4.8 14 2 14 2 10 4.8 10 5.49 8.32 3.51 6.34 6.34 3.51 8.32 5.49Z" })
573
573
  ] }),
574
574
  edit: /* @__PURE__ */ jsxs2(Fragment2, { children: [
575
575
  /* @__PURE__ */ jsx2("path", { d: "M4 20h4l11-11a2.8 2.8 0 0 0-4-4L4 16v4Z" }),
@@ -922,24 +922,9 @@ var PopupPortal = forwardRef2(function PopupPortal2({
922
922
  );
923
923
  });
924
924
 
925
- // src/components/shared.ts
926
- import { useCallback, useState as useState2 } from "react";
927
- function useControllableState({ value, defaultValue, onChange }) {
928
- const [internalValue, setInternalValue] = useState2(defaultValue);
929
- const controlled = value !== void 0;
930
- const currentValue = controlled ? value : internalValue;
931
- const setValue = useCallback((nextValue) => {
932
- if (Object.is(currentValue, nextValue)) return;
933
- if (!controlled) setInternalValue(nextValue);
934
- onChange?.(nextValue);
935
- }, [controlled, currentValue, onChange]);
936
- return [currentValue, setValue];
937
- }
938
-
939
925
  export {
940
926
  ICON_NAMES,
941
927
  FILLED_ICON_NAMES,
942
928
  Icon,
943
- PopupPortal,
944
- useControllableState
929
+ PopupPortal
945
930
  };
@@ -0,0 +1,36 @@
1
+ // src/components/shared.ts
2
+ import { createContext, useCallback, useContext, useState } from "react";
3
+ var PlaceholderModeContext = createContext("default");
4
+ function usePlaceholderMode(mode) {
5
+ const inherited = useContext(PlaceholderModeContext);
6
+ return mode ?? inherited;
7
+ }
8
+ function useControllableState({ value, defaultValue, onChange }) {
9
+ const [internalValue, setInternalValue] = useState(defaultValue);
10
+ const controlled = value !== void 0;
11
+ const currentValue = controlled ? value : internalValue;
12
+ const setValue = useCallback((nextValue) => {
13
+ if (Object.is(currentValue, nextValue)) return;
14
+ if (!controlled) setInternalValue(nextValue);
15
+ onChange?.(nextValue);
16
+ }, [controlled, currentValue, onChange]);
17
+ return [currentValue, setValue];
18
+ }
19
+
20
+ // src/components/FloatingPlaceholder.tsx
21
+ import { jsx } from "react/jsx-runtime";
22
+ function useFloatingPlaceholder({ mode, placeholder, filled, active = false }) {
23
+ const enabled = usePlaceholderMode(mode) === "floating" && Boolean(placeholder);
24
+ return {
25
+ enabled,
26
+ className: enabled ? ` sia-placeholder-floating${filled ? " sia-placeholder-floating--filled" : ""}${active ? " sia-placeholder-floating--active" : ""}` : "",
27
+ label: enabled ? /* @__PURE__ */ jsx("span", { className: "sia-floating-placeholder", "aria-hidden": "true", children: placeholder }) : null
28
+ };
29
+ }
30
+
31
+ export {
32
+ PlaceholderModeContext,
33
+ usePlaceholderMode,
34
+ useControllableState,
35
+ useFloatingPlaceholder
36
+ };
@@ -3,9 +3,12 @@ import {
3
3
  } from "./chunk-MBS2HXLZ.js";
4
4
  import {
5
5
  Icon,
6
- PopupPortal,
7
- useControllableState
8
- } from "./chunk-2RRTDU3N.js";
6
+ PopupPortal
7
+ } from "./chunk-EJ23MVR6.js";
8
+ import {
9
+ useControllableState,
10
+ usePlaceholderMode
11
+ } from "./chunk-EJDPRAU2.js";
9
12
 
10
13
  // src/components/Navigation.tsx
11
14
  import { useEffect, useId, useMemo, useRef, useState } from "react";
@@ -493,7 +496,7 @@ var Input = forwardRef(function Input2({
493
496
  allowClear = false,
494
497
  onClear,
495
498
  showCount = false,
496
- placeholderMode = "default",
499
+ placeholderMode,
497
500
  placeholder,
498
501
  className = "",
499
502
  id,
@@ -510,7 +513,7 @@ var Input = forwardRef(function Input2({
510
513
  const [uncontrolledValue, setUncontrolledValue] = useState3(() => defaultValue === void 0 ? "" : String(defaultValue));
511
514
  const currentText = value !== void 0 ? String(value) : uncontrolledValue;
512
515
  const hasValue = currentText.length > 0;
513
- const floatingPlaceholder = placeholderMode === "floating" && Boolean(placeholder);
516
+ const floatingPlaceholder = usePlaceholderMode(placeholderMode) === "floating" && Boolean(placeholder);
514
517
  const hintId = `${inputId}-hint`;
515
518
  const describedBy = [props["aria-describedby"], hint ? hintId : null].filter(Boolean).join(" ") || void 0;
516
519
  function setRef(node) {
@@ -1,11 +1,14 @@
1
1
  import {
2
2
  Select
3
- } from "./chunk-OAC7BSUR.js";
3
+ } from "./chunk-R7BVDN3Q.js";
4
4
  import {
5
5
  Icon,
6
- PopupPortal,
7
- useControllableState
8
- } from "./chunk-2RRTDU3N.js";
6
+ PopupPortal
7
+ } from "./chunk-EJ23MVR6.js";
8
+ import {
9
+ useControllableState,
10
+ useFloatingPlaceholder
11
+ } from "./chunk-EJDPRAU2.js";
9
12
 
10
13
  // src/components/DatePicker.tsx
11
14
  import { useEffect, useId, useMemo, useRef as useRef2, useState } from "react";
@@ -290,6 +293,7 @@ function DatePicker({
290
293
  onChange,
291
294
  onOpenChange,
292
295
  placeholder,
296
+ placeholderMode,
293
297
  formatValue = (value2) => value2,
294
298
  renderExtraFooter,
295
299
  ...props
@@ -369,8 +373,9 @@ function DatePicker({
369
373
  setCurrentValue(empty);
370
374
  }
371
375
  const display = Array.isArray(currentValue) ? currentValue.map(formatValue).join("\u3001") : currentValue ? formatValue(currentValue) : "";
376
+ const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder: placeholder ?? placeholderFor(picker, showTime, multiple), filled: Boolean(display), active: visible });
372
377
  const triggerLabel = props["aria-label"] ?? (typeof placeholder === "string" ? placeholder : "\u65E5\u671F\u9009\u62E9\u5668");
373
- return /* @__PURE__ */ jsxs2("span", { ref: rootRef, className: `sia-picker sia-picker--${size} sia-picker--${status}${visible ? " is-open" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
378
+ return /* @__PURE__ */ jsxs2("span", { ref: rootRef, className: `sia-picker${floating.className} sia-picker--${size} sia-picker--${status}${visible ? " is-open" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
374
379
  /* @__PURE__ */ jsxs2(
375
380
  "button",
376
381
  {
@@ -398,6 +403,7 @@ function DatePicker({
398
403
  ]
399
404
  }
400
405
  ),
406
+ floating.label,
401
407
  allowClear && display && !disabled ? /* @__PURE__ */ jsx2("button", { type: "button", className: "sia-picker__clear", "aria-label": "\u6E05\u9664\u65E5\u671F", onClick: clearValue, children: /* @__PURE__ */ jsx2(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
402
408
  /* @__PURE__ */ jsxs2(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: visible, className: `sia-date-panel${showTime ? " sia-date-panel--with-time" : ""}${presets?.length ? " sia-date-panel--with-presets" : ""}`, role: "dialog", "aria-label": "\u65E5\u671F\u9009\u62E9\u9762\u677F", children: [
403
409
  /* @__PURE__ */ jsxs2("div", { className: "sia-date-panel__body", children: [
@@ -446,6 +452,7 @@ function DateRangePicker({
446
452
  value,
447
453
  defaultValue = ["", ""],
448
454
  placeholder = ["\u5F00\u59CB\u65E5\u671F", "\u7ED3\u675F\u65E5\u671F"],
455
+ placeholderMode,
449
456
  separator = "\u2192",
450
457
  presets,
451
458
  maxRangeDays,
@@ -475,7 +482,7 @@ function DateRangePicker({
475
482
  const id = useId();
476
483
  const rootRef = useRef2(null);
477
484
  const popupRef = useRef2(null);
478
- const [currentValue, setCurrentValue] = useControllableState({ value, defaultValue, onChange });
485
+ const [currentValue, setCurrentValue] = useControllableState({ value: value === void 0 ? void 0 : Array.isArray(value) ? value : ["", ""], defaultValue, onChange });
479
486
  const [visible, setVisible] = useControllableState({ value: open, defaultValue: defaultOpen, onChange: onOpenChange });
480
487
  const [draftValue, setDraftValue] = useState(currentValue);
481
488
  const [activeIndex, setActiveIndex] = useState(currentValue[0] && !currentValue[1] ? 1 : 0);
@@ -712,7 +719,8 @@ function DateRangePicker({
712
719
  endpointLabel
713
720
  );
714
721
  }
715
- return /* @__PURE__ */ jsxs2("span", { ref: rootRef, className: `sia-picker sia-picker-range-control sia-picker--${size} sia-picker--${status}${visible ? " is-open" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
722
+ const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder: placeholder.filter(Boolean).join(" / "), filled: currentValue.some(Boolean), active: visible });
723
+ return /* @__PURE__ */ jsxs2("span", { ref: rootRef, className: `sia-picker${floating.className} sia-picker-range-control sia-picker--${size} sia-picker--${status}${visible ? " is-open" : ""}${disabled ? " is-disabled" : ""} ${className}`.trim(), children: [
716
724
  /* @__PURE__ */ jsxs2(
717
725
  "button",
718
726
  {
@@ -736,6 +744,7 @@ function DateRangePicker({
736
744
  ]
737
745
  }
738
746
  ),
747
+ floating.label,
739
748
  allowClear && (currentValue[0] || currentValue[1]) && !disabled ? /* @__PURE__ */ jsx2("button", { type: "button", className: "sia-picker__clear", "aria-label": "\u6E05\u9664\u65E5\u671F\u8303\u56F4", onClick: clearValue, children: /* @__PURE__ */ jsx2(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
740
749
  /* @__PURE__ */ jsxs2(PopupPortal, { ref: popupRef, anchorRef: rootRef, open: visible, className: `sia-date-panel sia-date-panel--range${showTime ? ` sia-date-panel--with-time sia-date-panel--range-time-${compactDateTime ? "compact" : "paired"}` : ""}${presets?.length ? " sia-date-panel--with-presets" : ""}`, role: "dialog", "aria-label": "\u65E5\u671F\u8303\u56F4\u9009\u62E9\u9762\u677F", children: [
741
750
  /* @__PURE__ */ jsx2("div", { className: "sia-date-panel__body", children: showTime ? /* @__PURE__ */ jsx2("div", { className: "sia-date-panel__range-date-time", children: compactDateTime ? renderDateTimeGroup(activeIndex) : /* @__PURE__ */ jsxs2(Fragment, { children: [
@@ -805,6 +814,7 @@ function SelectDateRange({
805
814
  value,
806
815
  defaultValue,
807
816
  selectPlaceholder = "\u8BF7\u9009\u62E9\u7C7B\u578B",
817
+ placeholderMode,
808
818
  selectWidth = 180,
809
819
  rangePlaceholder = ["\u5F00\u59CB\u65E5\u671F", "\u7ED3\u675F\u65E5\u671F"],
810
820
  selectAriaLabel = "\u9009\u62E9\u7C7B\u578B",
@@ -819,7 +829,7 @@ function SelectDateRange({
819
829
  ...props
820
830
  }) {
821
831
  const initialValue = defaultValue ?? { select: options[0]?.value ?? "", range: ["", ""] };
822
- const [currentValue, setCurrentValue] = useControllableState({ value, defaultValue: initialValue, onChange });
832
+ const [currentValue, setCurrentValue] = useControllableState({ value: value === void 0 ? void 0 : value && typeof value === "object" ? value : { select: "", range: ["", ""] }, defaultValue: initialValue, onChange });
823
833
  return /* @__PURE__ */ jsxs3("div", { className: `sia-select-date-range sia-select-date-range--${size} ${className}`.trim(), role: "group", "aria-label": `${selectAriaLabel}\u4E0E${rangeAriaLabel}`, ...props, style: { ...style, "--sia-select-date-range-select-width": typeof selectWidth === "number" ? `${selectWidth}px` : selectWidth }, children: [
824
834
  /* @__PURE__ */ jsx3(
825
835
  Select,
@@ -829,6 +839,7 @@ function SelectDateRange({
829
839
  options,
830
840
  value: currentValue.select,
831
841
  placeholder: selectPlaceholder,
842
+ placeholderMode,
832
843
  size,
833
844
  status,
834
845
  disabled,
@@ -845,6 +856,7 @@ function SelectDateRange({
845
856
  "aria-label": rangeAriaLabel,
846
857
  value: currentValue.range,
847
858
  placeholder: rangePlaceholder,
859
+ placeholderMode,
848
860
  presets,
849
861
  size,
850
862
  status,
@@ -1,13 +1,16 @@
1
1
  import {
2
2
  Dropdown,
3
3
  Input
4
- } from "./chunk-IMZT6VCU.js";
4
+ } from "./chunk-IHTODT53.js";
5
5
  import {
6
6
  Button
7
7
  } from "./chunk-MBS2HXLZ.js";
8
8
  import {
9
9
  Icon
10
- } from "./chunk-2RRTDU3N.js";
10
+ } from "./chunk-EJ23MVR6.js";
11
+ import {
12
+ useFloatingPlaceholder
13
+ } from "./chunk-EJDPRAU2.js";
11
14
 
12
15
  // src/components/RichTextEditor.tsx
13
16
  import { useEffect, useMemo, useRef, useState } from "react";
@@ -49,6 +52,7 @@ function RichTextEditor({
49
52
  contentFormat = "html",
50
53
  toolbar = "basic",
51
54
  placeholder = "\u8BF7\u8F93\u5165\u5185\u5BB9",
55
+ placeholderMode,
52
56
  disabled = false,
53
57
  minHeight = 150,
54
58
  pasteImageHint = "\u53EF\u76F4\u63A5\u7C98\u8D34\u56FE\u7247",
@@ -165,6 +169,7 @@ function RichTextEditor({
165
169
  if (!editor || value === void 0 || value === lastEmittedValueRef.current) return;
166
170
  editor.commands.setContent(value, { emitUpdate: false, contentType: contentFormat });
167
171
  lastEmittedValueRef.current = value;
172
+ setEditorRevision((current) => current + 1);
168
173
  }, [contentFormat, editor, value]);
169
174
  function openLinkEditor(open) {
170
175
  if (open && editor) setLinkHref(String(editor.getAttributes("link").href ?? ""));
@@ -218,7 +223,9 @@ function RichTextEditor({
218
223
  else editor.chain().focus().toggleHeading({ level: Number(key.slice(1)) }).run();
219
224
  }
220
225
  };
221
- return /* @__PURE__ */ jsxs("div", { ...props, id, style: mergedStyle, className: `sia-rich-text-editor${disabled ? " is-disabled" : ""} sia-rich-text-editor--${toolbar} ${className}`.trim(), children: [
226
+ const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: editor ? !editor.isEmpty : Boolean(value ?? defaultValue) });
227
+ return /* @__PURE__ */ jsxs("div", { ...props, id, style: mergedStyle, className: `sia-rich-text-editor${floating.className}${disabled ? " is-disabled" : ""} sia-rich-text-editor--${toolbar} ${className}`.trim(), children: [
228
+ floating.label,
222
229
  /* @__PURE__ */ jsxs("div", { className: "sia-rich-text-editor__toolbar", "aria-label": "\u6587\u672C\u683C\u5F0F\u5DE5\u5177\u680F", children: [
223
230
  /* @__PURE__ */ jsxs("div", { className: "sia-rich-text-editor__toolbar-main", children: [
224
231
  toolbar === "full" ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1,12 +1,64 @@
1
1
  import {
2
2
  Icon,
3
- PopupPortal,
4
- useControllableState
5
- } from "./chunk-2RRTDU3N.js";
3
+ PopupPortal
4
+ } from "./chunk-EJ23MVR6.js";
5
+ import {
6
+ useControllableState,
7
+ useFloatingPlaceholder
8
+ } from "./chunk-EJDPRAU2.js";
6
9
 
7
10
  // src/components/Select.tsx
8
- import { forwardRef, useDeferredValue, useEffect, useId, useMemo, useRef, useState } from "react";
11
+ import { forwardRef, useDeferredValue, useEffect, useId, useMemo, useRef as useRef2, useState as useState2 } from "react";
12
+
13
+ // src/components/OverflowTags.tsx
14
+ import { useLayoutEffect, useRef, useState } from "react";
9
15
  import { jsx, jsxs } from "react/jsx-runtime";
16
+ function OverflowTags({ items, maxCount, className = "", tagClassName, restClassName = "" }) {
17
+ const rootRef = useRef(null);
18
+ const measureRef = useRef(null);
19
+ const limit = Math.min(items.length, Math.max(0, Math.floor(maxCount) || 0));
20
+ const [visibleCount, setVisibleCount] = useState(0);
21
+ useLayoutEffect(() => {
22
+ const root = rootRef.current;
23
+ const measure = measureRef.current;
24
+ if (!root || !measure) return;
25
+ const update = () => {
26
+ const gap = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
27
+ const widths = Array.from(measure.children, (child) => child.getBoundingClientRect().width);
28
+ let used = 0;
29
+ let fitting = 0;
30
+ for (let count2 = 1; count2 <= limit; count2 += 1) {
31
+ used += widths[count2 - 1] + (count2 > 1 ? gap : 0);
32
+ const rest = count2 < items.length ? gap + widths[limit + count2] : 0;
33
+ if (used + rest <= root.clientWidth) fitting = count2;
34
+ }
35
+ setVisibleCount((previous) => previous === fitting ? previous : fitting);
36
+ };
37
+ update();
38
+ const observer = new ResizeObserver(update);
39
+ observer.observe(root);
40
+ for (const child of measure.children) observer.observe(child);
41
+ return () => observer.disconnect();
42
+ }, [items, limit]);
43
+ const count = Math.min(visibleCount, limit);
44
+ return /* @__PURE__ */ jsxs("span", { ref: rootRef, className: `sia-overflow-tags ${className}`.trim(), children: [
45
+ items.slice(0, count).map((item) => /* @__PURE__ */ jsx("span", { className: tagClassName, children: item.label }, item.key)),
46
+ items.length > count ? /* @__PURE__ */ jsxs("span", { className: `${tagClassName} sia-overflow-tags__rest ${restClassName}`.trim(), children: [
47
+ "+",
48
+ items.length - count
49
+ ] }) : null,
50
+ /* @__PURE__ */ jsxs("span", { ref: measureRef, className: "sia-overflow-tags__measure", "aria-hidden": "true", children: [
51
+ items.slice(0, limit).map((item) => /* @__PURE__ */ jsx("span", { className: tagClassName, children: item.label }, item.key)),
52
+ Array.from({ length: limit + 1 }, (_, index) => /* @__PURE__ */ jsxs("span", { className: `${tagClassName} ${restClassName}`.trim(), children: [
53
+ "+",
54
+ items.length - index
55
+ ] }, `rest-${index}`))
56
+ ] })
57
+ ] });
58
+ }
59
+
60
+ // src/components/Select.tsx
61
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
10
62
  function defaultFilterOption(query, option) {
11
63
  return String(option.label).toLowerCase().includes(query.toLowerCase());
12
64
  }
@@ -17,6 +69,7 @@ var Select = forwardRef(function Select2({
17
69
  defaultValue,
18
70
  onChange,
19
71
  placeholder = "\u8BF7\u9009\u62E9",
72
+ placeholderMode,
20
73
  size = "medium",
21
74
  status = "default",
22
75
  allowClear = false,
@@ -43,14 +96,14 @@ var Select = forwardRef(function Select2({
43
96
  const fallbackId = useId();
44
97
  const selectId = id ?? fallbackId;
45
98
  const listboxId = `${selectId}-listbox`;
46
- const rootRef = useRef(null);
47
- const popupRef = useRef(null);
48
- const searchRef = useRef(null);
49
- const listRef = useRef(null);
50
- const [open, setOpen] = useState(false);
51
- const [query, setQuery] = useState("");
52
- const [activeIndex, setActiveIndex] = useState(-1);
53
- const [scrollTop, setScrollTop] = useState(0);
99
+ const rootRef = useRef2(null);
100
+ const popupRef = useRef2(null);
101
+ const searchRef = useRef2(null);
102
+ const listRef = useRef2(null);
103
+ const [open, setOpen] = useState2(false);
104
+ const [query, setQuery] = useState2("");
105
+ const [activeIndex, setActiveIndex] = useState2(-1);
106
+ const [scrollTop, setScrollTop] = useState2(0);
54
107
  const deferredQuery = useDeferredValue(query.trim());
55
108
  const initialValue = defaultValue === void 0 ? mode === "multiple" ? [] : null : defaultValue;
56
109
  const [currentValue, setCurrentValue] = useControllableState({
@@ -220,7 +273,7 @@ var Select = forwardRef(function Select2({
220
273
  function renderOption(option, renderedIndex) {
221
274
  const optionIndex = virtualEnabled ? virtualStart + renderedIndex : renderedIndex;
222
275
  const selected = selectedValueSet.has(option.value);
223
- return /* @__PURE__ */ jsxs(
276
+ return /* @__PURE__ */ jsxs2(
224
277
  "div",
225
278
  {
226
279
  id: `${listboxId}-${optionIndex}`,
@@ -233,22 +286,21 @@ var Select = forwardRef(function Select2({
233
286
  onMouseDown: (event) => event.preventDefault(),
234
287
  onClick: () => selectOption(option),
235
288
  children: [
236
- /* @__PURE__ */ jsx("span", { children: option.label }),
237
- selected ? /* @__PURE__ */ jsx(Icon, { name: "check", size: 15 }) : null
289
+ /* @__PURE__ */ jsx2("span", { children: option.label }),
290
+ selected ? /* @__PURE__ */ jsx2(Icon, { name: "check", size: 15 }) : null
238
291
  ]
239
292
  },
240
293
  `${typeof option.value}-${option.value}`
241
294
  );
242
295
  }
243
- const visibleTags = selectedOptions.slice(0, Math.max(0, maxTagCount));
244
- const hiddenTagCount = selectedOptions.length - visibleTags.length;
245
- return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: `sia-select sia-select--${size} sia-select--${status}${open ? " is-open" : ""}${disabled ? " is-disabled" : ""}${multiple ? " sia-select--multiple" : ""} ${className}`.trim(), children: [
246
- /* @__PURE__ */ jsxs(
296
+ const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: hasValue, active: open });
297
+ return /* @__PURE__ */ jsxs2("div", { ref: rootRef, className: `sia-select sia-select--${size} sia-select--${status}${open ? " is-open" : ""}${disabled ? " is-disabled" : ""}${multiple ? " sia-select--multiple" : ""} ${className}`.trim(), children: [
298
+ /* @__PURE__ */ jsxs2(
247
299
  "button",
248
300
  {
249
301
  ...props,
250
302
  ref: forwardedRef,
251
- className: "sia-select__trigger",
303
+ className: `sia-select__trigger${floating.className}`,
252
304
  id: selectId,
253
305
  type: "button",
254
306
  role: "combobox",
@@ -261,41 +313,36 @@ var Select = forwardRef(function Select2({
261
313
  onClick: () => open ? closeDropdown() : openDropdown(),
262
314
  onKeyDown: handleTriggerKeyDown,
263
315
  children: [
264
- multiple && hasValue ? /* @__PURE__ */ jsxs("span", { className: "sia-select__tags", children: [
265
- visibleTags.map((option) => /* @__PURE__ */ jsx("span", { className: "sia-select__tag", children: option.label }, `${typeof option.value}-${option.value}`)),
266
- hiddenTagCount > 0 ? /* @__PURE__ */ jsxs("span", { className: "sia-select__tag sia-select__tag--rest", children: [
267
- "+",
268
- hiddenTagCount
269
- ] }) : null
270
- ] }) : /* @__PURE__ */ jsx("span", { className: `sia-select__value${hasValue ? "" : " is-placeholder"}`, children: selectedOptions[0]?.label ?? placeholder }),
271
- loading ? /* @__PURE__ */ jsx("span", { className: "sia-select__spinner", "aria-hidden": "true" }) : null,
272
- /* @__PURE__ */ jsx(Icon, { className: "sia-select__arrow", name: "chevron-down", size: 15 })
316
+ multiple && hasValue ? /* @__PURE__ */ jsx2(OverflowTags, { className: "sia-select__tags", tagClassName: "sia-select__tag", restClassName: "sia-select__tag--rest", maxCount: maxTagCount, items: selectedOptions.map((option) => ({ key: `${typeof option.value}-${option.value}`, label: option.label })) }) : /* @__PURE__ */ jsx2("span", { className: `sia-select__value${hasValue ? "" : " is-placeholder"}`, children: selectedOptions[0]?.label ?? placeholder }),
317
+ loading ? /* @__PURE__ */ jsx2("span", { className: "sia-select__spinner", "aria-hidden": "true" }) : null,
318
+ floating.label,
319
+ /* @__PURE__ */ jsx2(Icon, { className: "sia-select__arrow", name: "chevron-down", size: 15 })
273
320
  ]
274
321
  }
275
322
  ),
276
- allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ jsx("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ jsx(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
277
- /* @__PURE__ */ jsxs(PopupPortal, { ref: popupRef, anchorRef: rootRef, open, className: "sia-select__dropdown", children: [
278
- showSearch || allowInput ? /* @__PURE__ */ jsxs("label", { className: "sia-select__search", children: [
279
- /* @__PURE__ */ jsx(Icon, { name: "search", size: 15 }),
280
- /* @__PURE__ */ jsx("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
323
+ allowClear && hasValue && !disabled && !loading ? /* @__PURE__ */ jsx2("button", { className: "sia-select__clear", type: "button", "aria-label": "\u6E05\u7A7A\u9009\u62E9", onClick: clearValue, children: /* @__PURE__ */ jsx2(Icon, { name: "circle-close", variant: "filled", size: 15 }) }) : null,
324
+ /* @__PURE__ */ jsxs2(PopupPortal, { ref: popupRef, anchorRef: rootRef, open, className: "sia-select__dropdown", children: [
325
+ showSearch || allowInput ? /* @__PURE__ */ jsxs2("label", { className: "sia-select__search", children: [
326
+ /* @__PURE__ */ jsx2(Icon, { name: "search", size: 15 }),
327
+ /* @__PURE__ */ jsx2("input", { ref: searchRef, value: query, maxLength: inputMaxLength, onChange: handleSearchChange, onKeyDown: (event) => handleInteractionKeyDown(event, true), placeholder: searchPlaceholder, "aria-label": searchPlaceholder })
281
328
  ] }) : null,
282
- canSubmitInput ? /* @__PURE__ */ jsxs("button", { type: "button", className: "sia-select__input-option", onMouseDown: (event) => event.preventDefault(), onClick: submitInputValue, children: [
283
- /* @__PURE__ */ jsx(Icon, { name: "plus", size: 14 }),
284
- /* @__PURE__ */ jsxs("span", { children: [
329
+ canSubmitInput ? /* @__PURE__ */ jsxs2("button", { type: "button", className: "sia-select__input-option", onMouseDown: (event) => event.preventDefault(), onClick: submitInputValue, children: [
330
+ /* @__PURE__ */ jsx2(Icon, { name: "plus", size: 14 }),
331
+ /* @__PURE__ */ jsxs2("span", { children: [
285
332
  "\u4F7F\u7528\u201C",
286
333
  inputValue,
287
334
  "\u201D"
288
335
  ] })
289
336
  ] }) : null,
290
- multiple && showSelectAll ? /* @__PURE__ */ jsxs("div", { className: "sia-select__actions", children: [
291
- /* @__PURE__ */ jsx("button", { type: "button", disabled: allFilteredSelected || enabledFilteredOptions.length === 0, onClick: selectAllFiltered, children: "\u5168\u9009" }),
292
- /* @__PURE__ */ jsx("button", { type: "button", disabled: !hasValue, onClick: clearSelection, children: "\u6E05\u9664" }),
293
- /* @__PURE__ */ jsxs("span", { children: [
337
+ multiple && showSelectAll ? /* @__PURE__ */ jsxs2("div", { className: "sia-select__actions", children: [
338
+ /* @__PURE__ */ jsx2("button", { type: "button", disabled: allFilteredSelected || enabledFilteredOptions.length === 0, onClick: selectAllFiltered, children: "\u5168\u9009" }),
339
+ /* @__PURE__ */ jsx2("button", { type: "button", disabled: !hasValue, onClick: clearSelection, children: "\u6E05\u9664" }),
340
+ /* @__PURE__ */ jsxs2("span", { children: [
294
341
  selectedValues.length,
295
342
  " \u9879\u5DF2\u9009"
296
343
  ] })
297
344
  ] }) : null,
298
- /* @__PURE__ */ jsx(
345
+ /* @__PURE__ */ jsx2(
299
346
  "div",
300
347
  {
301
348
  ref: listRef,
@@ -306,7 +353,7 @@ var Select = forwardRef(function Select2({
306
353
  "aria-multiselectable": multiple || void 0,
307
354
  style: { maxHeight: listHeight },
308
355
  onScroll: handleListScroll,
309
- children: filteredOptions.length > 0 ? virtualEnabled ? /* @__PURE__ */ jsx("div", { className: "sia-select__virtual-space", style: { height: filteredOptions.length * optionHeight }, children: renderedOptions.map(renderOption) }) : renderedOptions.map(renderOption) : canSubmitInput ? null : /* @__PURE__ */ jsx("div", { className: "sia-select__empty", children: notFoundContent })
356
+ children: filteredOptions.length > 0 ? virtualEnabled ? /* @__PURE__ */ jsx2("div", { className: "sia-select__virtual-space", style: { height: filteredOptions.length * optionHeight }, children: renderedOptions.map(renderOption) }) : renderedOptions.map(renderOption) : canSubmitInput ? null : /* @__PURE__ */ jsx2("div", { className: "sia-select__empty", children: notFoundContent })
310
357
  }
311
358
  )
312
359
  ] })
@@ -314,5 +361,6 @@ var Select = forwardRef(function Select2({
314
361
  });
315
362
 
316
363
  export {
364
+ OverflowTags,
317
365
  Select
318
366
  };
@@ -1,16 +1,18 @@
1
1
  import {
2
2
  TextArea
3
- } from "./chunk-NZAT2RUM.js";
3
+ } from "./chunk-WHARTF2I.js";
4
4
  import {
5
5
  Dropdown
6
- } from "./chunk-IMZT6VCU.js";
6
+ } from "./chunk-IHTODT53.js";
7
7
  import {
8
8
  Button
9
9
  } from "./chunk-MBS2HXLZ.js";
10
10
  import {
11
- Icon,
11
+ Icon
12
+ } from "./chunk-EJ23MVR6.js";
13
+ import {
12
14
  useControllableState
13
- } from "./chunk-2RRTDU3N.js";
15
+ } from "./chunk-EJDPRAU2.js";
14
16
 
15
17
  // src/components/Card.tsx
16
18
  import { useState } from "react";
@@ -1,3 +1,7 @@
1
+ import {
2
+ useFloatingPlaceholder
3
+ } from "./chunk-EJDPRAU2.js";
4
+
1
5
  // src/components/TextArea.tsx
2
6
  import { forwardRef, useId, useState } from "react";
3
7
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -6,6 +10,8 @@ var TextArea = forwardRef(function TextArea2({
6
10
  hint,
7
11
  status = "default",
8
12
  showCount = false,
13
+ placeholder,
14
+ placeholderMode,
9
15
  className = "",
10
16
  id,
11
17
  disabled,
@@ -19,13 +25,14 @@ var TextArea = forwardRef(function TextArea2({
19
25
  const textAreaId = id ?? fallbackId;
20
26
  const [uncontrolledValue, setUncontrolledValue] = useState(() => defaultValue === void 0 ? "" : String(defaultValue));
21
27
  const currentText = value !== void 0 ? String(value) : uncontrolledValue;
28
+ const floating = useFloatingPlaceholder({ mode: placeholderMode, placeholder, filled: currentText.length > 0 });
22
29
  const hintId = `${textAreaId}-hint`;
23
30
  const describedBy = [props["aria-describedby"], hint ? hintId : null].filter(Boolean).join(" ") || void 0;
24
31
  function handleChange(event) {
25
32
  setUncontrolledValue(event.target.value);
26
33
  onChange?.(event);
27
34
  }
28
- const control = /* @__PURE__ */ jsxs("span", { className: `sia-textarea-control sia-textarea-control--${status}${disabled ? " is-disabled" : ""}`, children: [
35
+ const control = /* @__PURE__ */ jsxs("span", { className: `sia-textarea-control sia-textarea-control--${status}${floating.className}${disabled ? " is-disabled" : ""}`, children: [
29
36
  /* @__PURE__ */ jsx(
30
37
  "textarea",
31
38
  {
@@ -37,11 +44,13 @@ var TextArea = forwardRef(function TextArea2({
37
44
  value,
38
45
  defaultValue,
39
46
  maxLength,
47
+ placeholder,
40
48
  "aria-describedby": describedBy,
41
49
  "aria-invalid": status === "error" || void 0,
42
50
  onChange: handleChange
43
51
  }
44
52
  ),
53
+ floating.label,
45
54
  showCount ? /* @__PURE__ */ jsxs("span", { className: `sia-textarea-control__count${maxLength !== void 0 && currentText.length >= maxLength ? " is-limit" : ""}`, "aria-live": "polite", children: [
46
55
  currentText.length,
47
56
  maxLength !== void 0 ? `/${maxLength}` : null
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TextArea
3
- } from "./chunk-NZAT2RUM.js";
3
+ } from "./chunk-WHARTF2I.js";
4
4
  import {
5
5
  Button
6
6
  } from "./chunk-MBS2HXLZ.js";