@zenkigen-inc/component-ui 1.14.4 → 1.15.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/README.md +0 -5
- package/dist/hooks/use-outside-click.d.ts +1 -1
- package/dist/index.esm.js +128 -29
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +137 -32
- package/dist/index.js.map +1 -1
- package/dist/modal/body-scroll-lock.d.ts +27 -0
- package/dist/modal/modal.d.ts +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ function _objectWithoutPropertiesLoose(r, e) {
|
|
|
18
18
|
if (null == r) return {};
|
|
19
19
|
var t = {};
|
|
20
20
|
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
21
|
-
if (e.
|
|
21
|
+
if (-1 !== e.indexOf(n)) continue;
|
|
22
22
|
t[n] = r[n];
|
|
23
23
|
}
|
|
24
24
|
return t;
|
|
@@ -612,6 +612,109 @@ function Loading({
|
|
|
612
612
|
});
|
|
613
613
|
}
|
|
614
614
|
|
|
615
|
+
/**
|
|
616
|
+
* モーダル表示時にバックグラウンドのスクロールを防止するコンポーネント。
|
|
617
|
+
* コンポーネントがマウントされている間、position: fixedアプローチを使用して
|
|
618
|
+
* body要素にスクロールロックを適用します。
|
|
619
|
+
* 縦横両方のスクロール位置を保存し、コンポーネントのアンマウント時に復元します。
|
|
620
|
+
* スクロールバーの有無を検出し、その幅を考慮してレイアウトシフトを防止します。
|
|
621
|
+
* position、top、left、width、overflow、padding-rightを変更し、
|
|
622
|
+
* 最小限の変更でスクロールを防止します。
|
|
623
|
+
* グローバルCSSに依存せず、すべてインラインスタイルで実装されています。
|
|
624
|
+
* このコンポーネントは実際のDOM要素をレンダリングせず、効果のみを適用します。
|
|
625
|
+
*
|
|
626
|
+
* @example
|
|
627
|
+
* // モーダルコンポーネント内で使用する例
|
|
628
|
+
* const Modal = ({ isOpen, children }) => {
|
|
629
|
+
* return (
|
|
630
|
+
* <>
|
|
631
|
+
* {isOpen && <BodyScrollLock />}
|
|
632
|
+
* {isOpen && (
|
|
633
|
+
* <div className="modal">
|
|
634
|
+
* {children}
|
|
635
|
+
* </div>
|
|
636
|
+
* )}
|
|
637
|
+
* </>
|
|
638
|
+
* );
|
|
639
|
+
* };
|
|
640
|
+
*/
|
|
641
|
+
const BodyScrollLock = () => {
|
|
642
|
+
useLayoutEffect(() => {
|
|
643
|
+
// 現在の縦横スクロール位置を記録
|
|
644
|
+
const {
|
|
645
|
+
scrollX,
|
|
646
|
+
scrollY
|
|
647
|
+
} = window;
|
|
648
|
+
const {
|
|
649
|
+
body
|
|
650
|
+
} = document;
|
|
651
|
+
// スクロールバーの有無と幅を検出
|
|
652
|
+
const hasVerticalScrollbar = document.documentElement.scrollHeight > document.documentElement.clientHeight;
|
|
653
|
+
const scrollbarWidth = hasVerticalScrollbar ? window.innerWidth - document.documentElement.clientWidth : 0;
|
|
654
|
+
// 元のインラインスタイルの値を保存
|
|
655
|
+
const originalInlineStyles = {
|
|
656
|
+
position: body.style.position,
|
|
657
|
+
top: body.style.top,
|
|
658
|
+
left: body.style.left,
|
|
659
|
+
width: body.style.width,
|
|
660
|
+
overflow: body.style.overflow,
|
|
661
|
+
paddingRight: body.style.paddingRight
|
|
662
|
+
};
|
|
663
|
+
// スクロールロックスタイルを適用
|
|
664
|
+
body.style.position = 'fixed';
|
|
665
|
+
body.style.top = `-${scrollY}px`;
|
|
666
|
+
body.style.left = `-${scrollX}px`;
|
|
667
|
+
body.style.width = '100%';
|
|
668
|
+
body.style.overflow = 'hidden';
|
|
669
|
+
// スクロールバーがある場合、その幅分だけpadding-rightを調整
|
|
670
|
+
if (hasVerticalScrollbar && scrollbarWidth > 0) {
|
|
671
|
+
// 現在のpadding-rightの値を取得
|
|
672
|
+
const {
|
|
673
|
+
paddingRight
|
|
674
|
+
} = window.getComputedStyle(body);
|
|
675
|
+
const paddingRightValue = paddingRight !== '' ? parseInt(paddingRight, 10) : 0;
|
|
676
|
+
// スクロールバーの幅を加算
|
|
677
|
+
body.style.paddingRight = `${paddingRightValue + scrollbarWidth}px`;
|
|
678
|
+
}
|
|
679
|
+
// クリーンアップ関数
|
|
680
|
+
return () => {
|
|
681
|
+
// 元のスタイル値を取得
|
|
682
|
+
const {
|
|
683
|
+
position,
|
|
684
|
+
top,
|
|
685
|
+
left,
|
|
686
|
+
width,
|
|
687
|
+
overflow,
|
|
688
|
+
paddingRight
|
|
689
|
+
} = originalInlineStyles;
|
|
690
|
+
// プロパティごとに元の値を復元
|
|
691
|
+
restoreProperty(body, 'position', position);
|
|
692
|
+
restoreProperty(body, 'top', top);
|
|
693
|
+
restoreProperty(body, 'left', left);
|
|
694
|
+
restoreProperty(body, 'width', width);
|
|
695
|
+
restoreProperty(body, 'overflow', overflow);
|
|
696
|
+
restoreProperty(body, 'padding-right', paddingRight);
|
|
697
|
+
// スクロール位置を復元
|
|
698
|
+
window.scrollTo(scrollX, scrollY);
|
|
699
|
+
};
|
|
700
|
+
}, []); // 空の依存配列を指定して初回のみ実行
|
|
701
|
+
// DOM要素をレンダリングせず、nullを返す
|
|
702
|
+
return null;
|
|
703
|
+
};
|
|
704
|
+
/**
|
|
705
|
+
* 元のスタイル値を復元するヘルパー関数
|
|
706
|
+
* @param element スタイルを復元する要素
|
|
707
|
+
* @param property 復元するCSSプロパティ名
|
|
708
|
+
* @param value 復元する値
|
|
709
|
+
*/
|
|
710
|
+
function restoreProperty(element, property, value) {
|
|
711
|
+
if (value !== '') {
|
|
712
|
+
element.style.setProperty(property, value);
|
|
713
|
+
} else {
|
|
714
|
+
element.style.removeProperty(property);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
615
718
|
function ModalBody({
|
|
616
719
|
children
|
|
617
720
|
}) {
|
|
@@ -679,22 +782,24 @@ function Modal({
|
|
|
679
782
|
useEffect(() => {
|
|
680
783
|
setIsMounted(true);
|
|
681
784
|
}, []);
|
|
682
|
-
return isMounted && isOpen ? /*#__PURE__*/
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
className: "fixed left-0 top-0 z-overlay flex size-full items-center justify-center bg-backgroundOverlayBlack py-4",
|
|
785
|
+
return isMounted && isOpen ? /*#__PURE__*/jsxs(Fragment, {
|
|
786
|
+
children: [/*#__PURE__*/jsx(BodyScrollLock, {}), /*#__PURE__*/createPortal(/*#__PURE__*/jsx(ModalContext.Provider, {
|
|
787
|
+
value: {
|
|
788
|
+
onClose
|
|
789
|
+
},
|
|
688
790
|
children: /*#__PURE__*/jsx("div", {
|
|
689
|
-
className: "
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
791
|
+
className: "fixed left-0 top-0 z-overlay flex size-full items-center justify-center bg-backgroundOverlayBlack py-4",
|
|
792
|
+
children: /*#__PURE__*/jsx("div", {
|
|
793
|
+
className: "grid max-h-full min-h-[120px] grid-rows-[max-content_1fr_max-content] flex-col rounded-lg bg-uiBackground01 shadow-modalShadow",
|
|
794
|
+
style: {
|
|
795
|
+
width: renderWidth,
|
|
796
|
+
height: renderHeight
|
|
797
|
+
},
|
|
798
|
+
children: children
|
|
799
|
+
})
|
|
695
800
|
})
|
|
696
|
-
})
|
|
697
|
-
})
|
|
801
|
+
}), (portalTargetRef == null ? void 0 : portalTargetRef.current) != null ? portalTargetRef.current : document.body)]
|
|
802
|
+
}) : null;
|
|
698
803
|
}
|
|
699
804
|
Modal.Body = ModalBody;
|
|
700
805
|
Modal.Header = ModalHeader;
|
|
@@ -1552,19 +1657,23 @@ const TextInput = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
1552
1657
|
onClickClearButton
|
|
1553
1658
|
} = _ref,
|
|
1554
1659
|
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
1660
|
+
const isShowClearButton = !!onClickClearButton && props.value.length !== 0 && !disabled;
|
|
1555
1661
|
const inputWrapClasses = clsx('relative flex items-center gap-2 overflow-hidden rounded border', {
|
|
1556
1662
|
'border-uiBorder02': !isError && !disabled,
|
|
1557
1663
|
'border-supportError': isError && !disabled,
|
|
1558
1664
|
'hover:border-hoverInput': !disabled && !isError,
|
|
1559
1665
|
'hover:focus-within:border-activeInput': !isError,
|
|
1560
1666
|
'focus-within:border-activeInput': !isError,
|
|
1561
|
-
'bg-disabled02 border-disabled01': disabled
|
|
1667
|
+
'bg-disabled02 border-disabled01': disabled,
|
|
1668
|
+
'pr-2': size === 'medium' && isShowClearButton,
|
|
1669
|
+
'pr-3': size === 'large' && isShowClearButton
|
|
1562
1670
|
});
|
|
1563
|
-
const inputClasses = clsx('flex-1
|
|
1564
|
-
['typography-label14regular min-h-8']: size === 'medium',
|
|
1565
|
-
['typography-label16regular min-h-10']: size === 'large',
|
|
1671
|
+
const inputClasses = clsx('flex-1 outline-0 placeholder:text-textPlaceholder disabled:text-textPlaceholder', {
|
|
1672
|
+
['typography-label14regular min-h-8 px-2']: size === 'medium',
|
|
1673
|
+
['typography-label16regular min-h-10 px-3']: size === 'large',
|
|
1566
1674
|
'text-text01': !isError,
|
|
1567
|
-
'text-supportError': isError
|
|
1675
|
+
'text-supportError': isError,
|
|
1676
|
+
'pr-0': isShowClearButton
|
|
1568
1677
|
});
|
|
1569
1678
|
return /*#__PURE__*/jsxs("div", {
|
|
1570
1679
|
className: inputWrapClasses,
|
|
@@ -1574,15 +1683,11 @@ const TextInput = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
1574
1683
|
className: inputClasses,
|
|
1575
1684
|
disabled: disabled,
|
|
1576
1685
|
onChange: props.onChange
|
|
1577
|
-
}, props)),
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
size: "small",
|
|
1583
|
-
isNoPadding: true,
|
|
1584
|
-
onClick: onClickClearButton
|
|
1585
|
-
})
|
|
1686
|
+
}, props)), isShowClearButton && /*#__PURE__*/jsx(IconButton, {
|
|
1687
|
+
variant: "text",
|
|
1688
|
+
icon: "close",
|
|
1689
|
+
size: "small",
|
|
1690
|
+
onClick: onClickClearButton
|
|
1586
1691
|
})]
|
|
1587
1692
|
});
|
|
1588
1693
|
});
|
|
@@ -1685,7 +1790,7 @@ const ToastProvider = ({
|
|
|
1685
1790
|
addToast,
|
|
1686
1791
|
removeToast
|
|
1687
1792
|
},
|
|
1688
|
-
children: [children, isClientRender && /*#__PURE__*/createPortal(
|
|
1793
|
+
children: [children, isClientRender && /*#__PURE__*/createPortal(/*#__PURE__*/jsx("div", {
|
|
1689
1794
|
className: "pointer-events-none fixed bottom-0 left-0 z-toast mb-4 ml-4 flex w-full flex-col-reverse gap-[16px]",
|
|
1690
1795
|
children: toasts.map(({
|
|
1691
1796
|
id,
|
|
@@ -1719,7 +1824,7 @@ function Toggle({
|
|
|
1719
1824
|
'bg-disabledOn': isDisabled && isChecked,
|
|
1720
1825
|
'bg-disabled01': isDisabled && !isChecked,
|
|
1721
1826
|
'bg-interactive01 peer-hover:bg-hover01': !isDisabled && isChecked,
|
|
1722
|
-
'bg-interactive02 peer-hover:bg-
|
|
1827
|
+
'bg-interactive02 peer-hover:bg-hoverGray': !isDisabled && !isChecked,
|
|
1723
1828
|
'w-8 h-4 px-[3px]': size === 'small',
|
|
1724
1829
|
'w-12 h-6 px-1': size === 'medium' || size === 'large'
|
|
1725
1830
|
});
|
|
@@ -1961,7 +2066,7 @@ function Tooltip({
|
|
|
1961
2066
|
verticalPosition: verticalPosition,
|
|
1962
2067
|
horizontalAlign: horizontalAlign,
|
|
1963
2068
|
tooltipPosition: tooltipPosition
|
|
1964
|
-
}) : (
|
|
2069
|
+
}) : (/*#__PURE__*/createPortal(/*#__PURE__*/jsx(TooltipContent, {
|
|
1965
2070
|
isPortal: true,
|
|
1966
2071
|
content: content,
|
|
1967
2072
|
size: size,
|