@zenkigen-inc/component-ui 1.22.0 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1502,7 +1502,7 @@ import {
1502
1502
  import { DayPicker } from "react-day-picker";
1503
1503
 
1504
1504
  // src/popover/popover.tsx
1505
- import { autoUpdate as autoUpdate2, offset as offset2, useFloating as useFloating2, useId as useFloatingId } from "@floating-ui/react";
1505
+ import { autoUpdate as autoUpdate2, flip as flip2, offset as offset2, shift, useFloating as useFloating2, useId as useFloatingId } from "@floating-ui/react";
1506
1506
  import { useEffect as useEffect8, useMemo as useMemo4, useRef as useRef7 } from "react";
1507
1507
 
1508
1508
  // src/popover/popover-content.tsx
@@ -1544,6 +1544,9 @@ function isElement(node) {
1544
1544
  return node != null && typeof node === "object" && "type" in node;
1545
1545
  }
1546
1546
 
1547
+ // src/utils/top-layer.ts
1548
+ var TOP_LAYER_ATTRIBUTE = "data-zenkigen-top-layer";
1549
+
1547
1550
  // src/popover/popover-context.ts
1548
1551
  import { createContext as createContext5, useContext as useContext5 } from "react";
1549
1552
  var PopoverContext = createContext5(null);
@@ -1672,6 +1675,7 @@ var PopoverTrigger = forwardRef7(function PopoverTrigger2({ children }, ref) {
1672
1675
 
1673
1676
  // src/popover/popover.tsx
1674
1677
  import { jsx as jsx21 } from "react/jsx-runtime";
1678
+ var FLOATING_VIEWPORT_PADDING2 = 8;
1675
1679
  function Popover({
1676
1680
  isOpen,
1677
1681
  children,
@@ -1681,6 +1685,14 @@ function Popover({
1681
1685
  anchorRef
1682
1686
  }) {
1683
1687
  const triggerRef = useRef7(null);
1688
+ const middleware = useMemo4(
1689
+ () => [
1690
+ offset2(offsetValue),
1691
+ flip2({ padding: FLOATING_VIEWPORT_PADDING2, flipAlignment: false }),
1692
+ shift({ padding: FLOATING_VIEWPORT_PADDING2 })
1693
+ ],
1694
+ [offsetValue]
1695
+ );
1684
1696
  const floating = useFloating2({
1685
1697
  open: isOpen,
1686
1698
  onOpenChange: (open) => {
@@ -1689,7 +1701,7 @@ function Popover({
1689
1701
  }
1690
1702
  },
1691
1703
  placement,
1692
- middleware: [offset2(offsetValue)],
1704
+ middleware,
1693
1705
  whileElementsMounted: autoUpdate2,
1694
1706
  strategy: "fixed"
1695
1707
  });
@@ -1737,27 +1749,83 @@ import { DayButton } from "react-day-picker";
1737
1749
  import { clsx as clsx15 } from "clsx";
1738
1750
  import { getDefaultClassNames } from "react-day-picker";
1739
1751
  var defaultDayPickerClassNames = getDefaultClassNames();
1740
- var DAY_PICKER_FONT_SIZE = "12px";
1741
- var dayPickerStyle = {
1742
- "--rdp-nav-height": "30px",
1743
- "--rdp-day-width": "30px",
1744
- "--rdp-day-height": "30px",
1745
- "--rdp-day_button-width": "28px",
1746
- "--rdp-day_button-height": "28px",
1747
- "--rdp-day_button-border": "1px solid transparent",
1748
- "--rdp-weekday-padding": "0px",
1749
- fontFamily: "Arial, 'Noto Sans JP', sans-serif",
1750
- fontSize: DAY_PICKER_FONT_SIZE,
1751
- fontWeight: 700
1752
+ var BASE_TOKENS = {
1753
+ triggerIcon: "small",
1754
+ dayPickerStyle: {
1755
+ "--rdp-nav-height": "30px",
1756
+ "--rdp-day-width": "30px",
1757
+ "--rdp-day-height": "30px",
1758
+ "--rdp-day_button-width": "28px",
1759
+ "--rdp-day_button-height": "28px",
1760
+ "--rdp-day_button-border": "1px solid transparent",
1761
+ "--rdp-weekday-padding": "0px",
1762
+ fontFamily: "Arial, 'Noto Sans JP', sans-serif",
1763
+ fontSize: "12px",
1764
+ fontWeight: 700
1765
+ },
1766
+ dayPickerClassNames: {
1767
+ month: clsx15(defaultDayPickerClassNames.month, "flex flex-col px-[7px] py-2")
1768
+ },
1769
+ dayButtonClass: "relative grid size-full place-items-center rounded-full !border !border-solid",
1770
+ dayButtonFontSize: "12px",
1771
+ monthCaptionClass: "flex items-center justify-between px-1 pb-0.5",
1772
+ monthCaptionTypography: "typography-label12bold",
1773
+ navIconButton: "small",
1774
+ weekdayClass: "m-0 size-7 p-0 text-center align-middle",
1775
+ footerIconButton: "medium",
1776
+ footerClearButton: "small",
1777
+ errorTypography: "typography-label11regular"
1778
+ };
1779
+ var LARGE_TOKENS = {
1780
+ ...BASE_TOKENS,
1781
+ triggerIcon: "medium",
1782
+ errorTypography: "typography-label12regular"
1783
+ };
1784
+ var X_LARGE_TOKENS = {
1785
+ triggerIcon: "medium",
1786
+ dayPickerStyle: {
1787
+ "--rdp-nav-height": "40px",
1788
+ "--rdp-day-width": "48px",
1789
+ "--rdp-day-height": "48px",
1790
+ "--rdp-day_button-width": "40px",
1791
+ "--rdp-day_button-height": "40px",
1792
+ "--rdp-day_button-border": "1px solid transparent",
1793
+ "--rdp-weekday-padding": "0px",
1794
+ fontFamily: "Arial, 'Noto Sans JP', sans-serif",
1795
+ fontSize: "16px",
1796
+ fontWeight: 700
1797
+ },
1798
+ dayPickerClassNames: {
1799
+ month: clsx15(defaultDayPickerClassNames.month, "flex flex-col px-[3px] pb-1 pt-2")
1800
+ },
1801
+ dayButtonClass: "relative grid size-10 place-items-center rounded-full !border !border-solid",
1802
+ dayButtonFontSize: "16px",
1803
+ // caption は height 固定(--rdp-nav-height: 40px)のため pb-2 は食い込みとして働き、
1804
+ // ナビボタンが上へ 4px はみ出して月ヘッダーと曜日行の視覚間隔が 8px になる(上部ブロックコメント参照)
1805
+ monthCaptionClass: "flex items-center justify-between px-1 pb-2",
1806
+ monthCaptionTypography: "typography-label16bold",
1807
+ // IconButton に x-large は無いが、large が 40px で Figma と一致する(内部アイコンも 24px になる)
1808
+ navIconButton: "large",
1809
+ weekdayClass: "m-0 size-12 p-0 text-center align-middle",
1810
+ footerIconButton: "large",
1811
+ footerClearButton: "large",
1812
+ errorTypography: "typography-label12regular"
1752
1813
  };
1753
- var dayPickerClassNames = {
1754
- month: clsx15(defaultDayPickerClassNames.month, "flex flex-col px-[7px] py-2")
1814
+ var DATE_PICKER_SIZE_TOKENS = {
1815
+ small: BASE_TOKENS,
1816
+ medium: BASE_TOKENS,
1817
+ large: LARGE_TOKENS,
1818
+ "x-large": X_LARGE_TOKENS
1819
+ };
1820
+ var useDatePickerSizeTokens = (componentName = "DatePicker \u306E\u30AB\u30EC\u30F3\u30C0\u30FC") => {
1821
+ const context = useDatePickerCompoundContext(componentName);
1822
+ return { ...context, tokens: DATE_PICKER_SIZE_TOKENS[context.size] };
1755
1823
  };
1756
- var dayButtonBaseClass = "relative grid size-full place-items-center rounded-full !border !border-solid";
1757
1824
 
1758
1825
  // src/date-picker/date-picker-day-button.tsx
1759
1826
  import { jsx as jsx22 } from "react/jsx-runtime";
1760
1827
  var CustomDayButton = ({ day, modifiers, className, style, ...buttonProps }) => {
1828
+ const { tokens } = useDatePickerSizeTokens();
1761
1829
  const isSelected = Boolean(modifiers.selected);
1762
1830
  const isOutside = Boolean(modifiers.outside);
1763
1831
  const isMinMaxDisabled = Boolean(modifiers.minMaxDisabled);
@@ -1770,10 +1838,10 @@ var CustomDayButton = ({ day, modifiers, className, style, ...buttonProps }) =>
1770
1838
  ...buttonProps,
1771
1839
  day,
1772
1840
  modifiers,
1773
- style: { ...style, fontSize: DAY_PICKER_FONT_SIZE },
1841
+ style: { ...style, fontSize: tokens.dayButtonFontSize },
1774
1842
  className: clsx16(
1775
1843
  className,
1776
- dayButtonBaseClass,
1844
+ tokens.dayButtonClass,
1777
1845
  // 共通: フォーカスリング(有効な日のみ)
1778
1846
  // react-day-picker の rdp-day_button クラスが outline: none を設定しているため、!important で上書き
1779
1847
  !isDisabledDay && focusVisible5.normalImportant,
@@ -1799,8 +1867,8 @@ import { forwardRef as forwardRef8 } from "react";
1799
1867
  import { jsx as jsx23 } from "react/jsx-runtime";
1800
1868
  var DatePickerErrorMessage = forwardRef8(
1801
1869
  ({ "aria-live": ariaLive = "assertive", ...props }, ref) => {
1802
- const { size, isError } = useDatePickerCompoundContext("DatePicker.ErrorMessage");
1803
- const typographyClass = size === "large" ? "typography-label12regular" : "typography-label11regular";
1870
+ const { isError, tokens } = useDatePickerSizeTokens("DatePicker.ErrorMessage");
1871
+ const typographyClass = tokens.errorTypography;
1804
1872
  if (isError !== true) {
1805
1873
  return null;
1806
1874
  }
@@ -1881,11 +1949,12 @@ import { jsx as jsx24, jsxs as jsxs7 } from "react/jsx-runtime";
1881
1949
  var CustomMonthCaption = ({ calendarMonth, className, displayIndex, style, ...props }) => {
1882
1950
  void displayIndex;
1883
1951
  const { goToMonth, nextMonth, previousMonth } = useDayPicker();
1952
+ const { tokens } = useDatePickerSizeTokens();
1884
1953
  const captionMonth = calendarMonth.date;
1885
1954
  return /* @__PURE__ */ jsxs7(
1886
1955
  "div",
1887
1956
  {
1888
- className: clsx18("flex items-center justify-between px-1 pb-0.5", className),
1957
+ className: clsx18(tokens.monthCaptionClass, className),
1889
1958
  style: { ...style, fontSize: "inherit", fontWeight: "inherit" },
1890
1959
  ...props,
1891
1960
  children: [
@@ -1893,19 +1962,19 @@ var CustomMonthCaption = ({ calendarMonth, className, displayIndex, style, ...pr
1893
1962
  IconButton,
1894
1963
  {
1895
1964
  icon: "angle-left",
1896
- size: "small",
1965
+ size: tokens.navIconButton,
1897
1966
  variant: "text",
1898
1967
  isDisabled: !previousMonth,
1899
1968
  "aria-label": "\u524D\u306E\u6708",
1900
1969
  onClick: () => previousMonth && goToMonth(previousMonth)
1901
1970
  }
1902
1971
  ),
1903
- /* @__PURE__ */ jsx24("span", { className: "typography-label12bold text-text02", children: formatMonthLabel(captionMonth) }),
1972
+ /* @__PURE__ */ jsx24("span", { className: clsx18(tokens.monthCaptionTypography, "text-text02"), children: formatMonthLabel(captionMonth) }),
1904
1973
  /* @__PURE__ */ jsx24(
1905
1974
  IconButton,
1906
1975
  {
1907
1976
  icon: "angle-right",
1908
- size: "small",
1977
+ size: tokens.navIconButton,
1909
1978
  variant: "text",
1910
1979
  isDisabled: !nextMonth,
1911
1980
  "aria-label": "\u6B21\u306E\u6708",
@@ -1921,11 +1990,12 @@ var CustomMonthCaption = ({ calendarMonth, className, displayIndex, style, ...pr
1921
1990
  import { clsx as clsx19 } from "clsx";
1922
1991
  import { jsx as jsx25 } from "react/jsx-runtime";
1923
1992
  var CustomWeekday = ({ className, children, style, ...props }) => {
1993
+ const { tokens } = useDatePickerSizeTokens();
1924
1994
  return /* @__PURE__ */ jsx25(
1925
1995
  "th",
1926
1996
  {
1927
1997
  ...props,
1928
- className: clsx19(className, "m-0 size-7 p-0 text-center align-middle text-text02"),
1998
+ className: clsx19(className, tokens.weekdayClass, "text-text02"),
1929
1999
  style: { ...style, fontSize: "inherit", fontWeight: "bold" },
1930
2000
  children
1931
2001
  }
@@ -2060,7 +2130,7 @@ var DatePicker = ({
2060
2130
  formatWeekdayName: (date) => weekdayFormatter.format(date)
2061
2131
  };
2062
2132
  }, []);
2063
- const iconSize = size === "large" ? "medium" : "small";
2133
+ const tokens = DATE_PICKER_SIZE_TOKENS[size];
2064
2134
  const displayText = value ? formatDisplayDate(value, timeZone) : placeholder;
2065
2135
  const displayTextClasses = "min-w-0 truncate";
2066
2136
  const errorIds = [];
@@ -2108,7 +2178,7 @@ var DatePicker = ({
2108
2178
  size,
2109
2179
  variant: isError ? "outlineDanger" : "outline",
2110
2180
  isDisabled,
2111
- before: /* @__PURE__ */ jsx26(Icon, { name: "calendar", size: iconSize }),
2181
+ before: /* @__PURE__ */ jsx26(Icon, { name: "calendar", size: tokens.triggerIcon }),
2112
2182
  justifyContent: "start",
2113
2183
  onClick: handleTriggerClick,
2114
2184
  children: /* @__PURE__ */ jsx26("span", { className: displayTextClasses, children: displayText })
@@ -2122,7 +2192,7 @@ var DatePicker = ({
2122
2192
  showOutsideDays: true,
2123
2193
  hideNavigation: true,
2124
2194
  weekStartsOn: 0,
2125
- style: dayPickerStyle,
2195
+ style: tokens.dayPickerStyle,
2126
2196
  month: displayMonth,
2127
2197
  onMonthChange: setDisplayMonth,
2128
2198
  selected: selectedDate,
@@ -2130,7 +2200,7 @@ var DatePicker = ({
2130
2200
  today: todayForCalendar,
2131
2201
  disabled: disabledDays,
2132
2202
  modifiers: { minMaxDisabled: isMinMaxDisabled },
2133
- classNames: dayPickerClassNames,
2203
+ classNames: tokens.dayPickerClassNames,
2134
2204
  formatters,
2135
2205
  fixedWeeks: true,
2136
2206
  components: { MonthCaption: CustomMonthCaption, DayButton: CustomDayButton, Weekday: CustomWeekday }
@@ -2141,14 +2211,14 @@ var DatePicker = ({
2141
2211
  IconButton,
2142
2212
  {
2143
2213
  icon: "calendar-today",
2144
- size: "medium",
2214
+ size: tokens.footerIconButton,
2145
2215
  variant: "text",
2146
2216
  "aria-label": "\u4ECA\u65E5\u306B\u623B\u308B",
2147
2217
  iconAccentColor: "supportInfo",
2148
2218
  onClick: handleClickToday
2149
2219
  }
2150
2220
  ),
2151
- /* @__PURE__ */ jsx26(Button, { type: "button", size: "small", variant: "text", onClick: handleClear, children: "\u30AF\u30EA\u30A2" })
2221
+ /* @__PURE__ */ jsx26(Button, { type: "button", size: tokens.footerClearButton, variant: "text", onClick: handleClear, children: "\u30AF\u30EA\u30A2" })
2152
2222
  ] })
2153
2223
  ] }) })
2154
2224
  ] });
@@ -2828,7 +2898,8 @@ function Loading({ size = "medium", position = "fixed", height = "100%" }) {
2828
2898
  }
2829
2899
 
2830
2900
  // src/modal/modal.tsx
2831
- import { useEffect as useEffect10, useState as useState9 } from "react";
2901
+ import { FloatingFocusManager, useFloating as useFloating3 } from "@floating-ui/react";
2902
+ import { useEffect as useEffect10, useId as useId5, useLayoutEffect as useLayoutEffect3, useRef as useRef11, useState as useState9 } from "react";
2832
2903
  import { createPortal as createPortal2 } from "react-dom";
2833
2904
 
2834
2905
  // src/modal/body-scroll-lock.tsx
@@ -2902,10 +2973,16 @@ function ModalFooter({ children, isNoBorder = false }) {
2902
2973
 
2903
2974
  // src/modal/modal-header.tsx
2904
2975
  import clsx28 from "clsx";
2905
- import { useContext as useContext9 } from "react";
2976
+ import { useContext as useContext9, useLayoutEffect as useLayoutEffect2 } from "react";
2906
2977
  import { jsx as jsx36, jsxs as jsxs13 } from "react/jsx-runtime";
2907
2978
  function ModalHeader({ children, isNoBorder = false }) {
2908
- const { onClose } = useContext9(ModalContext);
2979
+ const { onClose, titleId, setHasTitle } = useContext9(ModalContext);
2980
+ useLayoutEffect2(() => {
2981
+ setHasTitle?.(true);
2982
+ return () => {
2983
+ setHasTitle?.(false);
2984
+ };
2985
+ }, [setHasTitle]);
2909
2986
  const headerClasses = clsx28(
2910
2987
  "typography-h5 flex w-full shrink-0 items-center justify-between rounded-t-lg px-6 text-text01",
2911
2988
  {
@@ -2915,7 +2992,7 @@ function ModalHeader({ children, isNoBorder = false }) {
2915
2992
  }
2916
2993
  );
2917
2994
  return /* @__PURE__ */ jsxs13("div", { className: headerClasses, children: [
2918
- /* @__PURE__ */ jsx36("div", { children }),
2995
+ /* @__PURE__ */ jsx36("div", { id: titleId, children }),
2919
2996
  onClose && /* @__PURE__ */ jsx36(IconButton, { icon: "close", size: "small", variant: "text", onClick: onClose })
2920
2997
  ] });
2921
2998
  }
@@ -2924,6 +3001,9 @@ function ModalHeader({ children, isNoBorder = false }) {
2924
3001
  import { Fragment as Fragment5, jsx as jsx37, jsxs as jsxs14 } from "react/jsx-runtime";
2925
3002
  var LIMIT_WIDTH = 320;
2926
3003
  var LIMIT_HEIGHT = 184;
3004
+ var MODAL_OVERLAY_ATTRIBUTE = "data-zenkigen-modal-overlay";
3005
+ var FOLLOWING_INSIDE_SELECTOR = `[data-floating-ui-portal],[${MODAL_OVERLAY_ATTRIBUTE}],[data-floating-ui-focus-guard]`;
3006
+ var isFollowing = (base, target) => (base.compareDocumentPosition(target) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0;
2927
3007
  function Modal({
2928
3008
  children,
2929
3009
  width = 480,
@@ -2934,6 +3014,26 @@ function Modal({
2934
3014
  portalTargetRef
2935
3015
  }) {
2936
3016
  const [isMounted, setIsMounted] = useState9(false);
3017
+ const overlayRef = useRef11(null);
3018
+ const titleId = useId5();
3019
+ const [hasTitle, setHasTitle] = useState9(false);
3020
+ const { refs, context } = useFloating3({ open: isOpen });
3021
+ const returnFocusRef = useRef11(null);
3022
+ useLayoutEffect3(() => {
3023
+ if (isOpen) {
3024
+ returnFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
3025
+ }
3026
+ }, [isOpen]);
3027
+ const getInsideElements = () => {
3028
+ const overlay = overlayRef.current;
3029
+ const topLayers = Array.from(document.querySelectorAll(`[${TOP_LAYER_ATTRIBUTE}]`));
3030
+ const following = overlay == null ? [] : Array.from(document.querySelectorAll(FOLLOWING_INSIDE_SELECTOR)).filter(
3031
+ (element) => isFollowing(overlay, element)
3032
+ );
3033
+ return [...topLayers, ...following].filter(
3034
+ (element) => element !== document.body && element !== document.documentElement
3035
+ );
3036
+ };
2937
3037
  const renderWidth = typeof width === "number" ? Math.max(width, LIMIT_WIDTH) : width;
2938
3038
  const renderHeight = typeof height === "number" ? Math.max(height, LIMIT_HEIGHT) : height;
2939
3039
  useEffect10(() => {
@@ -2947,16 +3047,36 @@ function Modal({
2947
3047
  return isMounted && isOpen ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
2948
3048
  /* @__PURE__ */ jsx37(BodyScrollLock, {}),
2949
3049
  createPortal2(
2950
- /* @__PURE__ */ jsx37(ModalContext.Provider, { value: { onClose }, children: /* @__PURE__ */ jsx37("div", { className: "fixed left-0 top-0 z-overlay flex size-full items-center justify-center bg-backgroundOverlayBlack py-4", children: /* @__PURE__ */ jsx37(
2951
- "div",
3050
+ /* @__PURE__ */ jsx37(ModalContext.Provider, { value: { onClose, titleId, setHasTitle }, children: /* @__PURE__ */ jsx37(
3051
+ FloatingFocusManager,
2952
3052
  {
2953
- role: "dialog",
2954
- "aria-modal": "true",
2955
- className: "grid max-h-full min-h-[120px] grid-rows-[max-content_1fr_max-content] flex-col rounded-lg bg-uiBackground01 shadow-modalShadow",
2956
- style: { width: renderWidth, height: renderHeight, maxWidth },
2957
- children
3053
+ context,
3054
+ initialFocus: refs.floating,
3055
+ returnFocus: returnFocusRef,
3056
+ outsideElementsInert: true,
3057
+ getInsideElements,
3058
+ children: /* @__PURE__ */ jsx37(
3059
+ "div",
3060
+ {
3061
+ ref: overlayRef,
3062
+ ...{ [MODAL_OVERLAY_ATTRIBUTE]: "" },
3063
+ className: "fixed left-0 top-0 z-overlay flex size-full items-center justify-center bg-backgroundOverlayBlack py-4",
3064
+ children: /* @__PURE__ */ jsx37(
3065
+ "div",
3066
+ {
3067
+ ref: refs.setFloating,
3068
+ role: "dialog",
3069
+ "aria-modal": "true",
3070
+ ...hasTitle && { "aria-labelledby": titleId },
3071
+ className: "grid max-h-full min-h-[120px] grid-rows-[max-content_1fr_max-content] flex-col rounded-lg bg-uiBackground01 shadow-modalShadow outline-none",
3072
+ style: { width: renderWidth, height: renderHeight, maxWidth },
3073
+ children
3074
+ }
3075
+ )
3076
+ }
3077
+ )
2958
3078
  }
2959
- ) }) }),
3079
+ ) }),
2960
3080
  portalTargetRef?.current != null ? portalTargetRef.current : document.body
2961
3081
  )
2962
3082
  ] }) : null;
@@ -2995,7 +3115,8 @@ function NotificationInline({ state = "default", size = "medium", variant = "def
2995
3115
  "fill-supportSuccess": state === "success"
2996
3116
  });
2997
3117
  const textClasses = clsx29("flex-1", {
2998
- "pt-[2px]": size === "medium" && state !== "default"
3118
+ "pt-[3px]": size === "medium" && state !== "default",
3119
+ "pt-[1px]": size === "small" && state !== "default"
2999
3120
  });
3000
3121
  const iconName = {
3001
3122
  attention: "attention",
@@ -3116,15 +3237,16 @@ function Pagination({ currentPage, totalPage, sideNumPagesToShow = 3, onClick })
3116
3237
  }
3117
3238
 
3118
3239
  // src/select/select.tsx
3119
- import { autoUpdate as autoUpdate3, FloatingPortal as FloatingPortal3, offset as offset3, size as sizeMiddleware2, useFloating as useFloating3 } from "@floating-ui/react";
3240
+ import { autoUpdate as autoUpdate3, FloatingPortal as FloatingPortal3, offset as offset3, size as sizeMiddleware2, useFloating as useFloating4 } from "@floating-ui/react";
3120
3241
  import { focusVisible as focusVisible11, selectColors } from "@zenkigen-inc/component-theme";
3121
3242
  import clsx33 from "clsx";
3122
- import { useRef as useRef11, useState as useState10 } from "react";
3243
+ import { useRef as useRef12, useState as useState10 } from "react";
3123
3244
 
3124
3245
  // src/select/select-context.ts
3125
3246
  import { createContext as createContext10 } from "react";
3126
3247
  var SelectContext = createContext10({
3127
3248
  size: "medium",
3249
+ isDeselectVisible: false,
3128
3250
  setIsOptionListOpen: () => false,
3129
3251
  variant: "outline",
3130
3252
  isError: false
@@ -3163,31 +3285,43 @@ function SelectItem({ option }) {
3163
3285
  // src/select/select-list.tsx
3164
3286
  import { focusVisible as focusVisible10 } from "@zenkigen-inc/component-theme";
3165
3287
  import clsx32 from "clsx";
3166
- import { forwardRef as forwardRef10, useContext as useContext12, useLayoutEffect as useLayoutEffect2 } from "react";
3288
+ import { forwardRef as forwardRef10, useContext as useContext12, useLayoutEffect as useLayoutEffect4 } from "react";
3167
3289
  import { jsx as jsx42, jsxs as jsxs18 } from "react/jsx-runtime";
3168
3290
  var SelectList = forwardRef10(({ children, maxHeight }, ref) => {
3169
- const { selectedOption, setIsOptionListOpen, variant, placeholder, onChange, floatingStyles, floatingRef, size } = useContext12(SelectContext);
3291
+ const {
3292
+ selectedOption,
3293
+ setIsOptionListOpen,
3294
+ variant,
3295
+ isDeselectVisible,
3296
+ onChange,
3297
+ floatingStyles,
3298
+ floatingRef,
3299
+ size
3300
+ } = useContext12(SelectContext);
3170
3301
  const handleClickDeselect = () => {
3171
3302
  onChange?.(null);
3172
3303
  setIsOptionListOpen(false);
3173
3304
  };
3174
- useLayoutEffect2(() => {
3175
- if (maxHeight != null && selectedOption != null) {
3176
- const container = floatingRef?.current;
3177
- if (container != null) {
3178
- const element = container.querySelector(`[data-id="${selectedOption.id}"]`);
3179
- if (element != null) {
3180
- const htmlElement = element;
3181
- const elementTop = htmlElement.offsetTop;
3182
- const elementHeight = htmlElement.offsetHeight;
3183
- const containerHeight = container.clientHeight;
3184
- const scrollTop = elementTop - (containerHeight - elementHeight) / 2;
3185
- container.scrollTo({
3186
- top: Math.max(0, scrollTop)
3187
- });
3188
- }
3189
- }
3305
+ useLayoutEffect4(() => {
3306
+ if (selectedOption == null) {
3307
+ return;
3308
+ }
3309
+ const container = floatingRef?.current;
3310
+ if (container == null || container.scrollHeight <= container.clientHeight) {
3311
+ return;
3312
+ }
3313
+ const element = container.querySelector(`[data-id="${selectedOption.id}"]`);
3314
+ if (element == null) {
3315
+ return;
3190
3316
  }
3317
+ const htmlElement = element;
3318
+ const elementTop = htmlElement.offsetTop;
3319
+ const elementHeight = htmlElement.offsetHeight;
3320
+ const containerHeight = container.clientHeight;
3321
+ const scrollTop = elementTop - (containerHeight - elementHeight) / 2;
3322
+ container.scrollTo({
3323
+ top: Math.max(0, scrollTop)
3324
+ });
3191
3325
  }, [selectedOption, maxHeight, floatingRef]);
3192
3326
  const listClasses = clsx32("overflow-y-auto rounded bg-uiBackground01 py-2 shadow-floatingShadow", {
3193
3327
  "border-solid border border-uiBorder01": variant === "outline"
@@ -3202,7 +3336,7 @@ var SelectList = forwardRef10(({ children, maxHeight }, ref) => {
3202
3336
  );
3203
3337
  return /* @__PURE__ */ jsxs18("ul", { className: listClasses, style: { maxHeight, ...floatingStyles }, ref, children: [
3204
3338
  children,
3205
- placeholder != null && selectedOption !== null && /* @__PURE__ */ jsx42("li", { children: /* @__PURE__ */ jsx42("button", { className: deselectButtonClasses, type: "button", onClick: handleClickDeselect, children: "\u9078\u629E\u89E3\u9664" }) })
3339
+ isDeselectVisible && selectedOption !== null && /* @__PURE__ */ jsx42("li", { children: /* @__PURE__ */ jsx42("button", { className: deselectButtonClasses, type: "button", onClick: handleClickDeselect, children: "\u9078\u629E\u89E3\u9664" }) })
3206
3340
  ] });
3207
3341
  });
3208
3342
  SelectList.displayName = "SelectList";
@@ -3210,6 +3344,10 @@ SelectList.displayName = "SelectList";
3210
3344
  // src/select/select.tsx
3211
3345
  import { jsx as jsx43, jsxs as jsxs19 } from "react/jsx-runtime";
3212
3346
  var FLOATING_OFFSET2 = 4;
3347
+ var OPTION_HEIGHT_PX = { "x-small": 32, small: 32, medium: 32, large: 40 };
3348
+ var DEFAULT_VISIBLE_OPTION_COUNT = 8.5;
3349
+ var LIST_VERTICAL_CHROME_PX = 10;
3350
+ var getDefaultOptionListMaxHeight = (size) => OPTION_HEIGHT_PX[size] * DEFAULT_VISIBLE_OPTION_COUNT + LIST_VERTICAL_CHROME_PX;
3213
3351
  function Select({
3214
3352
  children,
3215
3353
  size = "medium",
@@ -3222,6 +3360,7 @@ function Select({
3222
3360
  isDisabled = false,
3223
3361
  isError = false,
3224
3362
  isOptionSelected = false,
3363
+ hasDeselectButton,
3225
3364
  onChange,
3226
3365
  optionListMaxHeight,
3227
3366
  matchListToTrigger = false,
@@ -3229,14 +3368,14 @@ function Select({
3229
3368
  "aria-describedby": ariaDescribedby
3230
3369
  }) {
3231
3370
  const [isOptionListOpen, setIsOptionListOpen] = useState10(false);
3232
- const targetRef = useRef11(null);
3371
+ const targetRef = useRef12(null);
3233
3372
  useOutsideClick(targetRef, () => setIsOptionListOpen(false));
3234
3373
  useDismissOnModalOpen(() => {
3235
3374
  if (isOptionListOpen) {
3236
3375
  setIsOptionListOpen(false);
3237
3376
  }
3238
3377
  });
3239
- const { refs, floatingStyles } = useFloating3({
3378
+ const { refs, floatingStyles } = useFloating4({
3240
3379
  open: isOptionListOpen,
3241
3380
  onOpenChange: setIsOptionListOpen,
3242
3381
  placement: "bottom-start",
@@ -3257,8 +3396,10 @@ function Select({
3257
3396
  whileElementsMounted: autoUpdate3
3258
3397
  });
3259
3398
  const handleClickToggle = () => setIsOptionListOpen((prev) => !prev);
3399
+ const resolvedOptionListMaxHeight = optionListMaxHeight ?? getDefaultOptionListMaxHeight(size);
3260
3400
  const buttonVariant = isError && !isDisabled ? `${variant}Error` : variant;
3261
3401
  const isSelected = isOptionSelected && !isDisabled && selectedOption !== null && !isError;
3402
+ const isDeselectVisible = hasDeselectButton ?? placeholder != null;
3262
3403
  const wrapperClasses = clsx33("relative flex shrink-0 items-center gap-1 rounded bg-uiBackground01", {
3263
3404
  "h-6": size === "x-small" || size === "small",
3264
3405
  "h-8": size === "medium",
@@ -3294,7 +3435,7 @@ function Select({
3294
3435
  value: {
3295
3436
  size,
3296
3437
  variant,
3297
- placeholder,
3438
+ isDeselectVisible,
3298
3439
  setIsOptionListOpen,
3299
3440
  selectedOption,
3300
3441
  onChange,
@@ -3327,7 +3468,7 @@ function Select({
3327
3468
  ]
3328
3469
  }
3329
3470
  ),
3330
- isOptionListOpen && !isDisabled && /* @__PURE__ */ jsx43(FloatingPortal3, { children: /* @__PURE__ */ jsx43("div", { className: "relative z-popover", children: /* @__PURE__ */ jsx43(SelectList, { ref: refs.setFloating, maxHeight: optionListMaxHeight, children }) }) })
3471
+ isOptionListOpen && !isDisabled && /* @__PURE__ */ jsx43(FloatingPortal3, { children: /* @__PURE__ */ jsx43("div", { className: "relative z-popover", children: /* @__PURE__ */ jsx43(SelectList, { ref: refs.setFloating, maxHeight: resolvedOptionListMaxHeight, children }) }) })
3331
3472
  ] })
3332
3473
  }
3333
3474
  );
@@ -3621,7 +3762,7 @@ function Radio({
3621
3762
  }
3622
3763
 
3623
3764
  // src/radio-card/radio-card.tsx
3624
- import { Children as Children5, cloneElement as cloneElement5, isValidElement as isValidElement5, useId as useId6, useMemo as useMemo6 } from "react";
3765
+ import { Children as Children5, cloneElement as cloneElement5, isValidElement as isValidElement5, useId as useId7, useMemo as useMemo6 } from "react";
3625
3766
 
3626
3767
  // src/radio-card/radio-card-context.ts
3627
3768
  import { createContext as createContext12, useContext as useContext15 } from "react";
@@ -3667,11 +3808,11 @@ RadioCardGroup.displayName = "RadioCard.Group";
3667
3808
  // src/radio-card/radio-card-item.tsx
3668
3809
  import { focusVisible as focusVisible13 } from "@zenkigen-inc/component-theme";
3669
3810
  import clsx35 from "clsx";
3670
- import { useId as useId5 } from "react";
3811
+ import { useId as useId6 } from "react";
3671
3812
  import { jsx as jsx53, jsxs as jsxs23 } from "react/jsx-runtime";
3672
3813
  function RadioCardItem({ value, label, description, isDisabled: itemDisabled = false, id }) {
3673
3814
  const context = useRadioCardContext("RadioCard.Item");
3674
- const autoId = useId5();
3815
+ const autoId = useId6();
3675
3816
  const inputId = id ?? autoId;
3676
3817
  const labelId = `${inputId}-label`;
3677
3818
  const descriptionId = `${inputId}-description`;
@@ -3765,8 +3906,8 @@ function RadioCardRoot({
3765
3906
  "aria-label": ariaLabel,
3766
3907
  "aria-labelledby": ariaLabelledby
3767
3908
  }) {
3768
- const autoName = useId6();
3769
- const baseId = useId6();
3909
+ const autoName = useId7();
3910
+ const baseId = useId7();
3770
3911
  const resolvedName = name ?? autoName;
3771
3912
  const errorIds = [];
3772
3913
  const enhancedChildren = Children5.map(children, (child) => {
@@ -3846,7 +3987,7 @@ var Search = forwardRef12(({ width = "100%", size = "medium", ...props }, ref) =
3846
3987
  Search.displayName = "Search";
3847
3988
 
3848
3989
  // src/segmented-control/segmented-control.tsx
3849
- import React4, { Children as Children6, useRef as useRef13 } from "react";
3990
+ import React4, { Children as Children6, useRef as useRef14 } from "react";
3850
3991
 
3851
3992
  // src/segmented-control/segmented-control-context.ts
3852
3993
  import { createContext as createContext13 } from "react";
@@ -3855,7 +3996,7 @@ var SegmentedControlContext = createContext13(null);
3855
3996
  // src/segmented-control/segmented-control-item.tsx
3856
3997
  import { focusVisible as focusVisible14 } from "@zenkigen-inc/component-theme";
3857
3998
  import { clsx as clsx37 } from "clsx";
3858
- import { useContext as useContext16, useEffect as useEffect11, useRef as useRef12 } from "react";
3999
+ import { useContext as useContext16, useEffect as useEffect11, useRef as useRef13 } from "react";
3859
4000
  import { jsx as jsx56, jsxs as jsxs25 } from "react/jsx-runtime";
3860
4001
  var SegmentedControlItem = ({
3861
4002
  label,
@@ -3866,8 +4007,8 @@ var SegmentedControlItem = ({
3866
4007
  ...rest
3867
4008
  }) => {
3868
4009
  const context = useContext16(SegmentedControlContext);
3869
- const buttonRef = useRef12(null);
3870
- const lastInteractionWasMouse = useRef12(false);
4010
+ const buttonRef = useRef13(null);
4011
+ const lastInteractionWasMouse = useRef13(false);
3871
4012
  if (context === null) {
3872
4013
  throw new Error("SegmentedControl.Item must be used within SegmentedControl");
3873
4014
  }
@@ -3960,7 +4101,7 @@ var SegmentedControl = ({
3960
4101
  "aria-label": ariaLabel,
3961
4102
  ...rest
3962
4103
  }) => {
3963
- const containerRef = useRef13(null);
4104
+ const containerRef = useRef14(null);
3964
4105
  const itemIds = Children6.toArray(children).filter((child) => {
3965
4106
  if (!React4.isValidElement(child) || typeof child.props !== "object" || child.props === null || !("value" in child.props)) {
3966
4107
  return false;
@@ -4014,7 +4155,7 @@ SegmentedControl.Item = SegmentedControlItem;
4014
4155
  // src/select-sort/select-sort.tsx
4015
4156
  import { buttonColors as buttonColors4, focusVisible as focusVisible17 } from "@zenkigen-inc/component-theme";
4016
4157
  import clsx40 from "clsx";
4017
- import { useCallback as useCallback13, useRef as useRef14, useState as useState13 } from "react";
4158
+ import { useCallback as useCallback13, useRef as useRef15, useState as useState13 } from "react";
4018
4159
 
4019
4160
  // src/select-sort/select-list.tsx
4020
4161
  import { focusVisible as focusVisible16 } from "@zenkigen-inc/component-theme";
@@ -4082,7 +4223,7 @@ function SelectSort({
4082
4223
  onClickDeselect
4083
4224
  }) {
4084
4225
  const [isOptionListOpen, setIsOptionListOpen] = useState13(false);
4085
- const targetRef = useRef14(null);
4226
+ const targetRef = useRef15(null);
4086
4227
  useOutsideClick(targetRef, () => setIsOptionListOpen(false));
4087
4228
  useDismissOnModalOpen(() => {
4088
4229
  if (isOptionListOpen) {
@@ -4227,7 +4368,7 @@ function SortButton({
4227
4368
 
4228
4369
  // src/steps/steps.tsx
4229
4370
  import { clsx as clsx44 } from "clsx";
4230
- import { Children as Children7, Fragment as Fragment7, isValidElement as isValidElement6, useId as useId7, useMemo as useMemo7, useState as useState14 } from "react";
4371
+ import { Children as Children7, Fragment as Fragment7, isValidElement as isValidElement6, useId as useId8, useMemo as useMemo7, useState as useState14 } from "react";
4231
4372
 
4232
4373
  // src/steps/steps-context.ts
4233
4374
  import { createContext as createContext14, useContext as useContext17 } from "react";
@@ -4412,7 +4553,7 @@ function StepsRoot({
4412
4553
  variant = "solid",
4413
4554
  "aria-label": ariaLabel
4414
4555
  }) {
4415
- const baseId = useId7();
4556
+ const baseId = useId8();
4416
4557
  const [internalStep] = useState14(defaultCurrentStep ?? 0);
4417
4558
  const resolvedCurrentStep = currentStep ?? internalStep;
4418
4559
  const itemElements = useMemo7(() => collectStepsItems(children), [children]);
@@ -4616,7 +4757,7 @@ function Tag({ id, children, color, variant = "normal", size = "medium", isEdita
4616
4757
 
4617
4758
  // src/text-area/text-area.tsx
4618
4759
  import { clsx as clsx53 } from "clsx";
4619
- import { Children as Children9, cloneElement as cloneElement6, forwardRef as forwardRef15, isValidElement as isValidElement7, useId as useId8, useMemo as useMemo8 } from "react";
4760
+ import { Children as Children9, cloneElement as cloneElement6, forwardRef as forwardRef15, isValidElement as isValidElement7, useId as useId9, useMemo as useMemo8 } from "react";
4620
4761
 
4621
4762
  // src/text-area/text-area-context.tsx
4622
4763
  import { createContext as createContext16, useContext as useContext19 } from "react";
@@ -4677,7 +4818,7 @@ function TextAreaInner({
4677
4818
  maxLength,
4678
4819
  ...props
4679
4820
  }, ref) {
4680
- const autoGeneratedId = useId8();
4821
+ const autoGeneratedId = useId9();
4681
4822
  const textAreaPropsForContext = useMemo8(
4682
4823
  () => ({
4683
4824
  size,
@@ -4840,7 +4981,7 @@ var TextArea = attachStatics2(TextAreaBase);
4840
4981
 
4841
4982
  // src/time-picker/time-picker.tsx
4842
4983
  import { clsx as clsx55 } from "clsx";
4843
- import { Children as Children10, cloneElement as cloneElement7, Fragment as Fragment8, isValidElement as isValidElement8, useId as useId9, useMemo as useMemo9 } from "react";
4984
+ import { Children as Children10, cloneElement as cloneElement7, Fragment as Fragment8, isValidElement as isValidElement8, useId as useId10, useMemo as useMemo9 } from "react";
4844
4985
 
4845
4986
  // src/time-picker/time-picker-context.tsx
4846
4987
  import { createContext as createContext17, useContext as useContext20 } from "react";
@@ -4980,7 +5121,7 @@ var TimePicker = ({
4980
5121
  isError = false,
4981
5122
  children
4982
5123
  }) => {
4983
- const autoGeneratedId = useId9();
5124
+ const autoGeneratedId = useId10();
4984
5125
  const hourOptions = useMemo9(() => generateHourOptions(minuteStep, minTime, maxTime), [minuteStep, minTime, maxTime]);
4985
5126
  const minuteOptions = useMemo9(
4986
5127
  () => generateMinuteOptions(minuteStep, value.hour, minTime, maxTime),
@@ -5071,40 +5212,88 @@ TimePicker.ErrorMessage = TimePickerErrorMessage;
5071
5212
  TimePicker.displayName = "TimePicker";
5072
5213
 
5073
5214
  // src/toast/toast.tsx
5074
- import clsx56 from "clsx";
5075
- import { useCallback as useCallback15, useEffect as useEffect12, useState as useState15 } from "react";
5215
+ import { clsx as clsx56 } from "clsx";
5216
+ import { useCallback as useCallback15, useEffect as useEffect12, useRef as useRef16, useState as useState15 } from "react";
5076
5217
  import { jsx as jsx77, jsxs as jsxs35 } from "react/jsx-runtime";
5077
5218
  var CLOSE_TIME_MSEC = 5e3;
5219
+ var REMOVAL_FALLBACK_MSEC = 1e3;
5078
5220
  function Toast({
5079
5221
  state = "information",
5080
5222
  width = "auto",
5223
+ // 既定 false は v1.22.0 までの互換維持のため据え置き(自動クローズしない既定では、安全弁により閉じるボタンが表示される)。
5224
+ // 「自動クローズ・閉じるボタンなし」の新しい既定は ToastProvider が isAutoClose を明示的に渡すことで実現している。
5081
5225
  isAutoClose = false,
5082
5226
  isAnimation = false,
5227
+ hasCloseButton = false,
5228
+ description,
5083
5229
  children,
5084
5230
  onClickClose
5085
5231
  }) {
5086
5232
  const [isRemoving, setIsRemoving] = useState15(false);
5233
+ const onClickCloseRef = useRef16(onClickClose);
5234
+ useEffect12(() => {
5235
+ onClickCloseRef.current = onClickClose;
5236
+ }, [onClickClose]);
5237
+ const hasNotifiedCloseRef = useRef16(false);
5238
+ const notifyClose = useCallback15(() => {
5239
+ if (hasNotifiedCloseRef.current) {
5240
+ return;
5241
+ }
5242
+ hasNotifiedCloseRef.current = true;
5243
+ onClickCloseRef.current();
5244
+ }, []);
5087
5245
  const handleClose = useCallback15(() => {
5088
5246
  if (isAnimation) {
5089
5247
  setIsRemoving(true);
5090
5248
  } else {
5091
- onClickClose();
5249
+ notifyClose();
5092
5250
  }
5093
- }, [isAnimation, onClickClose]);
5094
- const handleAnimationEnd = (e) => window.getComputedStyle(e.currentTarget).opacity === "0" && onClickClose();
5095
- const wrapperClasses = clsx56("pointer-events-auto flex items-start gap-1 bg-white p-4 shadow-floatingShadow", {
5096
- ["animate-toast-in"]: isAnimation && !isRemoving,
5097
- ["animate-toast-out opacity-0"]: isAnimation && isRemoving
5098
- });
5099
- const iconClasses = clsx56("flex items-center", {
5251
+ }, [isAnimation, notifyClose]);
5252
+ const handleAnimationEnd = (e) => {
5253
+ if (e.target !== e.currentTarget) {
5254
+ return;
5255
+ }
5256
+ if (window.getComputedStyle(e.currentTarget).opacity === "0") {
5257
+ notifyClose();
5258
+ }
5259
+ };
5260
+ useEffect12(() => {
5261
+ if (!isAutoClose) {
5262
+ return;
5263
+ }
5264
+ const timer = window.setTimeout(() => {
5265
+ if (isAnimation) {
5266
+ setIsRemoving(true);
5267
+ } else {
5268
+ notifyClose();
5269
+ }
5270
+ }, CLOSE_TIME_MSEC);
5271
+ return () => window.clearTimeout(timer);
5272
+ }, [isAutoClose, isAnimation, notifyClose]);
5273
+ useEffect12(() => {
5274
+ if (!isRemoving) {
5275
+ return;
5276
+ }
5277
+ const fallbackTimer = window.setTimeout(notifyClose, REMOVAL_FALLBACK_MSEC);
5278
+ return () => window.clearTimeout(fallbackTimer);
5279
+ }, [isRemoving, notifyClose]);
5280
+ const isCloseButtonShown = hasCloseButton || !isAutoClose;
5281
+ const wrapperClasses = clsx56(
5282
+ "pointer-events-auto flex items-center gap-3 rounded border border-solid border-uiBorder01 bg-uiBackground01 p-4 shadow-floatingShadow",
5283
+ {
5284
+ ["animate-toast-in"]: isAnimation && !isRemoving,
5285
+ ["animate-toast-out opacity-0"]: isAnimation && isRemoving
5286
+ }
5287
+ );
5288
+ const iconClasses = clsx56("flex shrink-0 items-center", {
5100
5289
  "fill-supportSuccess": state === "success",
5101
5290
  "fill-supportError": state === "error",
5102
5291
  "fill-supportWarning": state === "warning",
5103
5292
  "fill-supportInfo": state === "information"
5104
5293
  });
5105
- const textClasses = clsx56("typography-body13regular flex-1 pt-[3px]", {
5294
+ const titleClasses = clsx56("typography-body13regular break-words", {
5106
5295
  "text-supportError": state === "error",
5107
- "text-text01": state === "success" || state === "warning" || state === "information"
5296
+ "text-text01": state !== "error"
5108
5297
  });
5109
5298
  const iconName = {
5110
5299
  success: "success-filled",
@@ -5112,32 +5301,45 @@ function Toast({
5112
5301
  warning: "warning",
5113
5302
  information: "information-filled"
5114
5303
  };
5115
- useEffect12(() => {
5116
- const timer = window.setTimeout(() => {
5117
- if (isAutoClose) {
5118
- setIsRemoving(true);
5119
- }
5120
- }, CLOSE_TIME_MSEC);
5121
- return () => window.clearTimeout(timer);
5122
- }, [isAutoClose]);
5123
5304
  return /* @__PURE__ */ jsxs35("div", { className: wrapperClasses, style: { width }, onAnimationEnd: handleAnimationEnd, children: [
5124
- /* @__PURE__ */ jsx77("div", { className: iconClasses, children: /* @__PURE__ */ jsx77(Icon, { name: iconName[state] }) }),
5125
- /* @__PURE__ */ jsx77("p", { className: textClasses, children }),
5126
- /* @__PURE__ */ jsx77(IconButton, { icon: "close", size: "medium", variant: "text", onClick: handleClose, isNoPadding: true })
5305
+ /* @__PURE__ */ jsxs35("div", { className: "flex min-w-0 flex-1 items-start gap-1", children: [
5306
+ /* @__PURE__ */ jsx77("div", { className: iconClasses, children: /* @__PURE__ */ jsx77(Icon, { name: iconName[state] }) }),
5307
+ /* @__PURE__ */ jsxs35("div", { className: "flex min-w-0 flex-1 flex-col gap-2 pt-[3px]", children: [
5308
+ /* @__PURE__ */ jsx77("p", { className: titleClasses, children }),
5309
+ description != null && description !== "" && /* @__PURE__ */ jsx77("p", { className: "typography-label12regular break-words text-text01", children: description })
5310
+ ] })
5311
+ ] }),
5312
+ isCloseButtonShown && /* @__PURE__ */ jsx77("div", { className: "flex shrink-0 items-center", children: /* @__PURE__ */ jsx77(IconButton, { icon: "close", size: "medium", variant: "text", isNoPadding: true, "aria-label": "\u9589\u3058\u308B", onClick: handleClose }) })
5127
5313
  ] });
5128
5314
  }
5129
5315
 
5130
5316
  // src/toast/toast-provider.tsx
5131
- import { createContext as createContext18, useCallback as useCallback16, useContext as useContext21, useEffect as useEffect13, useState as useState16 } from "react";
5317
+ import { createContext as createContext18, useCallback as useCallback16, useContext as useContext21, useEffect as useEffect13, useRef as useRef17, useState as useState16 } from "react";
5132
5318
  import { createPortal as createPortal3 } from "react-dom";
5133
5319
  import { jsx as jsx78, jsxs as jsxs36 } from "react/jsx-runtime";
5134
5320
  var ToastContext = createContext18({});
5135
- var ToastProvider = ({ children }) => {
5321
+ var ToastProvider = ({ children, hasCloseButton = false }) => {
5136
5322
  const [isClientRender, setIsClientRender] = useState16(false);
5137
5323
  const [toasts, setToasts] = useState16([]);
5138
- const addToast = useCallback16(({ message, state }) => {
5139
- setToasts((prev) => [...prev, { id: Math.trunc(Math.random() * 1e5), message, state }]);
5140
- }, []);
5324
+ const nextIdRef = useRef17(0);
5325
+ const addToast = useCallback16(
5326
+ (args) => {
5327
+ nextIdRef.current += 1;
5328
+ const id = nextIdRef.current;
5329
+ setToasts((prev) => [
5330
+ ...prev,
5331
+ {
5332
+ id,
5333
+ message: args.message,
5334
+ state: args.state,
5335
+ description: args.description,
5336
+ hasCloseButton: args.hasCloseButton ?? hasCloseButton,
5337
+ isAutoClose: args.isAutoClose ?? true
5338
+ }
5339
+ ]);
5340
+ },
5341
+ [hasCloseButton]
5342
+ );
5141
5343
  const removeToast = useCallback16((id) => {
5142
5344
  setToasts((prev) => prev.filter((snackbar) => snackbar.id !== id));
5143
5345
  }, []);
@@ -5147,7 +5349,28 @@ var ToastProvider = ({ children }) => {
5147
5349
  return /* @__PURE__ */ jsxs36(ToastContext.Provider, { value: { addToast, removeToast }, children: [
5148
5350
  children,
5149
5351
  isClientRender && createPortal3(
5150
- /* @__PURE__ */ jsx78("div", { className: "pointer-events-none fixed bottom-0 left-0 z-toast mb-4 ml-4 flex w-full flex-col-reverse gap-[16px]", children: toasts.map(({ id, message, state }) => /* @__PURE__ */ jsx78(Toast, { state, isAutoClose: true, isAnimation: true, onClickClose: () => removeToast(id), width: 475, children: message }, id)) }),
5352
+ /* @__PURE__ */ jsx78(
5353
+ "div",
5354
+ {
5355
+ ...{ [TOP_LAYER_ATTRIBUTE]: "" },
5356
+ role: "region",
5357
+ "aria-label": "\u901A\u77E5",
5358
+ className: "pointer-events-none fixed bottom-0 left-0 z-toast mb-4 ml-4 flex w-full flex-col-reverse gap-4",
5359
+ children: toasts.map((toast) => /* @__PURE__ */ jsx78("div", { role: toast.state === "error" ? "alert" : "status", children: /* @__PURE__ */ jsx78(
5360
+ Toast,
5361
+ {
5362
+ state: toast.state,
5363
+ description: toast.description,
5364
+ hasCloseButton: toast.hasCloseButton,
5365
+ isAutoClose: toast.isAutoClose,
5366
+ isAnimation: true,
5367
+ width: 475,
5368
+ onClickClose: () => removeToast(toast.id),
5369
+ children: toast.message
5370
+ }
5371
+ ) }, toast.id))
5372
+ }
5373
+ ),
5151
5374
  document.body
5152
5375
  )
5153
5376
  ] });
@@ -5213,7 +5436,7 @@ function Toggle({
5213
5436
  }
5214
5437
 
5215
5438
  // src/tooltip/tooltip.tsx
5216
- import { useCallback as useCallback18, useEffect as useEffect14, useRef as useRef15, useState as useState17 } from "react";
5439
+ import { useCallback as useCallback18, useEffect as useEffect14, useRef as useRef18, useState as useState17 } from "react";
5217
5440
  import { createPortal as createPortal4 } from "react-dom";
5218
5441
 
5219
5442
  // src/tooltip/tooltip-content.tsx
@@ -5384,7 +5607,7 @@ function Tooltip({
5384
5607
  translateX: "0",
5385
5608
  translateY: "0"
5386
5609
  });
5387
- const targetRef = useRef15(null);
5610
+ const targetRef = useRef18(null);
5388
5611
  const handleMouseOverWrapper = useCallback18(() => {
5389
5612
  if (isDisabledHover) {
5390
5613
  return;