smarthr-ui 99.3.0 → 99.3.2
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/lib/_virtual/index.cjs +2 -2
- package/lib/_virtual/index.js +2 -2
- package/lib/_virtual/index2.cjs +2 -2
- package/lib/_virtual/index2.js +2 -2
- package/lib/components/Checkbox/Checkbox.cjs +1 -1
- package/lib/components/Checkbox/Checkbox.cjs.map +1 -1
- package/lib/components/Checkbox/Checkbox.js +1 -1
- package/lib/components/Checkbox/Checkbox.js.map +1 -1
- package/lib/components/Combobox/ItemButton.cjs +11 -2
- package/lib/components/Combobox/ItemButton.cjs.map +1 -1
- package/lib/components/Combobox/ItemButton.js +11 -2
- package/lib/components/Combobox/ItemButton.js.map +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs +2 -2
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs.map +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.js +2 -2
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.js.map +1 -1
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs +2 -2
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs.map +1 -1
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.js +2 -2
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.js.map +1 -1
- package/lib/components/DatePicker/DatePicker.cjs +2 -2
- package/lib/components/DatePicker/DatePicker.cjs.map +1 -1
- package/lib/components/DatePicker/DatePicker.js +2 -2
- package/lib/components/DatePicker/DatePicker.js.map +1 -1
- package/lib/components/DatePicker/Portal.cjs +1 -1
- package/lib/components/DatePicker/Portal.cjs.map +1 -1
- package/lib/components/DatePicker/Portal.js +1 -1
- package/lib/components/DatePicker/Portal.js.map +1 -1
- package/lib/components/Dialog/FocusTrap.cjs +8 -8
- package/lib/components/Dialog/FocusTrap.cjs.map +1 -1
- package/lib/components/Dialog/FocusTrap.js +9 -9
- package/lib/components/Dialog/FocusTrap.js.map +1 -1
- package/lib/components/Dialog/ModelessDialog/ModelessDialog.cjs +2 -1
- package/lib/components/Dialog/ModelessDialog/ModelessDialog.cjs.map +1 -1
- package/lib/components/Dialog/ModelessDialog/ModelessDialog.js +2 -1
- package/lib/components/Dialog/ModelessDialog/ModelessDialog.js.map +1 -1
- package/lib/components/DropZone/DropZone.cjs +1 -1
- package/lib/components/DropZone/DropZone.cjs.map +1 -1
- package/lib/components/DropZone/DropZone.js +1 -1
- package/lib/components/DropZone/DropZone.js.map +1 -1
- package/lib/components/Heading/PageHeading/PageHeading.cjs +1 -1
- package/lib/components/Heading/PageHeading/PageHeading.cjs.map +1 -1
- package/lib/components/Heading/PageHeading/PageHeading.js +1 -1
- package/lib/components/Heading/PageHeading/PageHeading.js.map +1 -1
- package/lib/components/Input/CurrencyInput/CurrencyInput.cjs +3 -3
- package/lib/components/Input/CurrencyInput/CurrencyInput.cjs.map +1 -1
- package/lib/components/Input/CurrencyInput/CurrencyInput.js +3 -3
- package/lib/components/Input/CurrencyInput/CurrencyInput.js.map +1 -1
- package/lib/components/Input/Input.cjs +15 -17
- package/lib/components/Input/Input.cjs.map +1 -1
- package/lib/components/Input/Input.js +15 -17
- package/lib/components/Input/Input.js.map +1 -1
- package/lib/components/InputFile/InputFileMultiplyAppendable.cjs +8 -7
- package/lib/components/InputFile/InputFileMultiplyAppendable.cjs.map +1 -1
- package/lib/components/InputFile/InputFileMultiplyAppendable.js +8 -7
- package/lib/components/InputFile/InputFileMultiplyAppendable.js.map +1 -1
- package/lib/components/InputFile/InputFileNative.cjs +6 -5
- package/lib/components/InputFile/InputFileNative.cjs.map +1 -1
- package/lib/components/InputFile/InputFileNative.js +6 -5
- package/lib/components/InputFile/InputFileNative.js.map +1 -1
- package/lib/components/Layout/Container/Container.cjs.map +1 -1
- package/lib/components/Layout/Container/Container.js.map +1 -1
- package/lib/components/Pagination/Pagination.cjs +3 -2
- package/lib/components/Pagination/Pagination.cjs.map +1 -1
- package/lib/components/Pagination/Pagination.js +2 -1
- package/lib/components/Pagination/Pagination.js.map +1 -1
- package/lib/components/Panel/Groupbox/Groupbox.cjs +1 -0
- package/lib/components/Panel/Groupbox/Groupbox.cjs.map +1 -1
- package/lib/components/Panel/Groupbox/Groupbox.js +1 -0
- package/lib/components/Panel/Groupbox/Groupbox.js.map +1 -1
- package/lib/components/Scroller/Scroller.cjs +3 -1
- package/lib/components/Scroller/Scroller.cjs.map +1 -1
- package/lib/components/Scroller/Scroller.js +3 -1
- package/lib/components/Scroller/Scroller.js.map +1 -1
- package/lib/components/Select/Select.cjs +12 -14
- package/lib/components/Select/Select.cjs.map +1 -1
- package/lib/components/Select/Select.js +12 -14
- package/lib/components/Select/Select.js.map +1 -1
- package/lib/components/Table/TableReel.cjs +67 -3
- package/lib/components/Table/TableReel.cjs.map +1 -1
- package/lib/components/Table/TableReel.js +68 -4
- package/lib/components/Table/TableReel.js.map +1 -1
- package/lib/components/Table/TableScroller.cjs +13 -15
- package/lib/components/Table/TableScroller.cjs.map +1 -1
- package/lib/components/Table/TableScroller.js +14 -16
- package/lib/components/Table/TableScroller.js.map +1 -1
- package/lib/components/Textarea/Textarea.cjs +18 -12
- package/lib/components/Textarea/Textarea.cjs.map +1 -1
- package/lib/components/Textarea/Textarea.js +19 -13
- package/lib/components/Textarea/Textarea.js.map +1 -1
- package/lib/components/Tooltip/TooltipPortal.cjs +1 -0
- package/lib/components/Tooltip/TooltipPortal.cjs.map +1 -1
- package/lib/components/Tooltip/TooltipPortal.js +1 -0
- package/lib/components/Tooltip/TooltipPortal.js.map +1 -1
- package/lib/hooks/useClick.cjs +7 -4
- package/lib/hooks/useClick.cjs.map +1 -1
- package/lib/hooks/useClick.js +7 -4
- package/lib/hooks/useClick.js.map +1 -1
- package/lib/hooks/useOuterClick.cjs +5 -6
- package/lib/hooks/useOuterClick.cjs.map +1 -1
- package/lib/hooks/useOuterClick.js +6 -7
- package/lib/hooks/useOuterClick.js.map +1 -1
- package/lib/hooks/usePortal.cjs +24 -17
- package/lib/hooks/usePortal.cjs.map +1 -1
- package/lib/hooks/usePortal.d.ts +1 -1
- package/lib/hooks/usePortal.js +25 -18
- package/lib/hooks/usePortal.js.map +1 -1
- package/lib/hooks/useResponseStatus.cjs +20 -23
- package/lib/hooks/useResponseStatus.cjs.map +1 -1
- package/lib/hooks/useResponseStatus.js +20 -23
- package/lib/hooks/useResponseStatus.js.map +1 -1
- package/lib/intl/locales/en_us.json.cjs +1 -0
- package/lib/intl/locales/en_us.json.cjs.map +1 -1
- package/lib/intl/locales/en_us.json.js +1 -0
- package/lib/intl/locales/en_us.json.js.map +1 -1
- package/lib/intl/locales/id_id.json.cjs +0 -8
- package/lib/intl/locales/id_id.json.cjs.map +1 -1
- package/lib/intl/locales/id_id.json.js +0 -8
- package/lib/intl/locales/id_id.json.js.map +1 -1
- package/lib/intl/locales/index.d.ts +6 -16
- package/lib/intl/locales/ja_easy.json.cjs +1 -0
- package/lib/intl/locales/ja_easy.json.cjs.map +1 -1
- package/lib/intl/locales/ja_easy.json.js +1 -0
- package/lib/intl/locales/ja_easy.json.js.map +1 -1
- package/lib/intl/locales/ko_kr.json.cjs +1 -0
- package/lib/intl/locales/ko_kr.json.cjs.map +1 -1
- package/lib/intl/locales/ko_kr.json.js +1 -0
- package/lib/intl/locales/ko_kr.json.js.map +1 -1
- package/lib/intl/locales/pt_br.json.cjs +0 -8
- package/lib/intl/locales/pt_br.json.cjs.map +1 -1
- package/lib/intl/locales/pt_br.json.js +0 -8
- package/lib/intl/locales/pt_br.json.js.map +1 -1
- package/lib/intl/locales/vi_vn.json.cjs +1 -0
- package/lib/intl/locales/vi_vn.json.cjs.map +1 -1
- package/lib/intl/locales/vi_vn.json.js +1 -0
- package/lib/intl/locales/vi_vn.json.js.map +1 -1
- package/lib/intl/locales/zh_hans_cn.json.cjs +1 -0
- package/lib/intl/locales/zh_hans_cn.json.cjs.map +1 -1
- package/lib/intl/locales/zh_hans_cn.json.js +1 -0
- package/lib/intl/locales/zh_hans_cn.json.js.map +1 -1
- package/lib/intl/locales/zh_hant_tw.json.cjs +1 -0
- package/lib/intl/locales/zh_hant_tw.json.cjs.map +1 -1
- package/lib/intl/locales/zh_hant_tw.json.js +1 -0
- package/lib/intl/locales/zh_hant_tw.json.js.map +1 -1
- package/lib/intl/useDateFormat.cjs +1 -2
- package/lib/intl/useDateFormat.cjs.map +1 -1
- package/lib/intl/useDateFormat.js +1 -2
- package/lib/intl/useDateFormat.js.map +1 -1
- package/lib/intl/useIntl.cjs +2 -4
- package/lib/intl/useIntl.cjs.map +1 -1
- package/lib/intl/useIntl.js +2 -4
- package/lib/intl/useIntl.js.map +1 -1
- package/lib/libs/debounce.cjs +10 -2
- package/lib/libs/debounce.cjs.map +1 -1
- package/lib/libs/debounce.d.ts +4 -2
- package/lib/libs/debounce.js +10 -2
- package/lib/libs/debounce.js.map +1 -1
- package/lib/libs/lodash.cjs +3 -4
- package/lib/libs/lodash.cjs.map +1 -1
- package/lib/libs/lodash.d.ts +2 -11
- package/lib/libs/lodash.js +2 -7
- package/lib/libs/lodash.js.map +1 -1
- package/lib/libs/map.cjs +1 -5
- package/lib/libs/map.cjs.map +1 -1
- package/lib/libs/map.js +1 -5
- package/lib/libs/map.js.map +1 -1
- package/lib/themes/createBackgroundColor.cjs +3 -2
- package/lib/themes/createBackgroundColor.cjs.map +1 -1
- package/lib/themes/createBackgroundColor.js +2 -1
- package/lib/themes/createBackgroundColor.js.map +1 -1
- package/lib/themes/createBorder.cjs +3 -2
- package/lib/themes/createBorder.cjs.map +1 -1
- package/lib/themes/createBorder.js +2 -1
- package/lib/themes/createBorder.js.map +1 -1
- package/lib/themes/createBreakpoint.cjs +3 -2
- package/lib/themes/createBreakpoint.cjs.map +1 -1
- package/lib/themes/createBreakpoint.js +2 -1
- package/lib/themes/createBreakpoint.js.map +1 -1
- package/lib/themes/createColor.cjs +3 -2
- package/lib/themes/createColor.cjs.map +1 -1
- package/lib/themes/createColor.js +2 -1
- package/lib/themes/createColor.js.map +1 -1
- package/lib/themes/createFontSize.cjs +3 -2
- package/lib/themes/createFontSize.cjs.map +1 -1
- package/lib/themes/createFontSize.js +2 -1
- package/lib/themes/createFontSize.js.map +1 -1
- package/lib/themes/createInteraction.cjs +3 -2
- package/lib/themes/createInteraction.cjs.map +1 -1
- package/lib/themes/createInteraction.js +2 -1
- package/lib/themes/createInteraction.js.map +1 -1
- package/lib/themes/createLeading.cjs +3 -2
- package/lib/themes/createLeading.cjs.map +1 -1
- package/lib/themes/createLeading.js +2 -1
- package/lib/themes/createLeading.js.map +1 -1
- package/lib/themes/createRadius.cjs +3 -2
- package/lib/themes/createRadius.cjs.map +1 -1
- package/lib/themes/createRadius.js +2 -1
- package/lib/themes/createRadius.js.map +1 -1
- package/lib/themes/createShadow/createShadow.cjs +3 -2
- package/lib/themes/createShadow/createShadow.cjs.map +1 -1
- package/lib/themes/createShadow/createShadow.js +2 -1
- package/lib/themes/createShadow/createShadow.js.map +1 -1
- package/lib/themes/createTextColor.cjs +3 -2
- package/lib/themes/createTextColor.cjs.map +1 -1
- package/lib/themes/createTextColor.js +2 -1
- package/lib/themes/createTextColor.js.map +1 -1
- package/lib/themes/createZIndex.cjs +3 -2
- package/lib/themes/createZIndex.cjs.map +1 -1
- package/lib/themes/createZIndex.js +2 -1
- package/lib/themes/createZIndex.js.map +1 -1
- package/metadata.json +1 -1
- package/package.json +1 -1
- package/smarthr-ui.css +27 -7
- package/lib/components/Table/useReelCells.cjs +0 -83
- package/lib/components/Table/useReelCells.cjs.map +0 -1
- package/lib/components/Table/useReelCells.d.ts +0 -3
- package/lib/components/Table/useReelCells.js +0 -81
- package/lib/components/Table/useReelCells.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scroller.js","sources":["../../../src/components/Scroller/Scroller.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithoutRef,\n type ComponentType,\n type PropsWithChildren,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { type VariantProps, tv } from 'tailwind-variants'\n\nimport { useSectionWrapper } from '../SectioningContent'\n\ntype BaseProps = PropsWithChildren<\n VariantProps<typeof classNameGenerator> & {\n as?: string | ComponentType<any>\n }\n>\ntype Props = BaseProps & Omit<ComponentPropsWithoutRef<'div'>, keyof BaseProps | 'tabIndex'>\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Scroller',\n variants: {\n direction: {\n horizontal: '',\n vertical: '',\n both: '',\n },\n styleType: {\n auto: '',\n scroll: '',\n },\n },\n compoundVariants: [\n {\n direction: 'vertical',\n styleType: 'auto',\n className: 'shr-overflow-y-auto shr-overflow-x-hidden',\n },\n {\n direction: 'horizontal',\n styleType: 'auto',\n className: 'shr-overflow-x-auto shr-overflow-y-hidden',\n },\n {\n direction: 'both',\n styleType: 'auto',\n className: 'shr-overflow-auto',\n },\n {\n direction: 'vertical',\n styleType: 'scroll',\n className: 'shr-overflow-x-hidden shr-overflow-y-scroll',\n },\n {\n direction: 'horizontal',\n styleType: 'scroll',\n className: 'shr-overflow-y-hidden shr-overflow-x-scroll',\n },\n {\n direction: 'both',\n styleType: 'scroll',\n className: 'shr-overflow-scroll',\n },\n ],\n})\n\nexport const Scroller = forwardRef<HTMLDivElement, Props>(\n (\n {\n as: Component = 'div',\n direction = 'vertical',\n styleType = 'auto',\n className,\n children,\n ...rest\n },\n ref,\n ) => {\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n useImperativeHandle(ref, () => wrapperRef.current
|
|
1
|
+
{"version":3,"file":"Scroller.js","sources":["../../../src/components/Scroller/Scroller.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithoutRef,\n type ComponentType,\n type PropsWithChildren,\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { type VariantProps, tv } from 'tailwind-variants'\n\nimport { useSectionWrapper } from '../SectioningContent'\n\ntype BaseProps = PropsWithChildren<\n VariantProps<typeof classNameGenerator> & {\n as?: string | ComponentType<any>\n }\n>\ntype Props = BaseProps & Omit<ComponentPropsWithoutRef<'div'>, keyof BaseProps | 'tabIndex'>\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Scroller',\n variants: {\n direction: {\n horizontal: '',\n vertical: '',\n both: '',\n },\n styleType: {\n auto: '',\n scroll: '',\n },\n },\n compoundVariants: [\n {\n direction: 'vertical',\n styleType: 'auto',\n className: 'shr-overflow-y-auto shr-overflow-x-hidden',\n },\n {\n direction: 'horizontal',\n styleType: 'auto',\n className: 'shr-overflow-x-auto shr-overflow-y-hidden',\n },\n {\n direction: 'both',\n styleType: 'auto',\n className: 'shr-overflow-auto',\n },\n {\n direction: 'vertical',\n styleType: 'scroll',\n className: 'shr-overflow-x-hidden shr-overflow-y-scroll',\n },\n {\n direction: 'horizontal',\n styleType: 'scroll',\n className: 'shr-overflow-y-hidden shr-overflow-x-scroll',\n },\n {\n direction: 'both',\n styleType: 'scroll',\n className: 'shr-overflow-scroll',\n },\n ],\n})\n\nexport const Scroller = forwardRef<HTMLDivElement, Props>(\n (\n {\n as: Component = 'div',\n direction = 'vertical',\n styleType = 'auto',\n className,\n children,\n ...rest\n },\n ref,\n ) => {\n const wrapperRef = useRef<HTMLDivElement>(null)\n\n // as が切り替わると DOM 要素が変わるため、Component を依存配列に含める\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useImperativeHandle(ref, () => wrapperRef.current!, [Component])\n\n const [tabIndex, setTabIndex] = useState<0 | undefined>(undefined)\n\n const actualClassName = useMemo(\n () =>\n classNameGenerator({\n direction,\n styleType,\n className,\n }),\n [direction, styleType, className],\n )\n\n useEffect(() => {\n const refCurrent = wrapperRef.current\n if (!refCurrent) return\n\n const autoTabIndex = () => {\n let nextTabIndex: 0 | undefined = undefined\n\n switch (direction) {\n case 'vertical':\n nextTabIndex = refCurrent.scrollHeight > refCurrent.clientHeight ? 0 : undefined\n break\n case 'horizontal':\n nextTabIndex = refCurrent.scrollWidth > refCurrent.clientWidth ? 0 : undefined\n break\n case 'both':\n nextTabIndex =\n refCurrent.scrollHeight > refCurrent.clientHeight ||\n refCurrent.scrollWidth > refCurrent.clientWidth\n ? 0\n : undefined\n break\n }\n\n setTabIndex(nextTabIndex)\n }\n\n autoTabIndex()\n\n const resizeObserver = new ResizeObserver(autoTabIndex)\n resizeObserver.observe(refCurrent)\n\n return () => {\n resizeObserver.unobserve(refCurrent)\n }\n }, [direction])\n\n const Wrapper = useSectionWrapper(Component)\n const body = (\n <Component {...rest} ref={wrapperRef} className={actualClassName} tabIndex={tabIndex}>\n {children}\n </Component>\n )\n\n if (Wrapper) {\n return <Wrapper>{body}</Wrapper>\n }\n\n return body\n },\n)\n"],"names":[],"mappings":";;;;;;;;AAwBA;AACE;AACA;AACE;AACE;AACA;AACA;AACD;AACD;AACE;AACA;AACD;AACF;AACD;AACE;AACE;AACA;AACA;AACD;AACD;AACE;AACA;AACA;AACD;AACD;AACE;AACA;AACA;AACD;AACD;AACE;AACA;AACA;AACD;AACD;AACE;AACA;AACA;AACD;AACD;AACE;AACA;AACA;AACD;AACF;AACF;AAEM;AAYH;;;AAIA;;;;;;;;AAeE;AACA;;;;;AAMI;AACE;;AAEF;AACE;;AAEF;;AAEI;AACA;AACE;;;;;AAMV;AAEA;AAEA;AACA;AAEA;AACE;AACF;AACF;AAEA;;;AAQE;;AAGF;AACF;;"}
|
|
@@ -60,12 +60,17 @@ const ActualSelect = ({ options, onChange, onChangeValue, error, width, hasBlank
|
|
|
60
60
|
iconWrap: iconWrap(sizeProps),
|
|
61
61
|
blankOptGroup: blankOptgroup(),
|
|
62
62
|
};
|
|
63
|
-
}, [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
}, [size, className]);
|
|
64
|
+
return (jsxRuntime.jsxs("span", { className: classNames.wrapper, style: {
|
|
65
|
+
width: typeof width === 'number' ? `${width}px` : width,
|
|
66
|
+
}, children: [jsxRuntime.jsxs("select", { ...rest, ref: ref, disabled: disabled,
|
|
67
|
+
// HINT: required属性を設定すると、iOS端末で以下の問題が発生します
|
|
68
|
+
// - フォームのsubmit時にバリデーションは行われるが、ユーザーにフィードバックがない
|
|
69
|
+
// - エラーメッセージが表示されない
|
|
70
|
+
// - 問題のある入力フィールドまでスクロールしない
|
|
71
|
+
// 歴史的に一部の端末ではrequired属性が無視されることがあるため、HTMLのバリデーションのみとすることは少ないです
|
|
72
|
+
// そのため、iOS端末ではrequired属性を設定しない方がユーザーがsubmitできない理由をエラーメッセージなどで正しく理解できるようになります
|
|
73
|
+
required: libs_ua.isIOS ? undefined : required, "aria-invalid": error || undefined, "data-smarthr-ui-input": "true", onChange: (e) => {
|
|
69
74
|
onChange?.(e);
|
|
70
75
|
if (onChangeValue) {
|
|
71
76
|
const selectedOption = options
|
|
@@ -75,14 +80,7 @@ const ActualSelect = ({ options, onChange, onChangeValue, error, width, hasBlank
|
|
|
75
80
|
onChangeValue(selectedOption.value);
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
|
-
}, "
|
|
79
|
-
// HINT: required属性を設定すると、iOS端末で以下の問題が発生します
|
|
80
|
-
// - フォームのsubmit時にバリデーションは行われるが、ユーザーにフィードバックがない
|
|
81
|
-
// - エラーメッセージが表示されない
|
|
82
|
-
// - 問題のある入力フィールドまでスクロールしない
|
|
83
|
-
// 歴史的に一部の端末ではrequired属性が無視されることがあるため、HTMLのバリデーションのみとすることは少ないです
|
|
84
|
-
// そのため、iOS端末ではrequired属性を設定しない方がユーザーがsubmitできない理由をエラーメッセージなどで正しく理解できるようになります
|
|
85
|
-
required: libs_ua.isIOS ? undefined : required, ref: ref, className: classNames.select, children: [jsxRuntime.jsx(BlankOption, { hasBlank: hasBlank, children: actualBlankLabel }), options.map((option, index) => (React.createElement(Option, { ...option, key: index }))), jsxRuntime.jsx(NotOmittingLabelsInMobileSafari, { className: classNames.blankOptGroup })] }), jsxRuntime.jsx("span", { className: classNames.iconWrap, children: jsxRuntime.jsx(components_Icon_FaIcon.FaAngleDownIcon, {}) })] }));
|
|
83
|
+
}, className: classNames.select, children: [jsxRuntime.jsx(BlankOption, { hasBlank: hasBlank, children: blankLabel ?? '' }), options.map((option, index) => (React.createElement(Option, { ...option, key: index }))), jsxRuntime.jsx(NotOmittingLabelsInMobileSafari, { className: classNames.blankOptGroup })] }), jsxRuntime.jsx("span", { className: classNames.iconWrap, children: jsxRuntime.jsx(components_Icon_FaIcon.FaAngleDownIcon, {}) })] }));
|
|
86
84
|
};
|
|
87
85
|
const BlankOption = React.memo(({ hasBlank, children }) => hasBlank && jsxRuntime.jsx("option", { value: "", children: children }));
|
|
88
86
|
const Option = React.memo((option) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.cjs","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type ForwardedRef,\n type OptgroupHTMLAttributes,\n type OptionHTMLAttributes,\n type PropsWithChildren,\n memo,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { isIOS, isMobileSafari } from '../../libs/ua'\nimport { genericsForwardRef } from '../../libs/util'\nimport { FaAngleDownIcon } from '../Icon'\n\ntype Option<T extends string> = {\n value: T\n} & Omit<OptionHTMLAttributes<HTMLOptionElement>, 'value'>\ntype Optgroup<T extends string> = {\n label: string\n options: Array<Option<T>>\n} & OptgroupHTMLAttributes<HTMLOptGroupElement>\n\ntype BaseProps<T extends string> = {\n /** 選択肢のデータの配列 */\n options: Array<Option<T> | Optgroup<T>>\n /** フォームの値が変わったときに発火するコールバック関数 */\n onChangeValue?: (value: T) => void\n /** フォームの値にエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** コンポーネントの大きさ */\n size?: 'M' | 'S'\n /** 空の選択肢を表示するかどうか */\n hasBlank?: boolean\n /** 空の選択肢のラベル */\n blankLabel?: string\n}\n\ntype Props<T extends string> = BaseProps<T> &\n Omit<ComponentPropsWithoutRef<'select'>, keyof BaseProps<string> | 'children'>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: 'smarthr-ui-Select shr-relative shr-inline-block',\n select: [\n 'shr-peer shr-border-shorthand shr-w-full shr-cursor-pointer shr-appearance-none shr-rounded-m shr-bg-white shr-text-base shr-leading-tight shr-text-black',\n 'hover:shr-bg-white-darken',\n 'focus-visible:shr-focus-indicator',\n 'disabled:shr-pointer-events-none disabled:shr-bg-white-darken disabled:shr-text-disabled disabled:shr-opacity-100',\n 'contrast-more:shr-border-high-contrast',\n /* padding に依る積み上げでは文字が見切れてしまうため */\n 'shr-min-h-[calc(theme(fontSize.base)_+_theme(spacing[0.75])_*_2_+_theme(spacing.px)_*_2)]',\n 'shr-border-default disabled:shr-border-disabled',\n 'aria-[invalid]:shr-border-danger',\n ],\n iconWrap: [\n 'shr-pointer-events-none shr-absolute shr-inset-y-0 shr-inline-flex shr-items-center shr-text-grey',\n 'peer-focus-visible:shr-text-black peer-disabled:shr-text-disabled',\n ],\n blankOptgroup: 'shr-hidden',\n },\n variants: {\n size: {\n M: {\n select: 'shr-py-0.5 shr-pe-2 shr-ps-0.5',\n // ((右 padding - アイコン幅) / 2) + 右 border\n iconWrap: 'shr-end-[calc(theme(spacing[0.5])_+_theme(spacing.px))]',\n },\n S: {\n select: [\n 'shr-px-0.5 shr-py-0.25 shr-pe-1.5 shr-text-sm',\n /* padding に依る積み上げでは文字が見切れてしまうため */\n 'shr-min-h-[calc(theme(fontSize.sm)_+_theme(spacing[0.5])_*_2_+_theme(spacing.px)_*_2)]',\n ],\n iconWrap: 'shr-end-0.5 shr-text-sm',\n },\n },\n },\n})\n\nconst ActualSelect = <T extends string>(\n {\n options,\n onChange,\n onChangeValue,\n error,\n width,\n hasBlank,\n blankLabel,\n size,\n className,\n disabled,\n required,\n ...rest\n }: Props<T>,\n ref: ForwardedRef<HTMLSelectElement>,\n) => {\n const classNames = useMemo(() => {\n const { wrapper, select, iconWrap, blankOptgroup } = classNameGenerator()\n const sizeProps = {\n size: size || 'M',\n }\n\n return {\n wrapper: wrapper({ className }),\n select: select(sizeProps),\n iconWrap: iconWrap(sizeProps),\n blankOptGroup: blankOptgroup(),\n }\n }, [
|
|
1
|
+
{"version":3,"file":"Select.cjs","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type ForwardedRef,\n type OptgroupHTMLAttributes,\n type OptionHTMLAttributes,\n type PropsWithChildren,\n memo,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { isIOS, isMobileSafari } from '../../libs/ua'\nimport { genericsForwardRef } from '../../libs/util'\nimport { FaAngleDownIcon } from '../Icon'\n\ntype Option<T extends string> = {\n value: T\n} & Omit<OptionHTMLAttributes<HTMLOptionElement>, 'value'>\ntype Optgroup<T extends string> = {\n label: string\n options: Array<Option<T>>\n} & OptgroupHTMLAttributes<HTMLOptGroupElement>\n\ntype BaseProps<T extends string> = {\n /** 選択肢のデータの配列 */\n options: Array<Option<T> | Optgroup<T>>\n /** フォームの値が変わったときに発火するコールバック関数 */\n onChangeValue?: (value: T) => void\n /** フォームの値にエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** コンポーネントの大きさ */\n size?: 'M' | 'S'\n /** 空の選択肢を表示するかどうか */\n hasBlank?: boolean\n /** 空の選択肢のラベル */\n blankLabel?: string\n}\n\ntype Props<T extends string> = BaseProps<T> &\n Omit<ComponentPropsWithoutRef<'select'>, keyof BaseProps<string> | 'children'>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: 'smarthr-ui-Select shr-relative shr-inline-block',\n select: [\n 'shr-peer shr-border-shorthand shr-w-full shr-cursor-pointer shr-appearance-none shr-rounded-m shr-bg-white shr-text-base shr-leading-tight shr-text-black',\n 'hover:shr-bg-white-darken',\n 'focus-visible:shr-focus-indicator',\n 'disabled:shr-pointer-events-none disabled:shr-bg-white-darken disabled:shr-text-disabled disabled:shr-opacity-100',\n 'contrast-more:shr-border-high-contrast',\n /* padding に依る積み上げでは文字が見切れてしまうため */\n 'shr-min-h-[calc(theme(fontSize.base)_+_theme(spacing[0.75])_*_2_+_theme(spacing.px)_*_2)]',\n 'shr-border-default disabled:shr-border-disabled',\n 'aria-[invalid]:shr-border-danger',\n ],\n iconWrap: [\n 'shr-pointer-events-none shr-absolute shr-inset-y-0 shr-inline-flex shr-items-center shr-text-grey',\n 'peer-focus-visible:shr-text-black peer-disabled:shr-text-disabled',\n ],\n blankOptgroup: 'shr-hidden',\n },\n variants: {\n size: {\n M: {\n select: 'shr-py-0.5 shr-pe-2 shr-ps-0.5',\n // ((右 padding - アイコン幅) / 2) + 右 border\n iconWrap: 'shr-end-[calc(theme(spacing[0.5])_+_theme(spacing.px))]',\n },\n S: {\n select: [\n 'shr-px-0.5 shr-py-0.25 shr-pe-1.5 shr-text-sm',\n /* padding に依る積み上げでは文字が見切れてしまうため */\n 'shr-min-h-[calc(theme(fontSize.sm)_+_theme(spacing[0.5])_*_2_+_theme(spacing.px)_*_2)]',\n ],\n iconWrap: 'shr-end-0.5 shr-text-sm',\n },\n },\n },\n})\n\nconst ActualSelect = <T extends string>(\n {\n options,\n onChange,\n onChangeValue,\n error,\n width,\n hasBlank,\n blankLabel,\n size,\n className,\n disabled,\n required,\n ...rest\n }: Props<T>,\n ref: ForwardedRef<HTMLSelectElement>,\n) => {\n const classNames = useMemo(() => {\n const { wrapper, select, iconWrap, blankOptgroup } = classNameGenerator()\n const sizeProps = {\n size: size || 'M',\n }\n\n return {\n wrapper: wrapper({ className }),\n select: select(sizeProps),\n iconWrap: iconWrap(sizeProps),\n blankOptGroup: blankOptgroup(),\n }\n }, [size, className])\n\n return (\n <span\n className={classNames.wrapper}\n style={{\n width: typeof width === 'number' ? `${width}px` : width,\n }}\n >\n <select\n {...rest}\n ref={ref}\n disabled={disabled}\n // HINT: required属性を設定すると、iOS端末で以下の問題が発生します\n // - フォームのsubmit時にバリデーションは行われるが、ユーザーにフィードバックがない\n // - エラーメッセージが表示されない\n // - 問題のある入力フィールドまでスクロールしない\n // 歴史的に一部の端末ではrequired属性が無視されることがあるため、HTMLのバリデーションのみとすることは少ないです\n // そのため、iOS端末ではrequired属性を設定しない方がユーザーがsubmitできない理由をエラーメッセージなどで正しく理解できるようになります\n required={isIOS ? undefined : required}\n aria-invalid={error || undefined}\n data-smarthr-ui-input=\"true\"\n onChange={(e: ChangeEvent<HTMLSelectElement>) => {\n onChange?.(e)\n\n if (onChangeValue) {\n const selectedOption = options\n .flatMap((option) => ('value' in option ? [option] : option.options))\n .find((option) => option.value === e.target.value)\n\n if (selectedOption) {\n onChangeValue(selectedOption.value)\n }\n }\n }}\n className={classNames.select}\n >\n <BlankOption hasBlank={hasBlank}>{blankLabel ?? ''}</BlankOption>\n {options.map((option, index) => (\n <Option {...option} key={index} />\n ))}\n <NotOmittingLabelsInMobileSafari className={classNames.blankOptGroup} />\n </select>\n <span className={classNames.iconWrap}>\n <FaAngleDownIcon />\n </span>\n </span>\n )\n}\n\nconst BlankOption = memo<\n PropsWithChildren<{\n hasBlank: boolean | undefined\n }>\n>(({ hasBlank, children }) => hasBlank && <option value=\"\">{children}</option>)\n\nconst Option = memo<Props<string>['options'][number]>((option) => {\n if ('value' in option) {\n return <option {...option}>{option.label}</option>\n }\n\n const { options: groupedOptions, label, ...rest } = option\n\n return (\n <optgroup {...rest} key={label} label={label}>\n {groupedOptions.map((groupedOption) => (\n <option {...groupedOption} key={groupedOption.value}>\n {groupedOption.label}\n </option>\n ))}\n </optgroup>\n )\n})\n\n// Support for not omitting labels in Mobile Safari\nconst NotOmittingLabelsInMobileSafari = memo<{ className: string }>(\n ({ className }) => isMobileSafari && <optgroup className={className} />,\n)\n\nexport const Select = genericsForwardRef(ActualSelect)\n"],"names":[],"mappings":";;;;;;;;;;;;AA8CA;AACE;AACE;AACA;;;;;;;;;;AAUC;AACD;;;AAGC;AACD;AACD;AACD;AACE;AACE;AACE;;AAEA;AACD;AACD;AACE;;;;AAIC;AACD;AACD;AACF;AACF;AACF;AAED;AAiBE;AACE;AACA;;;;AAKE;AACA;AACA;;;AAGJ;;AAMM;;;;;;;;;AAiBE;;;;AAKK;;AAGD;;;AAGN;AAcR;AAEA;AAMA;AACE;AACE;;AAGF;AAEA;AASF;AAEA;AACA;;;"}
|
|
@@ -58,12 +58,17 @@ const ActualSelect = ({ options, onChange, onChangeValue, error, width, hasBlank
|
|
|
58
58
|
iconWrap: iconWrap(sizeProps),
|
|
59
59
|
blankOptGroup: blankOptgroup(),
|
|
60
60
|
};
|
|
61
|
-
}, [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
}, [size, className]);
|
|
62
|
+
return (jsxs("span", { className: classNames.wrapper, style: {
|
|
63
|
+
width: typeof width === 'number' ? `${width}px` : width,
|
|
64
|
+
}, children: [jsxs("select", { ...rest, ref: ref, disabled: disabled,
|
|
65
|
+
// HINT: required属性を設定すると、iOS端末で以下の問題が発生します
|
|
66
|
+
// - フォームのsubmit時にバリデーションは行われるが、ユーザーにフィードバックがない
|
|
67
|
+
// - エラーメッセージが表示されない
|
|
68
|
+
// - 問題のある入力フィールドまでスクロールしない
|
|
69
|
+
// 歴史的に一部の端末ではrequired属性が無視されることがあるため、HTMLのバリデーションのみとすることは少ないです
|
|
70
|
+
// そのため、iOS端末ではrequired属性を設定しない方がユーザーがsubmitできない理由をエラーメッセージなどで正しく理解できるようになります
|
|
71
|
+
required: isIOS ? undefined : required, "aria-invalid": error || undefined, "data-smarthr-ui-input": "true", onChange: (e) => {
|
|
67
72
|
onChange?.(e);
|
|
68
73
|
if (onChangeValue) {
|
|
69
74
|
const selectedOption = options
|
|
@@ -73,14 +78,7 @@ const ActualSelect = ({ options, onChange, onChangeValue, error, width, hasBlank
|
|
|
73
78
|
onChangeValue(selectedOption.value);
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
|
-
}, "
|
|
77
|
-
// HINT: required属性を設定すると、iOS端末で以下の問題が発生します
|
|
78
|
-
// - フォームのsubmit時にバリデーションは行われるが、ユーザーにフィードバックがない
|
|
79
|
-
// - エラーメッセージが表示されない
|
|
80
|
-
// - 問題のある入力フィールドまでスクロールしない
|
|
81
|
-
// 歴史的に一部の端末ではrequired属性が無視されることがあるため、HTMLのバリデーションのみとすることは少ないです
|
|
82
|
-
// そのため、iOS端末ではrequired属性を設定しない方がユーザーがsubmitできない理由をエラーメッセージなどで正しく理解できるようになります
|
|
83
|
-
required: isIOS ? undefined : required, ref: ref, className: classNames.select, children: [jsx(BlankOption, { hasBlank: hasBlank, children: actualBlankLabel }), options.map((option, index) => (createElement(Option, { ...option, key: index }))), jsx(NotOmittingLabelsInMobileSafari, { className: classNames.blankOptGroup })] }), jsx("span", { className: classNames.iconWrap, children: jsx(FaAngleDownIcon, {}) })] }));
|
|
81
|
+
}, className: classNames.select, children: [jsx(BlankOption, { hasBlank: hasBlank, children: blankLabel ?? '' }), options.map((option, index) => (createElement(Option, { ...option, key: index }))), jsx(NotOmittingLabelsInMobileSafari, { className: classNames.blankOptGroup })] }), jsx("span", { className: classNames.iconWrap, children: jsx(FaAngleDownIcon, {}) })] }));
|
|
84
82
|
};
|
|
85
83
|
const BlankOption = memo(({ hasBlank, children }) => hasBlank && jsx("option", { value: "", children: children }));
|
|
86
84
|
const Option = memo((option) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.js","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type ForwardedRef,\n type OptgroupHTMLAttributes,\n type OptionHTMLAttributes,\n type PropsWithChildren,\n memo,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { isIOS, isMobileSafari } from '../../libs/ua'\nimport { genericsForwardRef } from '../../libs/util'\nimport { FaAngleDownIcon } from '../Icon'\n\ntype Option<T extends string> = {\n value: T\n} & Omit<OptionHTMLAttributes<HTMLOptionElement>, 'value'>\ntype Optgroup<T extends string> = {\n label: string\n options: Array<Option<T>>\n} & OptgroupHTMLAttributes<HTMLOptGroupElement>\n\ntype BaseProps<T extends string> = {\n /** 選択肢のデータの配列 */\n options: Array<Option<T> | Optgroup<T>>\n /** フォームの値が変わったときに発火するコールバック関数 */\n onChangeValue?: (value: T) => void\n /** フォームの値にエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** コンポーネントの大きさ */\n size?: 'M' | 'S'\n /** 空の選択肢を表示するかどうか */\n hasBlank?: boolean\n /** 空の選択肢のラベル */\n blankLabel?: string\n}\n\ntype Props<T extends string> = BaseProps<T> &\n Omit<ComponentPropsWithoutRef<'select'>, keyof BaseProps<string> | 'children'>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: 'smarthr-ui-Select shr-relative shr-inline-block',\n select: [\n 'shr-peer shr-border-shorthand shr-w-full shr-cursor-pointer shr-appearance-none shr-rounded-m shr-bg-white shr-text-base shr-leading-tight shr-text-black',\n 'hover:shr-bg-white-darken',\n 'focus-visible:shr-focus-indicator',\n 'disabled:shr-pointer-events-none disabled:shr-bg-white-darken disabled:shr-text-disabled disabled:shr-opacity-100',\n 'contrast-more:shr-border-high-contrast',\n /* padding に依る積み上げでは文字が見切れてしまうため */\n 'shr-min-h-[calc(theme(fontSize.base)_+_theme(spacing[0.75])_*_2_+_theme(spacing.px)_*_2)]',\n 'shr-border-default disabled:shr-border-disabled',\n 'aria-[invalid]:shr-border-danger',\n ],\n iconWrap: [\n 'shr-pointer-events-none shr-absolute shr-inset-y-0 shr-inline-flex shr-items-center shr-text-grey',\n 'peer-focus-visible:shr-text-black peer-disabled:shr-text-disabled',\n ],\n blankOptgroup: 'shr-hidden',\n },\n variants: {\n size: {\n M: {\n select: 'shr-py-0.5 shr-pe-2 shr-ps-0.5',\n // ((右 padding - アイコン幅) / 2) + 右 border\n iconWrap: 'shr-end-[calc(theme(spacing[0.5])_+_theme(spacing.px))]',\n },\n S: {\n select: [\n 'shr-px-0.5 shr-py-0.25 shr-pe-1.5 shr-text-sm',\n /* padding に依る積み上げでは文字が見切れてしまうため */\n 'shr-min-h-[calc(theme(fontSize.sm)_+_theme(spacing[0.5])_*_2_+_theme(spacing.px)_*_2)]',\n ],\n iconWrap: 'shr-end-0.5 shr-text-sm',\n },\n },\n },\n})\n\nconst ActualSelect = <T extends string>(\n {\n options,\n onChange,\n onChangeValue,\n error,\n width,\n hasBlank,\n blankLabel,\n size,\n className,\n disabled,\n required,\n ...rest\n }: Props<T>,\n ref: ForwardedRef<HTMLSelectElement>,\n) => {\n const classNames = useMemo(() => {\n const { wrapper, select, iconWrap, blankOptgroup } = classNameGenerator()\n const sizeProps = {\n size: size || 'M',\n }\n\n return {\n wrapper: wrapper({ className }),\n select: select(sizeProps),\n iconWrap: iconWrap(sizeProps),\n blankOptGroup: blankOptgroup(),\n }\n }, [
|
|
1
|
+
{"version":3,"file":"Select.js","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type ForwardedRef,\n type OptgroupHTMLAttributes,\n type OptionHTMLAttributes,\n type PropsWithChildren,\n memo,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { isIOS, isMobileSafari } from '../../libs/ua'\nimport { genericsForwardRef } from '../../libs/util'\nimport { FaAngleDownIcon } from '../Icon'\n\ntype Option<T extends string> = {\n value: T\n} & Omit<OptionHTMLAttributes<HTMLOptionElement>, 'value'>\ntype Optgroup<T extends string> = {\n label: string\n options: Array<Option<T>>\n} & OptgroupHTMLAttributes<HTMLOptGroupElement>\n\ntype BaseProps<T extends string> = {\n /** 選択肢のデータの配列 */\n options: Array<Option<T> | Optgroup<T>>\n /** フォームの値が変わったときに発火するコールバック関数 */\n onChangeValue?: (value: T) => void\n /** フォームの値にエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** コンポーネントの大きさ */\n size?: 'M' | 'S'\n /** 空の選択肢を表示するかどうか */\n hasBlank?: boolean\n /** 空の選択肢のラベル */\n blankLabel?: string\n}\n\ntype Props<T extends string> = BaseProps<T> &\n Omit<ComponentPropsWithoutRef<'select'>, keyof BaseProps<string> | 'children'>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: 'smarthr-ui-Select shr-relative shr-inline-block',\n select: [\n 'shr-peer shr-border-shorthand shr-w-full shr-cursor-pointer shr-appearance-none shr-rounded-m shr-bg-white shr-text-base shr-leading-tight shr-text-black',\n 'hover:shr-bg-white-darken',\n 'focus-visible:shr-focus-indicator',\n 'disabled:shr-pointer-events-none disabled:shr-bg-white-darken disabled:shr-text-disabled disabled:shr-opacity-100',\n 'contrast-more:shr-border-high-contrast',\n /* padding に依る積み上げでは文字が見切れてしまうため */\n 'shr-min-h-[calc(theme(fontSize.base)_+_theme(spacing[0.75])_*_2_+_theme(spacing.px)_*_2)]',\n 'shr-border-default disabled:shr-border-disabled',\n 'aria-[invalid]:shr-border-danger',\n ],\n iconWrap: [\n 'shr-pointer-events-none shr-absolute shr-inset-y-0 shr-inline-flex shr-items-center shr-text-grey',\n 'peer-focus-visible:shr-text-black peer-disabled:shr-text-disabled',\n ],\n blankOptgroup: 'shr-hidden',\n },\n variants: {\n size: {\n M: {\n select: 'shr-py-0.5 shr-pe-2 shr-ps-0.5',\n // ((右 padding - アイコン幅) / 2) + 右 border\n iconWrap: 'shr-end-[calc(theme(spacing[0.5])_+_theme(spacing.px))]',\n },\n S: {\n select: [\n 'shr-px-0.5 shr-py-0.25 shr-pe-1.5 shr-text-sm',\n /* padding に依る積み上げでは文字が見切れてしまうため */\n 'shr-min-h-[calc(theme(fontSize.sm)_+_theme(spacing[0.5])_*_2_+_theme(spacing.px)_*_2)]',\n ],\n iconWrap: 'shr-end-0.5 shr-text-sm',\n },\n },\n },\n})\n\nconst ActualSelect = <T extends string>(\n {\n options,\n onChange,\n onChangeValue,\n error,\n width,\n hasBlank,\n blankLabel,\n size,\n className,\n disabled,\n required,\n ...rest\n }: Props<T>,\n ref: ForwardedRef<HTMLSelectElement>,\n) => {\n const classNames = useMemo(() => {\n const { wrapper, select, iconWrap, blankOptgroup } = classNameGenerator()\n const sizeProps = {\n size: size || 'M',\n }\n\n return {\n wrapper: wrapper({ className }),\n select: select(sizeProps),\n iconWrap: iconWrap(sizeProps),\n blankOptGroup: blankOptgroup(),\n }\n }, [size, className])\n\n return (\n <span\n className={classNames.wrapper}\n style={{\n width: typeof width === 'number' ? `${width}px` : width,\n }}\n >\n <select\n {...rest}\n ref={ref}\n disabled={disabled}\n // HINT: required属性を設定すると、iOS端末で以下の問題が発生します\n // - フォームのsubmit時にバリデーションは行われるが、ユーザーにフィードバックがない\n // - エラーメッセージが表示されない\n // - 問題のある入力フィールドまでスクロールしない\n // 歴史的に一部の端末ではrequired属性が無視されることがあるため、HTMLのバリデーションのみとすることは少ないです\n // そのため、iOS端末ではrequired属性を設定しない方がユーザーがsubmitできない理由をエラーメッセージなどで正しく理解できるようになります\n required={isIOS ? undefined : required}\n aria-invalid={error || undefined}\n data-smarthr-ui-input=\"true\"\n onChange={(e: ChangeEvent<HTMLSelectElement>) => {\n onChange?.(e)\n\n if (onChangeValue) {\n const selectedOption = options\n .flatMap((option) => ('value' in option ? [option] : option.options))\n .find((option) => option.value === e.target.value)\n\n if (selectedOption) {\n onChangeValue(selectedOption.value)\n }\n }\n }}\n className={classNames.select}\n >\n <BlankOption hasBlank={hasBlank}>{blankLabel ?? ''}</BlankOption>\n {options.map((option, index) => (\n <Option {...option} key={index} />\n ))}\n <NotOmittingLabelsInMobileSafari className={classNames.blankOptGroup} />\n </select>\n <span className={classNames.iconWrap}>\n <FaAngleDownIcon />\n </span>\n </span>\n )\n}\n\nconst BlankOption = memo<\n PropsWithChildren<{\n hasBlank: boolean | undefined\n }>\n>(({ hasBlank, children }) => hasBlank && <option value=\"\">{children}</option>)\n\nconst Option = memo<Props<string>['options'][number]>((option) => {\n if ('value' in option) {\n return <option {...option}>{option.label}</option>\n }\n\n const { options: groupedOptions, label, ...rest } = option\n\n return (\n <optgroup {...rest} key={label} label={label}>\n {groupedOptions.map((groupedOption) => (\n <option {...groupedOption} key={groupedOption.value}>\n {groupedOption.label}\n </option>\n ))}\n </optgroup>\n )\n})\n\n// Support for not omitting labels in Mobile Safari\nconst NotOmittingLabelsInMobileSafari = memo<{ className: string }>(\n ({ className }) => isMobileSafari && <optgroup className={className} />,\n)\n\nexport const Select = genericsForwardRef(ActualSelect)\n"],"names":[],"mappings":";;;;;;;;;;AA8CA;AACE;AACE;AACA;;;;;;;;;;AAUC;AACD;;;AAGC;AACD;AACD;AACD;AACE;AACE;AACE;;AAEA;AACD;AACD;AACE;;;;AAIC;AACD;AACD;AACF;AACF;AACF;AAED;AAiBE;AACE;AACA;;;;AAKE;AACA;AACA;;;AAGJ;;AAMM;;;;;;;;;AAiBE;;;;AAKK;;AAGD;;;AAGN;AAcR;AAEA;AAMA;AACE;AACE;;AAGF;AAEA;AASF;AAEA;AACA;;;"}
|
|
@@ -5,8 +5,11 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs');
|
|
7
7
|
var components_Table_reelShadowStyle = require('./reelShadowStyle.cjs');
|
|
8
|
-
var components_Table_useReelCells = require('./useReelCells.cjs');
|
|
9
8
|
|
|
9
|
+
const TR_SELECTOR = 'table tr';
|
|
10
|
+
const FIXED_LEFT_SELECTOR = '[data-fixed="left"]';
|
|
11
|
+
const FIXED_RIGHT_SELECTOR = '[data-fixed="right"]';
|
|
12
|
+
const HAS_FIXED_SELECTOR = `${TR_SELECTOR} ${FIXED_LEFT_SELECTOR},${TR_SELECTOR} ${FIXED_RIGHT_SELECTOR}`;
|
|
10
13
|
const classNameGenerator = index.tv({
|
|
11
14
|
slots: {
|
|
12
15
|
wrapper: ['smarthr-ui-TableReel', 'shr-relative'],
|
|
@@ -14,14 +17,75 @@ const classNameGenerator = index.tv({
|
|
|
14
17
|
},
|
|
15
18
|
});
|
|
16
19
|
const TableReel = ({ className, children, tableWrapperRef, ...rest }) => {
|
|
17
|
-
const
|
|
20
|
+
const [showShadow, setShowShadow] = React.useState(false);
|
|
21
|
+
React.useEffect(() => {
|
|
22
|
+
const wrapper = tableWrapperRef.current;
|
|
23
|
+
if (!wrapper) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
let currentObserver = null;
|
|
27
|
+
const handleScroll = () => {
|
|
28
|
+
if (!wrapper.querySelector(HAS_FIXED_SELECTOR)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
let isVisible = false;
|
|
32
|
+
const commonAction = (cells, direction, visible) => {
|
|
33
|
+
currentObserver?.disconnect();
|
|
34
|
+
currentObserver = null;
|
|
35
|
+
const action = () => {
|
|
36
|
+
let position = 0;
|
|
37
|
+
cells.forEach((cell, index) => {
|
|
38
|
+
if (cell.classList.toggle('fixed', visible)) {
|
|
39
|
+
isVisible = true;
|
|
40
|
+
cell.style[direction] = `${position}px`;
|
|
41
|
+
cell.style.zIndex = (index + 1).toString();
|
|
42
|
+
position += cell.offsetWidth;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
action();
|
|
47
|
+
const observer = new ResizeObserver(action);
|
|
48
|
+
cells.forEach((cell) => {
|
|
49
|
+
observer.observe(cell);
|
|
50
|
+
});
|
|
51
|
+
currentObserver = observer;
|
|
52
|
+
};
|
|
53
|
+
wrapper.querySelectorAll(TR_SELECTOR).forEach((tr) => {
|
|
54
|
+
const leftCells = tr.querySelectorAll(FIXED_LEFT_SELECTOR);
|
|
55
|
+
const rightCells = Array.from(tr.querySelectorAll(FIXED_RIGHT_SELECTOR)).reverse();
|
|
56
|
+
if (leftCells.length > 0) {
|
|
57
|
+
commonAction(leftCells, 'left', wrapper.scrollLeft > 0);
|
|
58
|
+
}
|
|
59
|
+
if (rightCells.length > 0) {
|
|
60
|
+
commonAction(rightCells, 'right', wrapper.scrollLeft < wrapper.scrollWidth - wrapper.clientWidth - 1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
setShowShadow(isVisible);
|
|
64
|
+
};
|
|
65
|
+
handleScroll();
|
|
66
|
+
wrapper.addEventListener('scroll', handleScroll);
|
|
67
|
+
const resizeObserver = new ResizeObserver(handleScroll);
|
|
68
|
+
resizeObserver.observe(wrapper);
|
|
69
|
+
// HINT: Paginationと組み合わせた際などにテーブル構造の変更を検知して再生成
|
|
70
|
+
const mutationObserver = new MutationObserver(handleScroll);
|
|
71
|
+
mutationObserver.observe(wrapper, {
|
|
72
|
+
childList: true,
|
|
73
|
+
subtree: true,
|
|
74
|
+
});
|
|
75
|
+
return () => {
|
|
76
|
+
wrapper.removeEventListener('scroll', handleScroll);
|
|
77
|
+
resizeObserver.unobserve(wrapper);
|
|
78
|
+
mutationObserver.disconnect();
|
|
79
|
+
currentObserver?.disconnect();
|
|
80
|
+
};
|
|
81
|
+
}, [tableWrapperRef]);
|
|
18
82
|
const classNames = React.useMemo(() => {
|
|
19
83
|
const { wrapper, inner } = classNameGenerator();
|
|
20
84
|
return {
|
|
21
85
|
wrapper: components_Table_reelShadowStyle.reelShadowClassNameGenerator({ showShadow, className: wrapper({ className }) }),
|
|
22
86
|
inner: inner(),
|
|
23
87
|
};
|
|
24
|
-
}, [
|
|
88
|
+
}, [showShadow, className]);
|
|
25
89
|
return (jsxRuntime.jsx("div", { className: classNames.wrapper, children: jsxRuntime.jsx("div", { ...rest, className: classNames.inner, children: children }) }));
|
|
26
90
|
};
|
|
27
91
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableReel.cjs","sources":["../../../src/components/Table/TableReel.tsx"],"sourcesContent":["'use client'\n\nimport {
|
|
1
|
+
{"version":3,"file":"TableReel.cjs","sources":["../../../src/components/Table/TableReel.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type FC,\n type PropsWithChildren,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { reelShadowClassNameGenerator } from './reelShadowStyle'\n\nconst TR_SELECTOR = 'table tr'\nconst FIXED_LEFT_SELECTOR = '[data-fixed=\"left\"]'\nconst FIXED_RIGHT_SELECTOR = '[data-fixed=\"right\"]'\n\nconst HAS_FIXED_SELECTOR = `${TR_SELECTOR} ${FIXED_LEFT_SELECTOR},${TR_SELECTOR} ${FIXED_RIGHT_SELECTOR}`\n\ntype Props = PropsWithChildren &\n Omit<ComponentPropsWithRef<'div'>, keyof PropsWithChildren> & {\n tableWrapperRef: React.RefObject<HTMLDivElement>\n }\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: ['smarthr-ui-TableReel', 'shr-relative'],\n inner: ['smarthr-ui-TableReel-inner', 'shr-relative'],\n },\n})\n\nexport const TableReel: FC<Props> = ({ className, children, tableWrapperRef, ...rest }) => {\n const [showShadow, setShowShadow] = useState(false)\n\n useEffect(() => {\n const wrapper = tableWrapperRef.current\n\n if (!wrapper) {\n return\n }\n\n let currentObserver: ResizeObserver | null = null\n\n const handleScroll = () => {\n if (!wrapper.querySelector(HAS_FIXED_SELECTOR)) {\n return\n }\n\n let isVisible = false\n const commonAction = (\n cells: HTMLElement[] | NodeListOf<HTMLElement>,\n direction: 'left' | 'right',\n visible: boolean,\n ) => {\n currentObserver?.disconnect()\n currentObserver = null\n\n const action = () => {\n let position = 0\n\n cells.forEach((cell, index) => {\n if (cell.classList.toggle('fixed', visible)) {\n isVisible = true\n cell.style[direction] = `${position}px`\n cell.style.zIndex = (index + 1).toString()\n\n position += cell.offsetWidth\n }\n })\n }\n\n action()\n const observer = new ResizeObserver(action)\n\n cells.forEach((cell) => {\n observer.observe(cell)\n })\n\n currentObserver = observer\n }\n\n wrapper.querySelectorAll<HTMLElement>(TR_SELECTOR).forEach((tr) => {\n const leftCells = tr.querySelectorAll<HTMLElement>(FIXED_LEFT_SELECTOR)\n const rightCells = Array.from(\n tr.querySelectorAll<HTMLElement>(FIXED_RIGHT_SELECTOR),\n ).reverse()\n\n if (leftCells.length > 0) {\n commonAction(leftCells, 'left' as const, wrapper.scrollLeft > 0)\n }\n\n if (rightCells.length > 0) {\n commonAction(\n rightCells,\n 'right' as const,\n wrapper.scrollLeft < wrapper.scrollWidth - wrapper.clientWidth - 1,\n )\n }\n })\n\n setShowShadow(isVisible)\n }\n\n handleScroll()\n wrapper.addEventListener('scroll', handleScroll)\n\n const resizeObserver = new ResizeObserver(handleScroll)\n resizeObserver.observe(wrapper)\n\n // HINT: Paginationと組み合わせた際などにテーブル構造の変更を検知して再生成\n const mutationObserver = new MutationObserver(handleScroll)\n mutationObserver.observe(wrapper, {\n childList: true,\n subtree: true,\n })\n\n return () => {\n wrapper.removeEventListener('scroll', handleScroll)\n resizeObserver.unobserve(wrapper)\n mutationObserver.disconnect()\n currentObserver?.disconnect()\n }\n }, [tableWrapperRef])\n\n const classNames = useMemo(() => {\n const { wrapper, inner } = classNameGenerator()\n\n return {\n wrapper: reelShadowClassNameGenerator({ showShadow, className: wrapper({ className }) }),\n inner: inner(),\n }\n }, [showShadow, className])\n\n return (\n <div className={classNames.wrapper}>\n <div {...rest} className={classNames.inner}>\n {children}\n </div>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;AAcA;AACA;AACA;AAEA;AAOA;AACE;AACE;AACA;AACD;AACF;AAEM;;;AAIH;;;;;;;;;;;;;;;;;;;AA6BU;AAEA;;AAEJ;AACF;AAEA;AACA;AAEA;AACE;AACF;;AAGF;;;AAIE;AAIA;;;AAIA;AACE;;AAMJ;;AAGF;AAEA;AACA;AAEA;AACA;;AAGA;AACA;AACE;AACA;AACD;AAED;AACE;AACA;;;AAGF;AACF;AAEA;;;AAII;;;AAGJ;;AASF;;"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useMemo } from 'react';
|
|
3
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
4
4
|
import { tv as ce } from './../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js';
|
|
5
5
|
import { reelShadowClassNameGenerator } from './reelShadowStyle.js';
|
|
6
|
-
import { useReelCells } from './useReelCells.js';
|
|
7
6
|
|
|
7
|
+
const TR_SELECTOR = 'table tr';
|
|
8
|
+
const FIXED_LEFT_SELECTOR = '[data-fixed="left"]';
|
|
9
|
+
const FIXED_RIGHT_SELECTOR = '[data-fixed="right"]';
|
|
10
|
+
const HAS_FIXED_SELECTOR = `${TR_SELECTOR} ${FIXED_LEFT_SELECTOR},${TR_SELECTOR} ${FIXED_RIGHT_SELECTOR}`;
|
|
8
11
|
const classNameGenerator = ce({
|
|
9
12
|
slots: {
|
|
10
13
|
wrapper: ['smarthr-ui-TableReel', 'shr-relative'],
|
|
@@ -12,14 +15,75 @@ const classNameGenerator = ce({
|
|
|
12
15
|
},
|
|
13
16
|
});
|
|
14
17
|
const TableReel = ({ className, children, tableWrapperRef, ...rest }) => {
|
|
15
|
-
const
|
|
18
|
+
const [showShadow, setShowShadow] = useState(false);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const wrapper = tableWrapperRef.current;
|
|
21
|
+
if (!wrapper) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
let currentObserver = null;
|
|
25
|
+
const handleScroll = () => {
|
|
26
|
+
if (!wrapper.querySelector(HAS_FIXED_SELECTOR)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
let isVisible = false;
|
|
30
|
+
const commonAction = (cells, direction, visible) => {
|
|
31
|
+
currentObserver?.disconnect();
|
|
32
|
+
currentObserver = null;
|
|
33
|
+
const action = () => {
|
|
34
|
+
let position = 0;
|
|
35
|
+
cells.forEach((cell, index) => {
|
|
36
|
+
if (cell.classList.toggle('fixed', visible)) {
|
|
37
|
+
isVisible = true;
|
|
38
|
+
cell.style[direction] = `${position}px`;
|
|
39
|
+
cell.style.zIndex = (index + 1).toString();
|
|
40
|
+
position += cell.offsetWidth;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
action();
|
|
45
|
+
const observer = new ResizeObserver(action);
|
|
46
|
+
cells.forEach((cell) => {
|
|
47
|
+
observer.observe(cell);
|
|
48
|
+
});
|
|
49
|
+
currentObserver = observer;
|
|
50
|
+
};
|
|
51
|
+
wrapper.querySelectorAll(TR_SELECTOR).forEach((tr) => {
|
|
52
|
+
const leftCells = tr.querySelectorAll(FIXED_LEFT_SELECTOR);
|
|
53
|
+
const rightCells = Array.from(tr.querySelectorAll(FIXED_RIGHT_SELECTOR)).reverse();
|
|
54
|
+
if (leftCells.length > 0) {
|
|
55
|
+
commonAction(leftCells, 'left', wrapper.scrollLeft > 0);
|
|
56
|
+
}
|
|
57
|
+
if (rightCells.length > 0) {
|
|
58
|
+
commonAction(rightCells, 'right', wrapper.scrollLeft < wrapper.scrollWidth - wrapper.clientWidth - 1);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
setShowShadow(isVisible);
|
|
62
|
+
};
|
|
63
|
+
handleScroll();
|
|
64
|
+
wrapper.addEventListener('scroll', handleScroll);
|
|
65
|
+
const resizeObserver = new ResizeObserver(handleScroll);
|
|
66
|
+
resizeObserver.observe(wrapper);
|
|
67
|
+
// HINT: Paginationと組み合わせた際などにテーブル構造の変更を検知して再生成
|
|
68
|
+
const mutationObserver = new MutationObserver(handleScroll);
|
|
69
|
+
mutationObserver.observe(wrapper, {
|
|
70
|
+
childList: true,
|
|
71
|
+
subtree: true,
|
|
72
|
+
});
|
|
73
|
+
return () => {
|
|
74
|
+
wrapper.removeEventListener('scroll', handleScroll);
|
|
75
|
+
resizeObserver.unobserve(wrapper);
|
|
76
|
+
mutationObserver.disconnect();
|
|
77
|
+
currentObserver?.disconnect();
|
|
78
|
+
};
|
|
79
|
+
}, [tableWrapperRef]);
|
|
16
80
|
const classNames = useMemo(() => {
|
|
17
81
|
const { wrapper, inner } = classNameGenerator();
|
|
18
82
|
return {
|
|
19
83
|
wrapper: reelShadowClassNameGenerator({ showShadow, className: wrapper({ className }) }),
|
|
20
84
|
inner: inner(),
|
|
21
85
|
};
|
|
22
|
-
}, [
|
|
86
|
+
}, [showShadow, className]);
|
|
23
87
|
return (jsx("div", { className: classNames.wrapper, children: jsx("div", { ...rest, className: classNames.inner, children: children }) }));
|
|
24
88
|
};
|
|
25
89
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableReel.js","sources":["../../../src/components/Table/TableReel.tsx"],"sourcesContent":["'use client'\n\nimport {
|
|
1
|
+
{"version":3,"file":"TableReel.js","sources":["../../../src/components/Table/TableReel.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type FC,\n type PropsWithChildren,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { reelShadowClassNameGenerator } from './reelShadowStyle'\n\nconst TR_SELECTOR = 'table tr'\nconst FIXED_LEFT_SELECTOR = '[data-fixed=\"left\"]'\nconst FIXED_RIGHT_SELECTOR = '[data-fixed=\"right\"]'\n\nconst HAS_FIXED_SELECTOR = `${TR_SELECTOR} ${FIXED_LEFT_SELECTOR},${TR_SELECTOR} ${FIXED_RIGHT_SELECTOR}`\n\ntype Props = PropsWithChildren &\n Omit<ComponentPropsWithRef<'div'>, keyof PropsWithChildren> & {\n tableWrapperRef: React.RefObject<HTMLDivElement>\n }\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: ['smarthr-ui-TableReel', 'shr-relative'],\n inner: ['smarthr-ui-TableReel-inner', 'shr-relative'],\n },\n})\n\nexport const TableReel: FC<Props> = ({ className, children, tableWrapperRef, ...rest }) => {\n const [showShadow, setShowShadow] = useState(false)\n\n useEffect(() => {\n const wrapper = tableWrapperRef.current\n\n if (!wrapper) {\n return\n }\n\n let currentObserver: ResizeObserver | null = null\n\n const handleScroll = () => {\n if (!wrapper.querySelector(HAS_FIXED_SELECTOR)) {\n return\n }\n\n let isVisible = false\n const commonAction = (\n cells: HTMLElement[] | NodeListOf<HTMLElement>,\n direction: 'left' | 'right',\n visible: boolean,\n ) => {\n currentObserver?.disconnect()\n currentObserver = null\n\n const action = () => {\n let position = 0\n\n cells.forEach((cell, index) => {\n if (cell.classList.toggle('fixed', visible)) {\n isVisible = true\n cell.style[direction] = `${position}px`\n cell.style.zIndex = (index + 1).toString()\n\n position += cell.offsetWidth\n }\n })\n }\n\n action()\n const observer = new ResizeObserver(action)\n\n cells.forEach((cell) => {\n observer.observe(cell)\n })\n\n currentObserver = observer\n }\n\n wrapper.querySelectorAll<HTMLElement>(TR_SELECTOR).forEach((tr) => {\n const leftCells = tr.querySelectorAll<HTMLElement>(FIXED_LEFT_SELECTOR)\n const rightCells = Array.from(\n tr.querySelectorAll<HTMLElement>(FIXED_RIGHT_SELECTOR),\n ).reverse()\n\n if (leftCells.length > 0) {\n commonAction(leftCells, 'left' as const, wrapper.scrollLeft > 0)\n }\n\n if (rightCells.length > 0) {\n commonAction(\n rightCells,\n 'right' as const,\n wrapper.scrollLeft < wrapper.scrollWidth - wrapper.clientWidth - 1,\n )\n }\n })\n\n setShowShadow(isVisible)\n }\n\n handleScroll()\n wrapper.addEventListener('scroll', handleScroll)\n\n const resizeObserver = new ResizeObserver(handleScroll)\n resizeObserver.observe(wrapper)\n\n // HINT: Paginationと組み合わせた際などにテーブル構造の変更を検知して再生成\n const mutationObserver = new MutationObserver(handleScroll)\n mutationObserver.observe(wrapper, {\n childList: true,\n subtree: true,\n })\n\n return () => {\n wrapper.removeEventListener('scroll', handleScroll)\n resizeObserver.unobserve(wrapper)\n mutationObserver.disconnect()\n currentObserver?.disconnect()\n }\n }, [tableWrapperRef])\n\n const classNames = useMemo(() => {\n const { wrapper, inner } = classNameGenerator()\n\n return {\n wrapper: reelShadowClassNameGenerator({ showShadow, className: wrapper({ className }) }),\n inner: inner(),\n }\n }, [showShadow, className])\n\n return (\n <div className={classNames.wrapper}>\n <div {...rest} className={classNames.inner}>\n {children}\n </div>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;AAcA;AACA;AACA;AAEA;AAOA;AACE;AACE;AACA;AACD;AACF;AAEM;;;AAIH;;;;;;;;;;;;;;;;;;;AA6BU;AAEA;;AAEJ;AACF;AAEA;AACA;AAEA;AACE;AACF;;AAGF;;;AAIE;AAIA;;;AAIA;AACE;;AAMJ;;AAGF;AAEA;AACA;AAEA;AACA;;AAGA;AACA;AACE;AACA;AACD;AAED;AACE;AACA;;;AAGF;AACF;AAEA;;;AAII;;;AAGJ;;AASF;;"}
|
|
@@ -21,13 +21,21 @@ const SCROLLER_PROPS = {
|
|
|
21
21
|
// fixedHead のとき、スクロールインスタンスがTableからWrapperに変わるため、Wrapperに対して高さとoverflowを指定する
|
|
22
22
|
className: 'shr-h-[inherit] shr-max-h-[inherit] shr-scroll-pb-0.5',
|
|
23
23
|
};
|
|
24
|
-
const TableScroller = React.forwardRef(({ children, fixedHead, ...rest },
|
|
24
|
+
const TableScroller = React.forwardRef(({ children, fixedHead, ...rest }, ref) => fixedHead ? (jsxRuntime.jsx(FixedHeadTableScroller, { ...rest, ...SCROLLER_PROPS, forwardedRef: ref, children: children })) : (jsxRuntime.jsx(components_Scroller_Scroller.Scroller, { ...rest, ...SCROLLER_PROPS, ref: ref, children: children })));
|
|
25
25
|
const FixedHeadTableScroller = ({ children, forwardedRef, direction, ...rest }) => {
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
26
|
+
// TODO: useMergeRefsが作成されたら修正する
|
|
27
|
+
const callbackRef = React.useCallback((node) => {
|
|
28
|
+
// thead の高さ分だけ scroll-padding-top を設定
|
|
29
|
+
if (node) {
|
|
30
|
+
const thead = node.querySelector('thead');
|
|
31
|
+
if (thead) {
|
|
32
|
+
const { height } = thead.getBoundingClientRect();
|
|
33
|
+
node.style.scrollPaddingTop = `${height + themes_createFontSize.defaultHtmlFontSize}px`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
29
36
|
if (forwardedRef) {
|
|
30
37
|
if (typeof forwardedRef === 'function') {
|
|
38
|
+
// React 19 では callback ref の戻り値を cleanup として使うため、返却する
|
|
31
39
|
forwardedRef(node);
|
|
32
40
|
}
|
|
33
41
|
else {
|
|
@@ -35,17 +43,7 @@ const FixedHeadTableScroller = ({ children, forwardedRef, direction, ...rest })
|
|
|
35
43
|
}
|
|
36
44
|
}
|
|
37
45
|
}, [forwardedRef]);
|
|
38
|
-
|
|
39
|
-
React.useLayoutEffect(() => {
|
|
40
|
-
if (!innerRef.current)
|
|
41
|
-
return;
|
|
42
|
-
const thead = innerRef.current.querySelector('thead');
|
|
43
|
-
if (thead) {
|
|
44
|
-
const { height } = thead.getBoundingClientRect();
|
|
45
|
-
innerRef.current.style.scrollPaddingTop = `${height + themes_createFontSize.defaultHtmlFontSize}px`;
|
|
46
|
-
}
|
|
47
|
-
}, []);
|
|
48
|
-
return (jsxRuntime.jsx(components_Scroller_Scroller.Scroller, { ...rest, ref: setRefs, direction: direction, children: children }));
|
|
46
|
+
return (jsxRuntime.jsx(components_Scroller_Scroller.Scroller, { ...rest, ref: callbackRef, direction: direction, children: children }));
|
|
49
47
|
};
|
|
50
48
|
|
|
51
49
|
exports.TableScroller = TableScroller;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableScroller.cjs","sources":["../../../src/components/Table/TableScroller.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type ForwardedRef,\n type PropsWithChildren,\n forwardRef,\n useCallback,\n
|
|
1
|
+
{"version":3,"file":"TableScroller.cjs","sources":["../../../src/components/Table/TableScroller.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type ForwardedRef,\n type PropsWithChildren,\n forwardRef,\n useCallback,\n} from 'react'\n\nimport { defaultHtmlFontSize } from '../../themes'\nimport { Scroller } from '../Scroller'\n\ntype Props = PropsWithChildren &\n Omit<ComponentPropsWithRef<'div'>, keyof PropsWithChildren> & {\n fixedHead?: boolean\n }\n\nconst SCROLLER_PROPS = {\n direction: 'both' as const,\n // fixedHead のとき、スクロールインスタンスがTableからWrapperに変わるため、Wrapperに対して高さとoverflowを指定する\n className: 'shr-h-[inherit] shr-max-h-[inherit] shr-scroll-pb-0.5',\n}\n\nexport const TableScroller = forwardRef<HTMLDivElement, Props>(\n ({ children, fixedHead, ...rest }, ref: ForwardedRef<HTMLDivElement>) =>\n fixedHead ? (\n <FixedHeadTableScroller {...rest} {...SCROLLER_PROPS} forwardedRef={ref}>\n {children}\n </FixedHeadTableScroller>\n ) : (\n <Scroller {...rest} {...SCROLLER_PROPS} ref={ref}>\n {children}\n </Scroller>\n ),\n)\n\ntype FixedHeadTableScrollerProps = PropsWithChildren &\n Omit<ComponentPropsWithRef<'div'>, keyof PropsWithChildren> & {\n forwardedRef: ForwardedRef<HTMLDivElement>\n direction: 'both'\n }\n\nconst FixedHeadTableScroller = ({\n children,\n forwardedRef,\n direction,\n ...rest\n}: FixedHeadTableScrollerProps) => {\n // TODO: useMergeRefsが作成されたら修正する\n const callbackRef = useCallback(\n (node: HTMLDivElement | null) => {\n // thead の高さ分だけ scroll-padding-top を設定\n if (node) {\n const thead = node.querySelector('thead')\n\n if (thead) {\n const { height } = thead.getBoundingClientRect()\n\n node.style.scrollPaddingTop = `${height + defaultHtmlFontSize}px`\n }\n }\n\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n // React 19 では callback ref の戻り値を cleanup として使うため、返却する\n forwardedRef(node)\n } else {\n forwardedRef.current = node\n }\n }\n },\n [forwardedRef],\n )\n\n return (\n <Scroller {...rest} ref={callbackRef} direction={direction}>\n {children}\n </Scroller>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAkBA;AACE;;AAEA;;AAGK;AAmBP;;AAOE;;;;;;;;;;AAcM;;;;;AAIE;;;AAGN;AAIF;AAKF;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { forwardRef,
|
|
3
|
+
import { forwardRef, useCallback } from 'react';
|
|
4
4
|
import '../../themes/createSpacing.js';
|
|
5
5
|
import { defaultHtmlFontSize } from '../../themes/createFontSize.js';
|
|
6
6
|
import '../../themes/createColor.js';
|
|
@@ -19,13 +19,21 @@ const SCROLLER_PROPS = {
|
|
|
19
19
|
// fixedHead のとき、スクロールインスタンスがTableからWrapperに変わるため、Wrapperに対して高さとoverflowを指定する
|
|
20
20
|
className: 'shr-h-[inherit] shr-max-h-[inherit] shr-scroll-pb-0.5',
|
|
21
21
|
};
|
|
22
|
-
const TableScroller = forwardRef(({ children, fixedHead, ...rest },
|
|
22
|
+
const TableScroller = forwardRef(({ children, fixedHead, ...rest }, ref) => fixedHead ? (jsx(FixedHeadTableScroller, { ...rest, ...SCROLLER_PROPS, forwardedRef: ref, children: children })) : (jsx(Scroller, { ...rest, ...SCROLLER_PROPS, ref: ref, children: children })));
|
|
23
23
|
const FixedHeadTableScroller = ({ children, forwardedRef, direction, ...rest }) => {
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
24
|
+
// TODO: useMergeRefsが作成されたら修正する
|
|
25
|
+
const callbackRef = useCallback((node) => {
|
|
26
|
+
// thead の高さ分だけ scroll-padding-top を設定
|
|
27
|
+
if (node) {
|
|
28
|
+
const thead = node.querySelector('thead');
|
|
29
|
+
if (thead) {
|
|
30
|
+
const { height } = thead.getBoundingClientRect();
|
|
31
|
+
node.style.scrollPaddingTop = `${height + defaultHtmlFontSize}px`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
27
34
|
if (forwardedRef) {
|
|
28
35
|
if (typeof forwardedRef === 'function') {
|
|
36
|
+
// React 19 では callback ref の戻り値を cleanup として使うため、返却する
|
|
29
37
|
forwardedRef(node);
|
|
30
38
|
}
|
|
31
39
|
else {
|
|
@@ -33,17 +41,7 @@ const FixedHeadTableScroller = ({ children, forwardedRef, direction, ...rest })
|
|
|
33
41
|
}
|
|
34
42
|
}
|
|
35
43
|
}, [forwardedRef]);
|
|
36
|
-
|
|
37
|
-
useLayoutEffect(() => {
|
|
38
|
-
if (!innerRef.current)
|
|
39
|
-
return;
|
|
40
|
-
const thead = innerRef.current.querySelector('thead');
|
|
41
|
-
if (thead) {
|
|
42
|
-
const { height } = thead.getBoundingClientRect();
|
|
43
|
-
innerRef.current.style.scrollPaddingTop = `${height + defaultHtmlFontSize}px`;
|
|
44
|
-
}
|
|
45
|
-
}, []);
|
|
46
|
-
return (jsx(Scroller, { ...rest, ref: setRefs, direction: direction, children: children }));
|
|
44
|
+
return (jsx(Scroller, { ...rest, ref: callbackRef, direction: direction, children: children }));
|
|
47
45
|
};
|
|
48
46
|
|
|
49
47
|
export { TableScroller };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableScroller.js","sources":["../../../src/components/Table/TableScroller.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type ForwardedRef,\n type PropsWithChildren,\n forwardRef,\n useCallback,\n
|
|
1
|
+
{"version":3,"file":"TableScroller.js","sources":["../../../src/components/Table/TableScroller.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type ForwardedRef,\n type PropsWithChildren,\n forwardRef,\n useCallback,\n} from 'react'\n\nimport { defaultHtmlFontSize } from '../../themes'\nimport { Scroller } from '../Scroller'\n\ntype Props = PropsWithChildren &\n Omit<ComponentPropsWithRef<'div'>, keyof PropsWithChildren> & {\n fixedHead?: boolean\n }\n\nconst SCROLLER_PROPS = {\n direction: 'both' as const,\n // fixedHead のとき、スクロールインスタンスがTableからWrapperに変わるため、Wrapperに対して高さとoverflowを指定する\n className: 'shr-h-[inherit] shr-max-h-[inherit] shr-scroll-pb-0.5',\n}\n\nexport const TableScroller = forwardRef<HTMLDivElement, Props>(\n ({ children, fixedHead, ...rest }, ref: ForwardedRef<HTMLDivElement>) =>\n fixedHead ? (\n <FixedHeadTableScroller {...rest} {...SCROLLER_PROPS} forwardedRef={ref}>\n {children}\n </FixedHeadTableScroller>\n ) : (\n <Scroller {...rest} {...SCROLLER_PROPS} ref={ref}>\n {children}\n </Scroller>\n ),\n)\n\ntype FixedHeadTableScrollerProps = PropsWithChildren &\n Omit<ComponentPropsWithRef<'div'>, keyof PropsWithChildren> & {\n forwardedRef: ForwardedRef<HTMLDivElement>\n direction: 'both'\n }\n\nconst FixedHeadTableScroller = ({\n children,\n forwardedRef,\n direction,\n ...rest\n}: FixedHeadTableScrollerProps) => {\n // TODO: useMergeRefsが作成されたら修正する\n const callbackRef = useCallback(\n (node: HTMLDivElement | null) => {\n // thead の高さ分だけ scroll-padding-top を設定\n if (node) {\n const thead = node.querySelector('thead')\n\n if (thead) {\n const { height } = thead.getBoundingClientRect()\n\n node.style.scrollPaddingTop = `${height + defaultHtmlFontSize}px`\n }\n }\n\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n // React 19 では callback ref の戻り値を cleanup として使うため、返却する\n forwardedRef(node)\n } else {\n forwardedRef.current = node\n }\n }\n },\n [forwardedRef],\n )\n\n return (\n <Scroller {...rest} ref={callbackRef} direction={direction}>\n {children}\n </Scroller>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAkBA;AACE;;AAEA;;AAGK;AAmBP;;AAOE;;;;;;;;;;AAcM;;;;;AAIE;;;AAGN;AAIF;AAKF;;"}
|