smarthr-ui 99.3.1 → 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/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 +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs.map +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.js +1 -1
- package/lib/components/Combobox/MultiCombobox/MultiCombobox.js.map +1 -1
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs +1 -1
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs.map +1 -1
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.js +1 -1
- package/lib/components/Combobox/SingleCombobox/SingleCombobox.js.map +1 -1
- package/lib/components/DatePicker/DatePicker.cjs +1 -1
- package/lib/components/DatePicker/DatePicker.cjs.map +1 -1
- package/lib/components/DatePicker/DatePicker.js +1 -1
- package/lib/components/DatePicker/DatePicker.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/Input/CurrencyInput/CurrencyInput.cjs +2 -2
- package/lib/components/Input/CurrencyInput/CurrencyInput.cjs.map +1 -1
- package/lib/components/Input/CurrencyInput/CurrencyInput.js +2 -2
- package/lib/components/Input/CurrencyInput/CurrencyInput.js.map +1 -1
- package/lib/components/Input/Input.cjs +14 -16
- package/lib/components/Input/Input.cjs.map +1 -1
- package/lib/components/Input/Input.js +14 -16
- 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/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/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
|
@@ -16,20 +16,18 @@ const backgroundColor = {
|
|
|
16
16
|
BORDER: 'border',
|
|
17
17
|
ACTION_BACKGROUND: 'action-background',
|
|
18
18
|
};
|
|
19
|
-
const
|
|
20
|
-
base: [
|
|
21
|
-
'smarthr-ui-Input',
|
|
22
|
-
'shr-border-shorthand shr-box-border shr-inline-flex shr-cursor-text shr-items-center shr-gap-0.5 shr-rounded-m shr-bg-white shr-px-0.5',
|
|
23
|
-
'contrast-more:shr-border-high-contrast',
|
|
24
|
-
'focus-within:shr-focus-indicator',
|
|
25
|
-
'has-[[aria-invalid]]:shr-border-danger',
|
|
26
|
-
'has-[:disabled]:[&&&]:shr-border-default/50',
|
|
27
|
-
'has-[:disabled]:shr-pointer-events-none has-[:disabled]:shr-bg-white-darken',
|
|
28
|
-
'has-[[readonly]:not(:disabled)]:[&&&]:shr-border-[theme(backgroundColor.column)] has-[[readonly]:not(:disabled)]:[&&&]:shr-bg-column',
|
|
29
|
-
],
|
|
30
|
-
});
|
|
31
|
-
const innerClassNameGenerator = index.tv({
|
|
19
|
+
const classNameGenerator = index.tv({
|
|
32
20
|
slots: {
|
|
21
|
+
wrapper: [
|
|
22
|
+
'smarthr-ui-Input',
|
|
23
|
+
'shr-border-shorthand shr-box-border shr-inline-flex shr-cursor-text shr-items-center shr-gap-0.5 shr-rounded-m shr-bg-white shr-px-0.5',
|
|
24
|
+
'contrast-more:shr-border-high-contrast',
|
|
25
|
+
'focus-within:shr-focus-indicator',
|
|
26
|
+
'has-[[aria-invalid]]:shr-border-danger',
|
|
27
|
+
'has-[:disabled]:[&&&]:shr-border-default/50',
|
|
28
|
+
'has-[:disabled]:shr-pointer-events-none has-[:disabled]:shr-bg-white-darken',
|
|
29
|
+
'has-[[readonly]:not(:disabled)]:[&&&]:shr-border-[theme(backgroundColor.column)] has-[[readonly]:not(:disabled)]:[&&&]:shr-bg-column',
|
|
30
|
+
],
|
|
33
31
|
input: [
|
|
34
32
|
'smarthr-ui-Input-input',
|
|
35
33
|
'shr-inline-block shr-w-full shr-grow shr-border-none shr-bg-transparent shr-py-0.75 shr-text-base shr-leading-none shr-text-black shr-outline-none shr-outline-0',
|
|
@@ -68,9 +66,9 @@ const Input = React.forwardRef(({ onFocus, onBlur, autoFocus, prefix, suffix, cl
|
|
|
68
66
|
handleDelegateClick: () => innerRef.current?.focus(),
|
|
69
67
|
}), [latest]);
|
|
70
68
|
const classNames = React.useMemo(() => {
|
|
71
|
-
const { input, affix } =
|
|
69
|
+
const { wrapper, input, affix } = classNameGenerator();
|
|
72
70
|
return {
|
|
73
|
-
wrapper:
|
|
71
|
+
wrapper: wrapper({ className }),
|
|
74
72
|
input: input(),
|
|
75
73
|
prefix: affix({ className: 'smarthr-ui-Input-prefix' }),
|
|
76
74
|
suffix: affix({ className: 'smarthr-ui-Input-suffix' }),
|
|
@@ -83,7 +81,7 @@ const Input = React.forwardRef(({ onFocus, onBlur, autoFocus, prefix, suffix, cl
|
|
|
83
81
|
backgroundColor: styleColor,
|
|
84
82
|
maxWidth: styleMaxWidth,
|
|
85
83
|
width: styleMaxWidth ? '100%' : undefined,
|
|
86
|
-
}, children: [prefix && jsxRuntime.jsx("span", { className: classNames.prefix, children: prefix }), jsxRuntime.jsx("input", { ...rest, type: type,
|
|
84
|
+
}, children: [prefix && jsxRuntime.jsx("span", { className: classNames.prefix, children: prefix }), jsxRuntime.jsx("input", { ...rest, ref: functions.handleInnerRef, type: type, disabled: disabled, readOnly: readOnly, max: max || (type && DEFAULT_MAX_ATTR[type]) || undefined, "aria-invalid": error || undefined, "data-smarthr-ui-input": "true", onWheel: type === 'number' ? disableWheel : undefined, onFocus: onFocus, onBlur: onBlur, className: classNames.input }), suffix && jsxRuntime.jsx("span", { className: classNames.suffix, children: suffix })] }));
|
|
87
85
|
});
|
|
88
86
|
const disableWheel = (e) => {
|
|
89
87
|
// wheel イベントに preventDefault はないため
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.cjs","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type MutableRefObject,\n type ReactNode,\n type WheelEvent,\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { useTheme } from '../../hooks/useTheme'\n\ntype BaseProps = {\n /** input 要素の `type` 値 */\n type?: HTMLInputElement['type']\n /** フォームにエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** オートフォーカスを行うかどうか */\n autoFocus?: boolean\n /** コンポーネント内の先頭に表示する内容 */\n prefix?: ReactNode\n /** コンポーネント内の末尾に表示する内容 */\n suffix?: ReactNode\n /** 背景色。readOnly を下地の上に載せる場合に使う */\n bgColor?: keyof typeof backgroundColor\n /**\n * @deprecated placeholder属性は非推奨です。別途ヒント用要素を設置するか、それらの領域を確保出来ない場合はTooltipコンポーネントの利用を検討してください。\n */\n placeholder?: string\n}\ntype Props = BaseProps & Omit<ComponentPropsWithRef<'input'>, keyof BaseProps | 'onWheel'>\n\nexport const backgroundColor = {\n BACKGROUND: 'background',\n COLUMN: 'column',\n BASE_GREY: 'base-grey',\n OVER_BACKGROUND: 'over-background',\n HEAD: 'head',\n BORDER: 'border',\n ACTION_BACKGROUND: 'action-background',\n} as const\n\nconst
|
|
1
|
+
{"version":3,"file":"Input.cjs","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type MutableRefObject,\n type ReactNode,\n type WheelEvent,\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { useTheme } from '../../hooks/useTheme'\n\ntype BaseProps = {\n /** input 要素の `type` 値 */\n type?: HTMLInputElement['type']\n /** フォームにエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** オートフォーカスを行うかどうか */\n autoFocus?: boolean\n /** コンポーネント内の先頭に表示する内容 */\n prefix?: ReactNode\n /** コンポーネント内の末尾に表示する内容 */\n suffix?: ReactNode\n /** 背景色。readOnly を下地の上に載せる場合に使う */\n bgColor?: keyof typeof backgroundColor\n /**\n * @deprecated placeholder属性は非推奨です。別途ヒント用要素を設置するか、それらの領域を確保出来ない場合はTooltipコンポーネントの利用を検討してください。\n */\n placeholder?: string\n}\ntype Props = BaseProps & Omit<ComponentPropsWithRef<'input'>, keyof BaseProps | 'onWheel'>\n\nexport const backgroundColor = {\n BACKGROUND: 'background',\n COLUMN: 'column',\n BASE_GREY: 'base-grey',\n OVER_BACKGROUND: 'over-background',\n HEAD: 'head',\n BORDER: 'border',\n ACTION_BACKGROUND: 'action-background',\n} as const\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-Input',\n 'shr-border-shorthand shr-box-border shr-inline-flex shr-cursor-text shr-items-center shr-gap-0.5 shr-rounded-m shr-bg-white shr-px-0.5',\n 'contrast-more:shr-border-high-contrast',\n 'focus-within:shr-focus-indicator',\n 'has-[[aria-invalid]]:shr-border-danger',\n 'has-[:disabled]:[&&&]:shr-border-default/50',\n 'has-[:disabled]:shr-pointer-events-none has-[:disabled]:shr-bg-white-darken',\n 'has-[[readonly]:not(:disabled)]:[&&&]:shr-border-[theme(backgroundColor.column)] has-[[readonly]:not(:disabled)]:[&&&]:shr-bg-column',\n ],\n input: [\n 'smarthr-ui-Input-input',\n 'shr-inline-block shr-w-full shr-grow shr-border-none shr-bg-transparent shr-py-0.75 shr-text-base shr-leading-none shr-text-black shr-outline-none shr-outline-0',\n 'placeholder:shr-text-grey',\n 'disabled:shr-text-disabled disabled:shr-opacity-100',\n 'shr-h-[theme(fontSize.base)]',\n // HINT: 日付系inputがsafariなどで対応されていないため、input要素内が空白になりフォームが潰れる場合がある\n // マジックナンバーになるが、ほかに適切なプロパティがないため、min-widthで最低幅を指定することで防ぐ\n '[&[type=\"datetime-local\"]]:shr-min-w-[11em] [&[type=\"month\"]]:shr-min-w-[8em] [&[type=\"time\"]]:shr-min-w-[5em]',\n ],\n affix: [\n 'shr-flex shr-shrink-0 shr-items-center shr-text-grey',\n '[.smarthr-ui-Input:has(:disabled)_&]:shr-text-disabled [.smarthr-ui-Input:has(:disabled)_&]:shr-opacity-100',\n ],\n },\n})\n\n// HINT: PC版ブラウザで年が6桁入力できる場合、コピー&ペーストが正常に動作しないなど、UI上の問題が発生する場合がある\n// 回避のためmaxで年四桁を指定する\nconst DEFAULT_MAX_ATTR = {\n date: '9999-12-31',\n 'datetime-local': '9999-12-31T23:59',\n month: '9999-12',\n}\n\nexport const Input = forwardRef<HTMLInputElement, Props>(\n (\n {\n onFocus,\n onBlur,\n autoFocus,\n prefix,\n suffix,\n className,\n width,\n disabled,\n error,\n readOnly,\n bgColor,\n type,\n max,\n ...rest\n },\n ref,\n ) => {\n const theme = useTheme()\n const innerRef: MutableRefObject<HTMLInputElement | null> = useRef(null)\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => innerRef.current,\n [],\n )\n\n const latest = useLatest({ autoFocus })\n\n const functions = useMemo(\n () => ({\n handleInnerRef: (node: HTMLInputElement | null) => {\n innerRef.current = node\n\n if (latest.autoFocus && node) {\n node.focus()\n }\n },\n handleDelegateClick: () => innerRef.current?.focus(),\n }),\n [latest],\n )\n\n const classNames = useMemo(() => {\n const { wrapper, input, affix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n input: input(),\n prefix: affix({ className: 'smarthr-ui-Input-prefix' }),\n suffix: affix({ className: 'smarthr-ui-Input-suffix' }),\n }\n }, [className])\n\n const styleColor = bgColor ? theme.backgroundColor[backgroundColor[bgColor]] : undefined\n const styleMaxWidth = typeof width === 'number' ? `${width}px` : width\n\n return (\n <span\n role=\"presentation\"\n onClick={functions.handleDelegateClick}\n className={classNames.wrapper}\n style={{\n borderColor: styleColor,\n backgroundColor: styleColor,\n maxWidth: styleMaxWidth,\n width: styleMaxWidth ? '100%' : undefined,\n }}\n >\n {prefix && <span className={classNames.prefix}>{prefix}</span>}\n <input\n {...rest}\n ref={functions.handleInnerRef}\n type={type}\n disabled={disabled}\n readOnly={readOnly}\n max={\n max || (type && DEFAULT_MAX_ATTR[type as keyof typeof DEFAULT_MAX_ATTR]) || undefined\n }\n aria-invalid={error || undefined}\n data-smarthr-ui-input=\"true\"\n onWheel={type === 'number' ? disableWheel : undefined}\n onFocus={onFocus}\n onBlur={onBlur}\n className={classNames.input}\n />\n {suffix && <span className={classNames.suffix}>{suffix}</span>}\n </span>\n )\n },\n)\n\nconst disableWheel = (e: WheelEvent) => {\n // wheel イベントに preventDefault はないため\n if (e.target) {\n ;(e.target as HTMLInputElement).blur()\n }\n}\n"],"names":[],"mappings":";;;;;;;;;AAuCO;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAGF;AACE;AACE;;;;;;;;;AASC;AACD;;;;;;;;;AASC;AACD;;;AAGC;AACF;AACF;AAED;AACA;AACA;AACE;AACA;AACA;;AAGK;AAoBH;AACA;AAEA;;AAQA;AAEI;AACE;AAEA;;;;;AAKH;AAIH;;;AAII;;;;;AAKJ;AAEA;AACA;AAEA;AAMM;AACA;AACA;;;AAwBR;AAGF;;AAEE;AACI;;AAEN;;;"}
|
|
@@ -14,20 +14,18 @@ const backgroundColor = {
|
|
|
14
14
|
BORDER: 'border',
|
|
15
15
|
ACTION_BACKGROUND: 'action-background',
|
|
16
16
|
};
|
|
17
|
-
const
|
|
18
|
-
base: [
|
|
19
|
-
'smarthr-ui-Input',
|
|
20
|
-
'shr-border-shorthand shr-box-border shr-inline-flex shr-cursor-text shr-items-center shr-gap-0.5 shr-rounded-m shr-bg-white shr-px-0.5',
|
|
21
|
-
'contrast-more:shr-border-high-contrast',
|
|
22
|
-
'focus-within:shr-focus-indicator',
|
|
23
|
-
'has-[[aria-invalid]]:shr-border-danger',
|
|
24
|
-
'has-[:disabled]:[&&&]:shr-border-default/50',
|
|
25
|
-
'has-[:disabled]:shr-pointer-events-none has-[:disabled]:shr-bg-white-darken',
|
|
26
|
-
'has-[[readonly]:not(:disabled)]:[&&&]:shr-border-[theme(backgroundColor.column)] has-[[readonly]:not(:disabled)]:[&&&]:shr-bg-column',
|
|
27
|
-
],
|
|
28
|
-
});
|
|
29
|
-
const innerClassNameGenerator = ce({
|
|
17
|
+
const classNameGenerator = ce({
|
|
30
18
|
slots: {
|
|
19
|
+
wrapper: [
|
|
20
|
+
'smarthr-ui-Input',
|
|
21
|
+
'shr-border-shorthand shr-box-border shr-inline-flex shr-cursor-text shr-items-center shr-gap-0.5 shr-rounded-m shr-bg-white shr-px-0.5',
|
|
22
|
+
'contrast-more:shr-border-high-contrast',
|
|
23
|
+
'focus-within:shr-focus-indicator',
|
|
24
|
+
'has-[[aria-invalid]]:shr-border-danger',
|
|
25
|
+
'has-[:disabled]:[&&&]:shr-border-default/50',
|
|
26
|
+
'has-[:disabled]:shr-pointer-events-none has-[:disabled]:shr-bg-white-darken',
|
|
27
|
+
'has-[[readonly]:not(:disabled)]:[&&&]:shr-border-[theme(backgroundColor.column)] has-[[readonly]:not(:disabled)]:[&&&]:shr-bg-column',
|
|
28
|
+
],
|
|
31
29
|
input: [
|
|
32
30
|
'smarthr-ui-Input-input',
|
|
33
31
|
'shr-inline-block shr-w-full shr-grow shr-border-none shr-bg-transparent shr-py-0.75 shr-text-base shr-leading-none shr-text-black shr-outline-none shr-outline-0',
|
|
@@ -66,9 +64,9 @@ const Input = forwardRef(({ onFocus, onBlur, autoFocus, prefix, suffix, classNam
|
|
|
66
64
|
handleDelegateClick: () => innerRef.current?.focus(),
|
|
67
65
|
}), [latest]);
|
|
68
66
|
const classNames = useMemo(() => {
|
|
69
|
-
const { input, affix } =
|
|
67
|
+
const { wrapper, input, affix } = classNameGenerator();
|
|
70
68
|
return {
|
|
71
|
-
wrapper:
|
|
69
|
+
wrapper: wrapper({ className }),
|
|
72
70
|
input: input(),
|
|
73
71
|
prefix: affix({ className: 'smarthr-ui-Input-prefix' }),
|
|
74
72
|
suffix: affix({ className: 'smarthr-ui-Input-suffix' }),
|
|
@@ -81,7 +79,7 @@ const Input = forwardRef(({ onFocus, onBlur, autoFocus, prefix, suffix, classNam
|
|
|
81
79
|
backgroundColor: styleColor,
|
|
82
80
|
maxWidth: styleMaxWidth,
|
|
83
81
|
width: styleMaxWidth ? '100%' : undefined,
|
|
84
|
-
}, children: [prefix && jsx("span", { className: classNames.prefix, children: prefix }), jsx("input", { ...rest, type: type,
|
|
82
|
+
}, children: [prefix && jsx("span", { className: classNames.prefix, children: prefix }), jsx("input", { ...rest, ref: functions.handleInnerRef, type: type, disabled: disabled, readOnly: readOnly, max: max || (type && DEFAULT_MAX_ATTR[type]) || undefined, "aria-invalid": error || undefined, "data-smarthr-ui-input": "true", onWheel: type === 'number' ? disableWheel : undefined, onFocus: onFocus, onBlur: onBlur, className: classNames.input }), suffix && jsx("span", { className: classNames.suffix, children: suffix })] }));
|
|
85
83
|
});
|
|
86
84
|
const disableWheel = (e) => {
|
|
87
85
|
// wheel イベントに preventDefault はないため
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.js","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type MutableRefObject,\n type ReactNode,\n type WheelEvent,\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { useTheme } from '../../hooks/useTheme'\n\ntype BaseProps = {\n /** input 要素の `type` 値 */\n type?: HTMLInputElement['type']\n /** フォームにエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** オートフォーカスを行うかどうか */\n autoFocus?: boolean\n /** コンポーネント内の先頭に表示する内容 */\n prefix?: ReactNode\n /** コンポーネント内の末尾に表示する内容 */\n suffix?: ReactNode\n /** 背景色。readOnly を下地の上に載せる場合に使う */\n bgColor?: keyof typeof backgroundColor\n /**\n * @deprecated placeholder属性は非推奨です。別途ヒント用要素を設置するか、それらの領域を確保出来ない場合はTooltipコンポーネントの利用を検討してください。\n */\n placeholder?: string\n}\ntype Props = BaseProps & Omit<ComponentPropsWithRef<'input'>, keyof BaseProps | 'onWheel'>\n\nexport const backgroundColor = {\n BACKGROUND: 'background',\n COLUMN: 'column',\n BASE_GREY: 'base-grey',\n OVER_BACKGROUND: 'over-background',\n HEAD: 'head',\n BORDER: 'border',\n ACTION_BACKGROUND: 'action-background',\n} as const\n\nconst
|
|
1
|
+
{"version":3,"file":"Input.js","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentPropsWithRef,\n type MutableRefObject,\n type ReactNode,\n type WheelEvent,\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { useTheme } from '../../hooks/useTheme'\n\ntype BaseProps = {\n /** input 要素の `type` 値 */\n type?: HTMLInputElement['type']\n /** フォームにエラーがあるかどうか */\n error?: boolean\n /** コンポーネントの幅 */\n width?: number | string\n /** オートフォーカスを行うかどうか */\n autoFocus?: boolean\n /** コンポーネント内の先頭に表示する内容 */\n prefix?: ReactNode\n /** コンポーネント内の末尾に表示する内容 */\n suffix?: ReactNode\n /** 背景色。readOnly を下地の上に載せる場合に使う */\n bgColor?: keyof typeof backgroundColor\n /**\n * @deprecated placeholder属性は非推奨です。別途ヒント用要素を設置するか、それらの領域を確保出来ない場合はTooltipコンポーネントの利用を検討してください。\n */\n placeholder?: string\n}\ntype Props = BaseProps & Omit<ComponentPropsWithRef<'input'>, keyof BaseProps | 'onWheel'>\n\nexport const backgroundColor = {\n BACKGROUND: 'background',\n COLUMN: 'column',\n BASE_GREY: 'base-grey',\n OVER_BACKGROUND: 'over-background',\n HEAD: 'head',\n BORDER: 'border',\n ACTION_BACKGROUND: 'action-background',\n} as const\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-Input',\n 'shr-border-shorthand shr-box-border shr-inline-flex shr-cursor-text shr-items-center shr-gap-0.5 shr-rounded-m shr-bg-white shr-px-0.5',\n 'contrast-more:shr-border-high-contrast',\n 'focus-within:shr-focus-indicator',\n 'has-[[aria-invalid]]:shr-border-danger',\n 'has-[:disabled]:[&&&]:shr-border-default/50',\n 'has-[:disabled]:shr-pointer-events-none has-[:disabled]:shr-bg-white-darken',\n 'has-[[readonly]:not(:disabled)]:[&&&]:shr-border-[theme(backgroundColor.column)] has-[[readonly]:not(:disabled)]:[&&&]:shr-bg-column',\n ],\n input: [\n 'smarthr-ui-Input-input',\n 'shr-inline-block shr-w-full shr-grow shr-border-none shr-bg-transparent shr-py-0.75 shr-text-base shr-leading-none shr-text-black shr-outline-none shr-outline-0',\n 'placeholder:shr-text-grey',\n 'disabled:shr-text-disabled disabled:shr-opacity-100',\n 'shr-h-[theme(fontSize.base)]',\n // HINT: 日付系inputがsafariなどで対応されていないため、input要素内が空白になりフォームが潰れる場合がある\n // マジックナンバーになるが、ほかに適切なプロパティがないため、min-widthで最低幅を指定することで防ぐ\n '[&[type=\"datetime-local\"]]:shr-min-w-[11em] [&[type=\"month\"]]:shr-min-w-[8em] [&[type=\"time\"]]:shr-min-w-[5em]',\n ],\n affix: [\n 'shr-flex shr-shrink-0 shr-items-center shr-text-grey',\n '[.smarthr-ui-Input:has(:disabled)_&]:shr-text-disabled [.smarthr-ui-Input:has(:disabled)_&]:shr-opacity-100',\n ],\n },\n})\n\n// HINT: PC版ブラウザで年が6桁入力できる場合、コピー&ペーストが正常に動作しないなど、UI上の問題が発生する場合がある\n// 回避のためmaxで年四桁を指定する\nconst DEFAULT_MAX_ATTR = {\n date: '9999-12-31',\n 'datetime-local': '9999-12-31T23:59',\n month: '9999-12',\n}\n\nexport const Input = forwardRef<HTMLInputElement, Props>(\n (\n {\n onFocus,\n onBlur,\n autoFocus,\n prefix,\n suffix,\n className,\n width,\n disabled,\n error,\n readOnly,\n bgColor,\n type,\n max,\n ...rest\n },\n ref,\n ) => {\n const theme = useTheme()\n const innerRef: MutableRefObject<HTMLInputElement | null> = useRef(null)\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => innerRef.current,\n [],\n )\n\n const latest = useLatest({ autoFocus })\n\n const functions = useMemo(\n () => ({\n handleInnerRef: (node: HTMLInputElement | null) => {\n innerRef.current = node\n\n if (latest.autoFocus && node) {\n node.focus()\n }\n },\n handleDelegateClick: () => innerRef.current?.focus(),\n }),\n [latest],\n )\n\n const classNames = useMemo(() => {\n const { wrapper, input, affix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n input: input(),\n prefix: affix({ className: 'smarthr-ui-Input-prefix' }),\n suffix: affix({ className: 'smarthr-ui-Input-suffix' }),\n }\n }, [className])\n\n const styleColor = bgColor ? theme.backgroundColor[backgroundColor[bgColor]] : undefined\n const styleMaxWidth = typeof width === 'number' ? `${width}px` : width\n\n return (\n <span\n role=\"presentation\"\n onClick={functions.handleDelegateClick}\n className={classNames.wrapper}\n style={{\n borderColor: styleColor,\n backgroundColor: styleColor,\n maxWidth: styleMaxWidth,\n width: styleMaxWidth ? '100%' : undefined,\n }}\n >\n {prefix && <span className={classNames.prefix}>{prefix}</span>}\n <input\n {...rest}\n ref={functions.handleInnerRef}\n type={type}\n disabled={disabled}\n readOnly={readOnly}\n max={\n max || (type && DEFAULT_MAX_ATTR[type as keyof typeof DEFAULT_MAX_ATTR]) || undefined\n }\n aria-invalid={error || undefined}\n data-smarthr-ui-input=\"true\"\n onWheel={type === 'number' ? disableWheel : undefined}\n onFocus={onFocus}\n onBlur={onBlur}\n className={classNames.input}\n />\n {suffix && <span className={classNames.suffix}>{suffix}</span>}\n </span>\n )\n },\n)\n\nconst disableWheel = (e: WheelEvent) => {\n // wheel イベントに preventDefault はないため\n if (e.target) {\n ;(e.target as HTMLInputElement).blur()\n }\n}\n"],"names":[],"mappings":";;;;;;;AAuCO;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;AAGF;AACE;AACE;;;;;;;;;AASC;AACD;;;;;;;;;AASC;AACD;;;AAGC;AACF;AACF;AAED;AACA;AACA;AACE;AACA;AACA;;AAGK;AAoBH;AACA;AAEA;;AAQA;AAEI;AACE;AAEA;;;;;AAKH;AAIH;;;AAII;;;;;AAKJ;AAEA;AACA;AAEA;AAMM;AACA;AACA;;;AAwBR;AAGF;;AAEE;AACI;;AAEN;;"}
|
|
@@ -34,12 +34,13 @@ const InputFileMultiplyAppendable = React.forwardRef(({ className, size, label,
|
|
|
34
34
|
}, [size, className]);
|
|
35
35
|
// Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ
|
|
36
36
|
const isUpdatingFilesRef = React.useRef(false);
|
|
37
|
-
const
|
|
38
|
-
|
|
37
|
+
const innerRef = React.useRef(null);
|
|
38
|
+
// TODO: useMergeRefsが実装されたら修正
|
|
39
|
+
React.useImperativeHandle(ref, () => innerRef.current, []);
|
|
39
40
|
const latest = hooks_useLatest.useLatest({ onChange, files, previewFile });
|
|
40
41
|
const functions = React.useMemo(() => {
|
|
41
42
|
const updateFiles = (newFiles) => {
|
|
42
|
-
if (!
|
|
43
|
+
if (!innerRef.current) {
|
|
43
44
|
return;
|
|
44
45
|
}
|
|
45
46
|
latest.onChange?.(newFiles);
|
|
@@ -48,7 +49,7 @@ const InputFileMultiplyAppendable = React.forwardRef(({ className, size, label,
|
|
|
48
49
|
buff.items.add(file);
|
|
49
50
|
});
|
|
50
51
|
isUpdatingFilesRef.current = true;
|
|
51
|
-
|
|
52
|
+
innerRef.current.files = buff.files;
|
|
52
53
|
isUpdatingFilesRef.current = false;
|
|
53
54
|
setFiles(newFiles);
|
|
54
55
|
};
|
|
@@ -62,13 +63,13 @@ const InputFileMultiplyAppendable = React.forwardRef(({ className, size, label,
|
|
|
62
63
|
updateFiles([...latest.files, ...newFiles]);
|
|
63
64
|
},
|
|
64
65
|
handleDelete: (e) => {
|
|
65
|
-
if (!
|
|
66
|
+
if (!innerRef.current) {
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
68
69
|
const index = parseInt(e.currentTarget.value, 10);
|
|
69
70
|
const newFiles = latest.files.filter((_, i) => index !== i);
|
|
70
71
|
// 削除後、同一ファイルを再選択可能にするためinput.valueをリセット
|
|
71
|
-
|
|
72
|
+
innerRef.current.value = '';
|
|
72
73
|
updateFiles(newFiles);
|
|
73
74
|
},
|
|
74
75
|
handleClosePreview: () => {
|
|
@@ -87,7 +88,7 @@ const InputFileMultiplyAppendable = React.forwardRef(({ className, size, label,
|
|
|
87
88
|
},
|
|
88
89
|
};
|
|
89
90
|
}, [latest]);
|
|
90
|
-
return (jsxRuntime.jsxs(components_Layout_Stack_Stack.Stack, { align: "flex-start", className: classNames.wrapper, children: [hasFileList && !disabled && files.length > 0 && (jsxRuntime.jsx(components_Panel_Groupbox_Groupbox.Groupbox, { as: "ul", padding: BASE_COLUMN_PADDING, className: classNames.fileList, children: files.map((file, index) => (jsxRuntime.jsx(components_InputFile_parts.FileListItem, { file: file, index: index, previewable: !!previewable, handleDeleteClick: functions.handleDelete, handlePreviewClick: setPreviewFile, className: classNames.fileItem }, index))) })), jsxRuntime.jsxs("span", { className: classNames.inputWrapper, children: [jsxRuntime.jsx("input", { ...rest,
|
|
91
|
+
return (jsxRuntime.jsxs(components_Layout_Stack_Stack.Stack, { align: "flex-start", className: classNames.wrapper, children: [hasFileList && !disabled && files.length > 0 && (jsxRuntime.jsx(components_Panel_Groupbox_Groupbox.Groupbox, { as: "ul", padding: BASE_COLUMN_PADDING, className: classNames.fileList, children: files.map((file, index) => (jsxRuntime.jsx(components_InputFile_parts.FileListItem, { file: file, index: index, previewable: !!previewable, handleDeleteClick: functions.handleDelete, handlePreviewClick: setPreviewFile, className: classNames.fileItem }, index))) })), jsxRuntime.jsxs("span", { className: classNames.inputWrapper, children: [jsxRuntime.jsx("input", { ...rest, ref: innerRef, type: "file", disabled: disabled, multiple: true, "aria-invalid": error || undefined, "aria-labelledby": labelId, "data-smarthr-ui-input": "true", onChange: functions.handleChange, className: classNames.input }), jsxRuntime.jsx(components_InputFile_parts.StyledFaFolderOpenIcon, { className: classNames.prefix }), jsxRuntime.jsx(components_InputFile_parts.LabelRender, { id: labelId, label: label })] }), previewable && (jsxRuntime.jsx(components_InputFile_FilePreviewDialog.FilePreviewDialog, { file: previewFile, handleClose: functions.handleClosePreview, handleDownload: functions.handleDownload, searchable: previewable?.searchable }))] }));
|
|
91
92
|
});
|
|
92
93
|
|
|
93
94
|
exports.InputFileMultiplyAppendable = InputFileMultiplyAppendable;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputFileMultiplyAppendable.cjs","sources":["../../../src/components/InputFile/InputFileMultiplyAppendable.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type MouseEvent,\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { Stack } from '../Layout'\nimport { Groupbox } from '../Panel'\n\nimport { FilePreviewDialog } from './FilePreviewDialog'\nimport { FileListItem, LabelRender, StyledFaFolderOpenIcon } from './parts'\nimport { classNameGenerator } from './style'\n\nimport type { LowerProps } from './types'\n\nconst BASE_COLUMN_PADDING = { block: 0.5, inline: 1 } as const\n\nexport const InputFileMultiplyAppendable = forwardRef<\n HTMLInputElement,\n Omit<LowerProps, 'multiple'>\n>(\n (\n { className, size, label, hasFileList = true, previewable, onChange, disabled, error, ...rest },\n ref,\n ) => {\n const [files, setFiles] = useState<File[]>([])\n const [previewFile, setPreviewFile] = useState<File | null>(null)\n const labelId = useId()\n\n const classNames = useMemo(() => {\n const { wrapper, fileList, fileItem, inputWrapper, input, prefix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n inputWrapper: inputWrapper({ size }),\n fileList: fileList(),\n fileItem: fileItem(),\n input: input(),\n prefix: prefix(),\n }\n }, [size, className])\n\n // Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ\n const isUpdatingFilesRef = useRef(false)\n\n const
|
|
1
|
+
{"version":3,"file":"InputFileMultiplyAppendable.cjs","sources":["../../../src/components/InputFile/InputFileMultiplyAppendable.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type MouseEvent,\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { Stack } from '../Layout'\nimport { Groupbox } from '../Panel'\n\nimport { FilePreviewDialog } from './FilePreviewDialog'\nimport { FileListItem, LabelRender, StyledFaFolderOpenIcon } from './parts'\nimport { classNameGenerator } from './style'\n\nimport type { LowerProps } from './types'\n\nconst BASE_COLUMN_PADDING = { block: 0.5, inline: 1 } as const\n\nexport const InputFileMultiplyAppendable = forwardRef<\n HTMLInputElement,\n Omit<LowerProps, 'multiple'>\n>(\n (\n { className, size, label, hasFileList = true, previewable, onChange, disabled, error, ...rest },\n ref,\n ) => {\n const [files, setFiles] = useState<File[]>([])\n const [previewFile, setPreviewFile] = useState<File | null>(null)\n const labelId = useId()\n\n const classNames = useMemo(() => {\n const { wrapper, fileList, fileItem, inputWrapper, input, prefix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n inputWrapper: inputWrapper({ size }),\n fileList: fileList(),\n fileItem: fileItem(),\n input: input(),\n prefix: prefix(),\n }\n }, [size, className])\n\n // Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ\n const isUpdatingFilesRef = useRef(false)\n\n const innerRef = useRef<HTMLInputElement>(null)\n\n // TODO: useMergeRefsが実装されたら修正\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => innerRef.current,\n [],\n )\n\n const latest = useLatest({ onChange, files, previewFile })\n\n const functions = useMemo(() => {\n const updateFiles = (newFiles: File[]) => {\n if (!innerRef.current) {\n return\n }\n\n latest.onChange?.(newFiles)\n\n const buff = new DataTransfer()\n newFiles.forEach((file) => {\n buff.items.add(file)\n })\n\n isUpdatingFilesRef.current = true\n innerRef.current.files = buff.files\n isUpdatingFilesRef.current = false\n\n setFiles(newFiles)\n }\n\n return {\n handleChange: (e: ChangeEvent<HTMLInputElement>) => {\n // Safari において、input.files への直接代入時はonChangeを発火させない\n if (isUpdatingFilesRef.current) {\n return\n }\n\n const newFiles = Array.from(e.target.files ?? [])\n\n updateFiles([...latest.files, ...newFiles])\n },\n handleDelete: (e: MouseEvent<HTMLButtonElement>) => {\n if (!innerRef.current) {\n return\n }\n\n const index = parseInt(e.currentTarget.value, 10)\n const newFiles = latest.files.filter((_, i) => index !== i)\n\n // 削除後、同一ファイルを再選択可能にするためinput.valueをリセット\n innerRef.current.value = ''\n\n updateFiles(newFiles)\n },\n handleClosePreview: () => {\n setPreviewFile(null)\n },\n handleDownload: () => {\n const file = latest.previewFile\n if (!file) return\n\n const url = URL.createObjectURL(file)\n const a = document.createElement('a')\n a.href = url\n a.download = file.name\n a.click()\n URL.revokeObjectURL(url)\n },\n }\n }, [latest])\n\n return (\n <Stack align=\"flex-start\" className={classNames.wrapper}>\n {hasFileList && !disabled && files.length > 0 && (\n <Groupbox as=\"ul\" padding={BASE_COLUMN_PADDING} className={classNames.fileList}>\n {files.map((file, index) => (\n <FileListItem\n key={index}\n file={file}\n index={index}\n previewable={!!previewable}\n handleDeleteClick={functions.handleDelete}\n handlePreviewClick={setPreviewFile}\n className={classNames.fileItem}\n />\n ))}\n </Groupbox>\n )}\n <span className={classNames.inputWrapper}>\n <input\n {...rest}\n ref={innerRef}\n type=\"file\"\n disabled={disabled}\n multiple\n aria-invalid={error || undefined}\n aria-labelledby={labelId}\n data-smarthr-ui-input=\"true\"\n onChange={functions.handleChange}\n className={classNames.input}\n />\n <StyledFaFolderOpenIcon className={classNames.prefix} />\n <LabelRender id={labelId} label={label} />\n </span>\n {previewable && (\n <FilePreviewDialog\n file={previewFile}\n handleClose={functions.handleClosePreview}\n handleDownload={functions.handleDownload}\n searchable={previewable?.searchable}\n />\n )}\n </Stack>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAuBA;AAEO;;;AAUH;AAEA;AACE;;AAGE;AACA;;;;;;AAMJ;;AAGA;AAEA;;AAGA;AAMA;AAEA;AACE;AACE;;;AAIA;AAEA;AACA;AACE;AACF;AAEA;;AAEA;;AAGF;;AAGE;;AAEE;;;AAIA;;;AAIF;AACE;;;AAIA;AACA;;AAGA;;;;;;;AAQA;AACA;;;;AAIA;AACA;;AAEA;;;AAGN;;AA6CF;;"}
|
|
@@ -32,12 +32,13 @@ const InputFileMultiplyAppendable = forwardRef(({ className, size, label, hasFil
|
|
|
32
32
|
}, [size, className]);
|
|
33
33
|
// Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ
|
|
34
34
|
const isUpdatingFilesRef = useRef(false);
|
|
35
|
-
const
|
|
36
|
-
|
|
35
|
+
const innerRef = useRef(null);
|
|
36
|
+
// TODO: useMergeRefsが実装されたら修正
|
|
37
|
+
useImperativeHandle(ref, () => innerRef.current, []);
|
|
37
38
|
const latest = useLatest({ onChange, files, previewFile });
|
|
38
39
|
const functions = useMemo(() => {
|
|
39
40
|
const updateFiles = (newFiles) => {
|
|
40
|
-
if (!
|
|
41
|
+
if (!innerRef.current) {
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
44
|
latest.onChange?.(newFiles);
|
|
@@ -46,7 +47,7 @@ const InputFileMultiplyAppendable = forwardRef(({ className, size, label, hasFil
|
|
|
46
47
|
buff.items.add(file);
|
|
47
48
|
});
|
|
48
49
|
isUpdatingFilesRef.current = true;
|
|
49
|
-
|
|
50
|
+
innerRef.current.files = buff.files;
|
|
50
51
|
isUpdatingFilesRef.current = false;
|
|
51
52
|
setFiles(newFiles);
|
|
52
53
|
};
|
|
@@ -60,13 +61,13 @@ const InputFileMultiplyAppendable = forwardRef(({ className, size, label, hasFil
|
|
|
60
61
|
updateFiles([...latest.files, ...newFiles]);
|
|
61
62
|
},
|
|
62
63
|
handleDelete: (e) => {
|
|
63
|
-
if (!
|
|
64
|
+
if (!innerRef.current) {
|
|
64
65
|
return;
|
|
65
66
|
}
|
|
66
67
|
const index = parseInt(e.currentTarget.value, 10);
|
|
67
68
|
const newFiles = latest.files.filter((_, i) => index !== i);
|
|
68
69
|
// 削除後、同一ファイルを再選択可能にするためinput.valueをリセット
|
|
69
|
-
|
|
70
|
+
innerRef.current.value = '';
|
|
70
71
|
updateFiles(newFiles);
|
|
71
72
|
},
|
|
72
73
|
handleClosePreview: () => {
|
|
@@ -85,7 +86,7 @@ const InputFileMultiplyAppendable = forwardRef(({ className, size, label, hasFil
|
|
|
85
86
|
},
|
|
86
87
|
};
|
|
87
88
|
}, [latest]);
|
|
88
|
-
return (jsxs(Stack, { align: "flex-start", className: classNames.wrapper, children: [hasFileList && !disabled && files.length > 0 && (jsx(Groupbox, { as: "ul", padding: BASE_COLUMN_PADDING, className: classNames.fileList, children: files.map((file, index) => (jsx(FileListItem, { file: file, index: index, previewable: !!previewable, handleDeleteClick: functions.handleDelete, handlePreviewClick: setPreviewFile, className: classNames.fileItem }, index))) })), jsxs("span", { className: classNames.inputWrapper, children: [jsx("input", { ...rest,
|
|
89
|
+
return (jsxs(Stack, { align: "flex-start", className: classNames.wrapper, children: [hasFileList && !disabled && files.length > 0 && (jsx(Groupbox, { as: "ul", padding: BASE_COLUMN_PADDING, className: classNames.fileList, children: files.map((file, index) => (jsx(FileListItem, { file: file, index: index, previewable: !!previewable, handleDeleteClick: functions.handleDelete, handlePreviewClick: setPreviewFile, className: classNames.fileItem }, index))) })), jsxs("span", { className: classNames.inputWrapper, children: [jsx("input", { ...rest, ref: innerRef, type: "file", disabled: disabled, multiple: true, "aria-invalid": error || undefined, "aria-labelledby": labelId, "data-smarthr-ui-input": "true", onChange: functions.handleChange, className: classNames.input }), jsx(StyledFaFolderOpenIcon, { className: classNames.prefix }), jsx(LabelRender, { id: labelId, label: label })] }), previewable && (jsx(FilePreviewDialog, { file: previewFile, handleClose: functions.handleClosePreview, handleDownload: functions.handleDownload, searchable: previewable?.searchable }))] }));
|
|
89
90
|
});
|
|
90
91
|
|
|
91
92
|
export { InputFileMultiplyAppendable };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputFileMultiplyAppendable.js","sources":["../../../src/components/InputFile/InputFileMultiplyAppendable.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type MouseEvent,\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { Stack } from '../Layout'\nimport { Groupbox } from '../Panel'\n\nimport { FilePreviewDialog } from './FilePreviewDialog'\nimport { FileListItem, LabelRender, StyledFaFolderOpenIcon } from './parts'\nimport { classNameGenerator } from './style'\n\nimport type { LowerProps } from './types'\n\nconst BASE_COLUMN_PADDING = { block: 0.5, inline: 1 } as const\n\nexport const InputFileMultiplyAppendable = forwardRef<\n HTMLInputElement,\n Omit<LowerProps, 'multiple'>\n>(\n (\n { className, size, label, hasFileList = true, previewable, onChange, disabled, error, ...rest },\n ref,\n ) => {\n const [files, setFiles] = useState<File[]>([])\n const [previewFile, setPreviewFile] = useState<File | null>(null)\n const labelId = useId()\n\n const classNames = useMemo(() => {\n const { wrapper, fileList, fileItem, inputWrapper, input, prefix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n inputWrapper: inputWrapper({ size }),\n fileList: fileList(),\n fileItem: fileItem(),\n input: input(),\n prefix: prefix(),\n }\n }, [size, className])\n\n // Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ\n const isUpdatingFilesRef = useRef(false)\n\n const
|
|
1
|
+
{"version":3,"file":"InputFileMultiplyAppendable.js","sources":["../../../src/components/InputFile/InputFileMultiplyAppendable.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type MouseEvent,\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { Stack } from '../Layout'\nimport { Groupbox } from '../Panel'\n\nimport { FilePreviewDialog } from './FilePreviewDialog'\nimport { FileListItem, LabelRender, StyledFaFolderOpenIcon } from './parts'\nimport { classNameGenerator } from './style'\n\nimport type { LowerProps } from './types'\n\nconst BASE_COLUMN_PADDING = { block: 0.5, inline: 1 } as const\n\nexport const InputFileMultiplyAppendable = forwardRef<\n HTMLInputElement,\n Omit<LowerProps, 'multiple'>\n>(\n (\n { className, size, label, hasFileList = true, previewable, onChange, disabled, error, ...rest },\n ref,\n ) => {\n const [files, setFiles] = useState<File[]>([])\n const [previewFile, setPreviewFile] = useState<File | null>(null)\n const labelId = useId()\n\n const classNames = useMemo(() => {\n const { wrapper, fileList, fileItem, inputWrapper, input, prefix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n inputWrapper: inputWrapper({ size }),\n fileList: fileList(),\n fileItem: fileItem(),\n input: input(),\n prefix: prefix(),\n }\n }, [size, className])\n\n // Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ\n const isUpdatingFilesRef = useRef(false)\n\n const innerRef = useRef<HTMLInputElement>(null)\n\n // TODO: useMergeRefsが実装されたら修正\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => innerRef.current,\n [],\n )\n\n const latest = useLatest({ onChange, files, previewFile })\n\n const functions = useMemo(() => {\n const updateFiles = (newFiles: File[]) => {\n if (!innerRef.current) {\n return\n }\n\n latest.onChange?.(newFiles)\n\n const buff = new DataTransfer()\n newFiles.forEach((file) => {\n buff.items.add(file)\n })\n\n isUpdatingFilesRef.current = true\n innerRef.current.files = buff.files\n isUpdatingFilesRef.current = false\n\n setFiles(newFiles)\n }\n\n return {\n handleChange: (e: ChangeEvent<HTMLInputElement>) => {\n // Safari において、input.files への直接代入時はonChangeを発火させない\n if (isUpdatingFilesRef.current) {\n return\n }\n\n const newFiles = Array.from(e.target.files ?? [])\n\n updateFiles([...latest.files, ...newFiles])\n },\n handleDelete: (e: MouseEvent<HTMLButtonElement>) => {\n if (!innerRef.current) {\n return\n }\n\n const index = parseInt(e.currentTarget.value, 10)\n const newFiles = latest.files.filter((_, i) => index !== i)\n\n // 削除後、同一ファイルを再選択可能にするためinput.valueをリセット\n innerRef.current.value = ''\n\n updateFiles(newFiles)\n },\n handleClosePreview: () => {\n setPreviewFile(null)\n },\n handleDownload: () => {\n const file = latest.previewFile\n if (!file) return\n\n const url = URL.createObjectURL(file)\n const a = document.createElement('a')\n a.href = url\n a.download = file.name\n a.click()\n URL.revokeObjectURL(url)\n },\n }\n }, [latest])\n\n return (\n <Stack align=\"flex-start\" className={classNames.wrapper}>\n {hasFileList && !disabled && files.length > 0 && (\n <Groupbox as=\"ul\" padding={BASE_COLUMN_PADDING} className={classNames.fileList}>\n {files.map((file, index) => (\n <FileListItem\n key={index}\n file={file}\n index={index}\n previewable={!!previewable}\n handleDeleteClick={functions.handleDelete}\n handlePreviewClick={setPreviewFile}\n className={classNames.fileItem}\n />\n ))}\n </Groupbox>\n )}\n <span className={classNames.inputWrapper}>\n <input\n {...rest}\n ref={innerRef}\n type=\"file\"\n disabled={disabled}\n multiple\n aria-invalid={error || undefined}\n aria-labelledby={labelId}\n data-smarthr-ui-input=\"true\"\n onChange={functions.handleChange}\n className={classNames.input}\n />\n <StyledFaFolderOpenIcon className={classNames.prefix} />\n <LabelRender id={labelId} label={label} />\n </span>\n {previewable && (\n <FilePreviewDialog\n file={previewFile}\n handleClose={functions.handleClosePreview}\n handleDownload={functions.handleDownload}\n searchable={previewable?.searchable}\n />\n )}\n </Stack>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAuBA;AAEO;;;AAUH;AAEA;AACE;;AAGE;AACA;;;;;;AAMJ;;AAGA;AAEA;;AAGA;AAMA;AAEA;AACE;AACE;;;AAIA;AAEA;AACA;AACE;AACF;AAEA;;AAEA;;AAGF;;AAGE;;AAEE;;;AAIA;;;AAIF;AACE;;;AAIA;AACA;;AAGA;;;;;;;AAQA;AACA;;;;AAIA;AACA;;AAEA;;;AAGN;;AA6CF;;"}
|
|
@@ -34,8 +34,9 @@ const InputFileNative = React.forwardRef(({ className, size, label, hasFileList
|
|
|
34
34
|
}, [size, className]);
|
|
35
35
|
// Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ
|
|
36
36
|
const isUpdatingFilesRef = React.useRef(false);
|
|
37
|
-
const
|
|
38
|
-
|
|
37
|
+
const innerRef = React.useRef(null);
|
|
38
|
+
// TODO: useMergeRefsが実装されたら修正
|
|
39
|
+
React.useImperativeHandle(ref, () => innerRef.current, []);
|
|
39
40
|
const latest = hooks_useLatest.useLatest({ onChange, files, previewFile });
|
|
40
41
|
const functions = React.useMemo(() => {
|
|
41
42
|
const updateFiles = (newFiles) => {
|
|
@@ -49,7 +50,7 @@ const InputFileNative = React.forwardRef(({ className, size, label, hasFileList
|
|
|
49
50
|
}
|
|
50
51
|
},
|
|
51
52
|
handleDelete: (e) => {
|
|
52
|
-
if (!
|
|
53
|
+
if (!innerRef.current) {
|
|
53
54
|
return;
|
|
54
55
|
}
|
|
55
56
|
const index = parseInt(e.currentTarget.value, 10);
|
|
@@ -60,7 +61,7 @@ const InputFileNative = React.forwardRef(({ className, size, label, hasFileList
|
|
|
60
61
|
buff.items.add(file);
|
|
61
62
|
});
|
|
62
63
|
isUpdatingFilesRef.current = true;
|
|
63
|
-
|
|
64
|
+
innerRef.current.files = buff.files;
|
|
64
65
|
isUpdatingFilesRef.current = false;
|
|
65
66
|
},
|
|
66
67
|
handleClosePreview: () => {
|
|
@@ -79,7 +80,7 @@ const InputFileNative = React.forwardRef(({ className, size, label, hasFileList
|
|
|
79
80
|
},
|
|
80
81
|
};
|
|
81
82
|
}, [latest]);
|
|
82
|
-
return (jsxRuntime.jsxs(components_Layout_Stack_Stack.Stack, { align: "flex-start", className: classNames.wrapper, children: [hasFileList && !disabled && files.length > 0 && (jsxRuntime.jsx(components_Panel_Groupbox_Groupbox.Groupbox, { as: "ul", padding: BASE_COLUMN_PADDING, className: classNames.fileList, children: files.map((file, index) => (jsxRuntime.jsx(components_InputFile_parts.FileListItem, { file: file, index: index, previewable: !!previewable, handleDeleteClick: functions.handleDelete, handlePreviewClick: setPreviewFile, className: classNames.fileItem }, index))) })), jsxRuntime.jsxs("span", { className: classNames.inputWrapper, children: [jsxRuntime.jsx("input", { ...rest,
|
|
83
|
+
return (jsxRuntime.jsxs(components_Layout_Stack_Stack.Stack, { align: "flex-start", className: classNames.wrapper, children: [hasFileList && !disabled && files.length > 0 && (jsxRuntime.jsx(components_Panel_Groupbox_Groupbox.Groupbox, { as: "ul", padding: BASE_COLUMN_PADDING, className: classNames.fileList, children: files.map((file, index) => (jsxRuntime.jsx(components_InputFile_parts.FileListItem, { file: file, index: index, previewable: !!previewable, handleDeleteClick: functions.handleDelete, handlePreviewClick: setPreviewFile, className: classNames.fileItem }, index))) })), jsxRuntime.jsxs("span", { className: classNames.inputWrapper, children: [jsxRuntime.jsx("input", { ...rest, ref: innerRef, type: "file", disabled: disabled, "aria-invalid": error || undefined, "aria-labelledby": labelId, "data-smarthr-ui-input": "true", onChange: functions.handleChange, className: classNames.input }), jsxRuntime.jsx(components_InputFile_parts.StyledFaFolderOpenIcon, { className: classNames.prefix }), jsxRuntime.jsx(components_InputFile_parts.LabelRender, { id: labelId, label: label })] }), previewable && (jsxRuntime.jsx(components_InputFile_FilePreviewDialog.FilePreviewDialog, { file: previewFile, handleClose: functions.handleClosePreview, handleDownload: functions.handleDownload, searchable: previewable?.searchable }))] }));
|
|
83
84
|
});
|
|
84
85
|
|
|
85
86
|
exports.InputFileNative = InputFileNative;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputFileNative.cjs","sources":["../../../src/components/InputFile/InputFileNative.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type MouseEvent,\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { Stack } from '../Layout'\nimport { Groupbox } from '../Panel'\n\nimport { FilePreviewDialog } from './FilePreviewDialog'\nimport { FileListItem, LabelRender, StyledFaFolderOpenIcon } from './parts'\nimport { classNameGenerator } from './style'\n\nimport type { LowerProps } from './types'\n\nconst BASE_COLUMN_PADDING = { block: 0.5, inline: 1 } as const\n\ntype Props = Omit<LowerProps, 'multiple'> & {\n multiple?: boolean\n}\n\nexport const InputFileNative = forwardRef<HTMLInputElement, Props>(\n (\n { className, size, label, hasFileList = true, previewable, onChange, disabled, error, ...rest },\n ref,\n ) => {\n const [files, setFiles] = useState<File[]>([])\n const [previewFile, setPreviewFile] = useState<File | null>(null)\n const labelId = useId()\n\n const classNames = useMemo(() => {\n const { wrapper, fileList, fileItem, inputWrapper, input, prefix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n inputWrapper: inputWrapper({ size }),\n fileList: fileList(),\n fileItem: fileItem(),\n input: input(),\n prefix: prefix(),\n }\n }, [size, className])\n\n // Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ\n const isUpdatingFilesRef = useRef(false)\n\n const
|
|
1
|
+
{"version":3,"file":"InputFileNative.cjs","sources":["../../../src/components/InputFile/InputFileNative.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type MouseEvent,\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { Stack } from '../Layout'\nimport { Groupbox } from '../Panel'\n\nimport { FilePreviewDialog } from './FilePreviewDialog'\nimport { FileListItem, LabelRender, StyledFaFolderOpenIcon } from './parts'\nimport { classNameGenerator } from './style'\n\nimport type { LowerProps } from './types'\n\nconst BASE_COLUMN_PADDING = { block: 0.5, inline: 1 } as const\n\ntype Props = Omit<LowerProps, 'multiple'> & {\n multiple?: boolean\n}\n\nexport const InputFileNative = forwardRef<HTMLInputElement, Props>(\n (\n { className, size, label, hasFileList = true, previewable, onChange, disabled, error, ...rest },\n ref,\n ) => {\n const [files, setFiles] = useState<File[]>([])\n const [previewFile, setPreviewFile] = useState<File | null>(null)\n const labelId = useId()\n\n const classNames = useMemo(() => {\n const { wrapper, fileList, fileItem, inputWrapper, input, prefix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n inputWrapper: inputWrapper({ size }),\n fileList: fileList(),\n fileItem: fileItem(),\n input: input(),\n prefix: prefix(),\n }\n }, [size, className])\n\n // Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ\n const isUpdatingFilesRef = useRef(false)\n\n const innerRef = useRef<HTMLInputElement>(null)\n\n // TODO: useMergeRefsが実装されたら修正\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => innerRef.current,\n [],\n )\n\n const latest = useLatest({ onChange, files, previewFile })\n\n const functions = useMemo(() => {\n const updateFiles = (newFiles: File[]) => {\n latest.onChange?.(newFiles)\n setFiles(newFiles)\n }\n\n return {\n handleChange: (e: ChangeEvent<HTMLInputElement>) => {\n if (!isUpdatingFilesRef.current) {\n updateFiles(Array.from(e.target.files ?? []))\n }\n },\n handleDelete: (e: MouseEvent<HTMLButtonElement>) => {\n if (!innerRef.current) {\n return\n }\n\n const index = parseInt(e.currentTarget.value, 10)\n const newFiles = latest.files.filter((_, i) => index !== i)\n\n updateFiles(newFiles)\n\n const buff = new DataTransfer()\n\n newFiles.forEach((file) => {\n buff.items.add(file)\n })\n\n isUpdatingFilesRef.current = true\n innerRef.current.files = buff.files\n isUpdatingFilesRef.current = false\n },\n handleClosePreview: () => {\n setPreviewFile(null)\n },\n handleDownload: () => {\n const file = latest.previewFile\n if (!file) return\n\n const url = URL.createObjectURL(file)\n const a = document.createElement('a')\n a.href = url\n a.download = file.name\n a.click()\n URL.revokeObjectURL(url)\n },\n }\n }, [latest])\n\n return (\n <Stack align=\"flex-start\" className={classNames.wrapper}>\n {hasFileList && !disabled && files.length > 0 && (\n <Groupbox as=\"ul\" padding={BASE_COLUMN_PADDING} className={classNames.fileList}>\n {files.map((file, index) => (\n <FileListItem\n key={index}\n file={file}\n index={index}\n previewable={!!previewable}\n handleDeleteClick={functions.handleDelete}\n handlePreviewClick={setPreviewFile}\n className={classNames.fileItem}\n />\n ))}\n </Groupbox>\n )}\n <span className={classNames.inputWrapper}>\n <input\n {...rest}\n ref={innerRef}\n type=\"file\"\n disabled={disabled}\n aria-invalid={error || undefined}\n aria-labelledby={labelId}\n data-smarthr-ui-input=\"true\"\n onChange={functions.handleChange}\n className={classNames.input}\n />\n <StyledFaFolderOpenIcon className={classNames.prefix} />\n <LabelRender id={labelId} label={label} />\n </span>\n {previewable && (\n <FilePreviewDialog\n file={previewFile}\n handleClose={functions.handleClosePreview}\n handleDownload={functions.handleDownload}\n searchable={previewable?.searchable}\n />\n )}\n </Stack>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAuBA;AAMO;;;AAOH;AAEA;AACE;;AAGE;AACA;;;;;;AAMJ;;AAGA;AAEA;;AAGA;AAMA;AAEA;AACE;AACE;;AAEF;;AAGE;AACE;AACE;;;AAGJ;AACE;;;AAIA;AACA;;AAIA;AAEA;AACE;AACF;AAEA;;AAEA;;;;;;AAMA;AACA;;;;AAIA;AACA;;AAEA;;;AAGN;;AA4CF;;"}
|
|
@@ -32,8 +32,9 @@ const InputFileNative = forwardRef(({ className, size, label, hasFileList = true
|
|
|
32
32
|
}, [size, className]);
|
|
33
33
|
// Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ
|
|
34
34
|
const isUpdatingFilesRef = useRef(false);
|
|
35
|
-
const
|
|
36
|
-
|
|
35
|
+
const innerRef = useRef(null);
|
|
36
|
+
// TODO: useMergeRefsが実装されたら修正
|
|
37
|
+
useImperativeHandle(ref, () => innerRef.current, []);
|
|
37
38
|
const latest = useLatest({ onChange, files, previewFile });
|
|
38
39
|
const functions = useMemo(() => {
|
|
39
40
|
const updateFiles = (newFiles) => {
|
|
@@ -47,7 +48,7 @@ const InputFileNative = forwardRef(({ className, size, label, hasFileList = true
|
|
|
47
48
|
}
|
|
48
49
|
},
|
|
49
50
|
handleDelete: (e) => {
|
|
50
|
-
if (!
|
|
51
|
+
if (!innerRef.current) {
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
const index = parseInt(e.currentTarget.value, 10);
|
|
@@ -58,7 +59,7 @@ const InputFileNative = forwardRef(({ className, size, label, hasFileList = true
|
|
|
58
59
|
buff.items.add(file);
|
|
59
60
|
});
|
|
60
61
|
isUpdatingFilesRef.current = true;
|
|
61
|
-
|
|
62
|
+
innerRef.current.files = buff.files;
|
|
62
63
|
isUpdatingFilesRef.current = false;
|
|
63
64
|
},
|
|
64
65
|
handleClosePreview: () => {
|
|
@@ -77,7 +78,7 @@ const InputFileNative = forwardRef(({ className, size, label, hasFileList = true
|
|
|
77
78
|
},
|
|
78
79
|
};
|
|
79
80
|
}, [latest]);
|
|
80
|
-
return (jsxs(Stack, { align: "flex-start", className: classNames.wrapper, children: [hasFileList && !disabled && files.length > 0 && (jsx(Groupbox, { as: "ul", padding: BASE_COLUMN_PADDING, className: classNames.fileList, children: files.map((file, index) => (jsx(FileListItem, { file: file, index: index, previewable: !!previewable, handleDeleteClick: functions.handleDelete, handlePreviewClick: setPreviewFile, className: classNames.fileItem }, index))) })), jsxs("span", { className: classNames.inputWrapper, children: [jsx("input", { ...rest,
|
|
81
|
+
return (jsxs(Stack, { align: "flex-start", className: classNames.wrapper, children: [hasFileList && !disabled && files.length > 0 && (jsx(Groupbox, { as: "ul", padding: BASE_COLUMN_PADDING, className: classNames.fileList, children: files.map((file, index) => (jsx(FileListItem, { file: file, index: index, previewable: !!previewable, handleDeleteClick: functions.handleDelete, handlePreviewClick: setPreviewFile, className: classNames.fileItem }, index))) })), jsxs("span", { className: classNames.inputWrapper, children: [jsx("input", { ...rest, ref: innerRef, type: "file", disabled: disabled, "aria-invalid": error || undefined, "aria-labelledby": labelId, "data-smarthr-ui-input": "true", onChange: functions.handleChange, className: classNames.input }), jsx(StyledFaFolderOpenIcon, { className: classNames.prefix }), jsx(LabelRender, { id: labelId, label: label })] }), previewable && (jsx(FilePreviewDialog, { file: previewFile, handleClose: functions.handleClosePreview, handleDownload: functions.handleDownload, searchable: previewable?.searchable }))] }));
|
|
81
82
|
});
|
|
82
83
|
|
|
83
84
|
export { InputFileNative };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputFileNative.js","sources":["../../../src/components/InputFile/InputFileNative.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type MouseEvent,\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { Stack } from '../Layout'\nimport { Groupbox } from '../Panel'\n\nimport { FilePreviewDialog } from './FilePreviewDialog'\nimport { FileListItem, LabelRender, StyledFaFolderOpenIcon } from './parts'\nimport { classNameGenerator } from './style'\n\nimport type { LowerProps } from './types'\n\nconst BASE_COLUMN_PADDING = { block: 0.5, inline: 1 } as const\n\ntype Props = Omit<LowerProps, 'multiple'> & {\n multiple?: boolean\n}\n\nexport const InputFileNative = forwardRef<HTMLInputElement, Props>(\n (\n { className, size, label, hasFileList = true, previewable, onChange, disabled, error, ...rest },\n ref,\n ) => {\n const [files, setFiles] = useState<File[]>([])\n const [previewFile, setPreviewFile] = useState<File | null>(null)\n const labelId = useId()\n\n const classNames = useMemo(() => {\n const { wrapper, fileList, fileItem, inputWrapper, input, prefix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n inputWrapper: inputWrapper({ size }),\n fileList: fileList(),\n fileItem: fileItem(),\n input: input(),\n prefix: prefix(),\n }\n }, [size, className])\n\n // Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ\n const isUpdatingFilesRef = useRef(false)\n\n const
|
|
1
|
+
{"version":3,"file":"InputFileNative.js","sources":["../../../src/components/InputFile/InputFileNative.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type MouseEvent,\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { Stack } from '../Layout'\nimport { Groupbox } from '../Panel'\n\nimport { FilePreviewDialog } from './FilePreviewDialog'\nimport { FileListItem, LabelRender, StyledFaFolderOpenIcon } from './parts'\nimport { classNameGenerator } from './style'\n\nimport type { LowerProps } from './types'\n\nconst BASE_COLUMN_PADDING = { block: 0.5, inline: 1 } as const\n\ntype Props = Omit<LowerProps, 'multiple'> & {\n multiple?: boolean\n}\n\nexport const InputFileNative = forwardRef<HTMLInputElement, Props>(\n (\n { className, size, label, hasFileList = true, previewable, onChange, disabled, error, ...rest },\n ref,\n ) => {\n const [files, setFiles] = useState<File[]>([])\n const [previewFile, setPreviewFile] = useState<File | null>(null)\n const labelId = useId()\n\n const classNames = useMemo(() => {\n const { wrapper, fileList, fileItem, inputWrapper, input, prefix } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n inputWrapper: inputWrapper({ size }),\n fileList: fileList(),\n fileItem: fileItem(),\n input: input(),\n prefix: prefix(),\n }\n }, [size, className])\n\n // Safari において、input.files への直接代入時に onChange が発火することを防ぐためのフラグ\n const isUpdatingFilesRef = useRef(false)\n\n const innerRef = useRef<HTMLInputElement>(null)\n\n // TODO: useMergeRefsが実装されたら修正\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(\n ref,\n () => innerRef.current,\n [],\n )\n\n const latest = useLatest({ onChange, files, previewFile })\n\n const functions = useMemo(() => {\n const updateFiles = (newFiles: File[]) => {\n latest.onChange?.(newFiles)\n setFiles(newFiles)\n }\n\n return {\n handleChange: (e: ChangeEvent<HTMLInputElement>) => {\n if (!isUpdatingFilesRef.current) {\n updateFiles(Array.from(e.target.files ?? []))\n }\n },\n handleDelete: (e: MouseEvent<HTMLButtonElement>) => {\n if (!innerRef.current) {\n return\n }\n\n const index = parseInt(e.currentTarget.value, 10)\n const newFiles = latest.files.filter((_, i) => index !== i)\n\n updateFiles(newFiles)\n\n const buff = new DataTransfer()\n\n newFiles.forEach((file) => {\n buff.items.add(file)\n })\n\n isUpdatingFilesRef.current = true\n innerRef.current.files = buff.files\n isUpdatingFilesRef.current = false\n },\n handleClosePreview: () => {\n setPreviewFile(null)\n },\n handleDownload: () => {\n const file = latest.previewFile\n if (!file) return\n\n const url = URL.createObjectURL(file)\n const a = document.createElement('a')\n a.href = url\n a.download = file.name\n a.click()\n URL.revokeObjectURL(url)\n },\n }\n }, [latest])\n\n return (\n <Stack align=\"flex-start\" className={classNames.wrapper}>\n {hasFileList && !disabled && files.length > 0 && (\n <Groupbox as=\"ul\" padding={BASE_COLUMN_PADDING} className={classNames.fileList}>\n {files.map((file, index) => (\n <FileListItem\n key={index}\n file={file}\n index={index}\n previewable={!!previewable}\n handleDeleteClick={functions.handleDelete}\n handlePreviewClick={setPreviewFile}\n className={classNames.fileItem}\n />\n ))}\n </Groupbox>\n )}\n <span className={classNames.inputWrapper}>\n <input\n {...rest}\n ref={innerRef}\n type=\"file\"\n disabled={disabled}\n aria-invalid={error || undefined}\n aria-labelledby={labelId}\n data-smarthr-ui-input=\"true\"\n onChange={functions.handleChange}\n className={classNames.input}\n />\n <StyledFaFolderOpenIcon className={classNames.prefix} />\n <LabelRender id={labelId} label={label} />\n </span>\n {previewable && (\n <FilePreviewDialog\n file={previewFile}\n handleClose={functions.handleClosePreview}\n handleDownload={functions.handleDownload}\n searchable={previewable?.searchable}\n />\n )}\n </Stack>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAuBA;AAMO;;;AAOH;AAEA;AACE;;AAGE;AACA;;;;;;AAMJ;;AAGA;AAEA;;AAGA;AAMA;AAEA;AACE;AACE;;AAEF;;AAGE;AACE;AACE;;;AAGJ;AACE;;;AAIA;AACA;;AAIA;AAEA;AACE;AACF;AAEA;;AAEA;;;;;;AAMA;AACA;;;;AAIA;AACA;;AAEA;;;AAGN;;AA4CF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Container.cjs","sources":["../../../../src/components/Layout/Container/Container.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, type FC, type PropsWithChildren, useMemo } from 'react'\nimport { type VariantProps, tv } from 'tailwind-variants'\n\nimport { useEnvironment } from '../../../hooks/useEnvironment'\nimport { paddingBlock, paddingInline } from '../../../tailwind'\n\nimport type { Gap } from '../../../types'\n\ntype BaseProps = PropsWithChildren<\n Omit<VariantProps<typeof classNameGenerator>, 'paddingBlock' | 'paddingInline'> & {\n padding?: Gap | SeparatePadding\n }\n>\ntype Props = BaseProps & Omit<ComponentProps<'div'>, keyof BaseProps>\n\ntype SeparatePadding = {\n block?: Gap\n inline?: Gap\n /** 画面幅が狭い時のブロック方向パディング */\n narrowModeBlock?: Gap\n /** 画面幅が狭い時のインライン方向パディング */\n narrowModeInline?: Gap\n}\n\nconst classNameGenerator = tv({\n base: 'shr-mx-auto shr-w-full',\n variants: {\n size: {\n NARROW: 'shr-max-w-col6',\n DEFAULT: 'shr-max-w-col8',\n WIDE: 'shr-max-w-col9',\n FULL: '',\n },\n paddingBlock,\n paddingInline,\n },\n compoundVariants: [\n {\n paddingInline: [0.25, 'X3S'],\n className: 'shr-w-[calc(100%-theme(spacing[0.25])*2)]',\n },\n {\n paddingInline: [0.5, 'XXS'],\n className: 'shr-w-[calc(100%-theme(spacing[0.5])*2)]',\n },\n {\n paddingInline: 0.75,\n className: 'shr-w-[calc(100%-theme(spacing[0.75])*2)]',\n },\n {\n paddingInline: [1, 'XS'],\n className: 'shr-w-[calc(100%-theme(spacing[1])*2)]',\n },\n {\n paddingInline: 1.25,\n className: 'shr-w-[calc(100%-theme(spacing[1.25])*2)]',\n },\n {\n paddingInline: [1.5, 'S'],\n className: 'shr-w-[calc(100%-theme(spacing[1.5])*2)]',\n },\n {\n paddingInline: [2, 'M'],\n className: 'shr-w-[calc(100%-theme(spacing[2])*2)]',\n },\n {\n paddingInline: [2.5, 'L'],\n className: 'shr-w-[calc(100%-theme(spacing[2.5])*2)]',\n },\n {\n paddingInline: [3, 'XL'],\n className: 'shr-w-[calc(100%-theme(spacing[3])*2)]',\n },\n {\n paddingInline: [3.5, 'XXL'],\n className: 'shr-w-[calc(100%-theme(spacing[3.5])*2)]',\n },\n {\n paddingInline: [4, 'X3L'],\n className: 'shr-w-[calc(100%-theme(spacing[4])*2)]',\n },\n {\n paddingInline: 8,\n className: 'shr-w-[calc(100%-theme(spacing[8])*2)]',\n },\n ],\n})\n\nconst DEFAULT_PADDING = {\n block: 2,\n inline: 2,\n narrowModeBlock: 1.5,\n narrowModeInline: 1,\n} as const\n\nexport const Container: FC<Props> = ({\n size = 'DEFAULT',\n padding = DEFAULT_PADDING,\n className,\n ...rest\n}) => {\n const { mobile } = useEnvironment()\n const actualClassName = useMemo(() => {\n const actualPadding =\n padding instanceof Object\n ? padding\n : { block: padding, inline: padding, narrowModeBlock: padding, narrowModeInline: padding }\n return classNameGenerator({\n size,\n paddingBlock: mobile ? actualPadding.narrowModeBlock : actualPadding.block,\n paddingInline: mobile ? actualPadding.narrowModeInline : actualPadding.inline,\n className,\n })\n }, [size, className, padding, mobile])\n return <div {...rest} className={actualClassName} />\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AA0BA;AACE;AACA;AACE;AACE;AACA;AACA;AACA;AACD;;;AAGF;AACD;AACE;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACF;AACF;AAED;AACE;AACA;AACA;AACA;;;AASA;AACA;AACE;AAEI;AACA;AACJ;;AAEE;AACA;;AAED;;
|
|
1
|
+
{"version":3,"file":"Container.cjs","sources":["../../../../src/components/Layout/Container/Container.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, type FC, type PropsWithChildren, useMemo } from 'react'\nimport { type VariantProps, tv } from 'tailwind-variants'\n\nimport { useEnvironment } from '../../../hooks/useEnvironment'\nimport { paddingBlock, paddingInline } from '../../../tailwind'\n\nimport type { Gap } from '../../../types'\n\ntype BaseProps = PropsWithChildren<\n Omit<VariantProps<typeof classNameGenerator>, 'paddingBlock' | 'paddingInline'> & {\n padding?: Gap | SeparatePadding\n }\n>\ntype Props = BaseProps & Omit<ComponentProps<'div'>, keyof BaseProps>\n\ntype SeparatePadding = {\n block?: Gap\n inline?: Gap\n /** 画面幅が狭い時のブロック方向パディング */\n narrowModeBlock?: Gap\n /** 画面幅が狭い時のインライン方向パディング */\n narrowModeInline?: Gap\n}\n\nconst classNameGenerator = tv({\n base: 'shr-mx-auto shr-w-full',\n variants: {\n size: {\n NARROW: 'shr-max-w-col6',\n DEFAULT: 'shr-max-w-col8',\n WIDE: 'shr-max-w-col9',\n FULL: '',\n },\n paddingBlock,\n paddingInline,\n },\n compoundVariants: [\n {\n paddingInline: [0.25, 'X3S'],\n className: 'shr-w-[calc(100%-theme(spacing[0.25])*2)]',\n },\n {\n paddingInline: [0.5, 'XXS'],\n className: 'shr-w-[calc(100%-theme(spacing[0.5])*2)]',\n },\n {\n paddingInline: 0.75,\n className: 'shr-w-[calc(100%-theme(spacing[0.75])*2)]',\n },\n {\n paddingInline: [1, 'XS'],\n className: 'shr-w-[calc(100%-theme(spacing[1])*2)]',\n },\n {\n paddingInline: 1.25,\n className: 'shr-w-[calc(100%-theme(spacing[1.25])*2)]',\n },\n {\n paddingInline: [1.5, 'S'],\n className: 'shr-w-[calc(100%-theme(spacing[1.5])*2)]',\n },\n {\n paddingInline: [2, 'M'],\n className: 'shr-w-[calc(100%-theme(spacing[2])*2)]',\n },\n {\n paddingInline: [2.5, 'L'],\n className: 'shr-w-[calc(100%-theme(spacing[2.5])*2)]',\n },\n {\n paddingInline: [3, 'XL'],\n className: 'shr-w-[calc(100%-theme(spacing[3])*2)]',\n },\n {\n paddingInline: [3.5, 'XXL'],\n className: 'shr-w-[calc(100%-theme(spacing[3.5])*2)]',\n },\n {\n paddingInline: [4, 'X3L'],\n className: 'shr-w-[calc(100%-theme(spacing[4])*2)]',\n },\n {\n paddingInline: 8,\n className: 'shr-w-[calc(100%-theme(spacing[8])*2)]',\n },\n ],\n})\n\nconst DEFAULT_PADDING = {\n block: 2,\n inline: 2,\n narrowModeBlock: 1.5,\n narrowModeInline: 1,\n} as const\n\nexport const Container: FC<Props> = ({\n size = 'DEFAULT',\n padding = DEFAULT_PADDING,\n className,\n ...rest\n}) => {\n const { mobile } = useEnvironment()\n const actualClassName = useMemo(() => {\n const actualPadding =\n padding instanceof Object\n ? padding\n : { block: padding, inline: padding, narrowModeBlock: padding, narrowModeInline: padding }\n return classNameGenerator({\n size,\n paddingBlock: mobile ? actualPadding.narrowModeBlock : actualPadding.block,\n paddingInline: mobile ? actualPadding.narrowModeInline : actualPadding.inline,\n className,\n })\n }, [size, className, padding, mobile])\n\n return <div {...rest} className={actualClassName} />\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AA0BA;AACE;AACA;AACE;AACE;AACA;AACA;AACA;AACD;;;AAGF;AACD;AACE;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACF;AACF;AAED;AACE;AACA;AACA;AACA;;;AASA;AACA;AACE;AAEI;AACA;AACJ;;AAEE;AACA;;AAED;;AAGH;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Container.js","sources":["../../../../src/components/Layout/Container/Container.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, type FC, type PropsWithChildren, useMemo } from 'react'\nimport { type VariantProps, tv } from 'tailwind-variants'\n\nimport { useEnvironment } from '../../../hooks/useEnvironment'\nimport { paddingBlock, paddingInline } from '../../../tailwind'\n\nimport type { Gap } from '../../../types'\n\ntype BaseProps = PropsWithChildren<\n Omit<VariantProps<typeof classNameGenerator>, 'paddingBlock' | 'paddingInline'> & {\n padding?: Gap | SeparatePadding\n }\n>\ntype Props = BaseProps & Omit<ComponentProps<'div'>, keyof BaseProps>\n\ntype SeparatePadding = {\n block?: Gap\n inline?: Gap\n /** 画面幅が狭い時のブロック方向パディング */\n narrowModeBlock?: Gap\n /** 画面幅が狭い時のインライン方向パディング */\n narrowModeInline?: Gap\n}\n\nconst classNameGenerator = tv({\n base: 'shr-mx-auto shr-w-full',\n variants: {\n size: {\n NARROW: 'shr-max-w-col6',\n DEFAULT: 'shr-max-w-col8',\n WIDE: 'shr-max-w-col9',\n FULL: '',\n },\n paddingBlock,\n paddingInline,\n },\n compoundVariants: [\n {\n paddingInline: [0.25, 'X3S'],\n className: 'shr-w-[calc(100%-theme(spacing[0.25])*2)]',\n },\n {\n paddingInline: [0.5, 'XXS'],\n className: 'shr-w-[calc(100%-theme(spacing[0.5])*2)]',\n },\n {\n paddingInline: 0.75,\n className: 'shr-w-[calc(100%-theme(spacing[0.75])*2)]',\n },\n {\n paddingInline: [1, 'XS'],\n className: 'shr-w-[calc(100%-theme(spacing[1])*2)]',\n },\n {\n paddingInline: 1.25,\n className: 'shr-w-[calc(100%-theme(spacing[1.25])*2)]',\n },\n {\n paddingInline: [1.5, 'S'],\n className: 'shr-w-[calc(100%-theme(spacing[1.5])*2)]',\n },\n {\n paddingInline: [2, 'M'],\n className: 'shr-w-[calc(100%-theme(spacing[2])*2)]',\n },\n {\n paddingInline: [2.5, 'L'],\n className: 'shr-w-[calc(100%-theme(spacing[2.5])*2)]',\n },\n {\n paddingInline: [3, 'XL'],\n className: 'shr-w-[calc(100%-theme(spacing[3])*2)]',\n },\n {\n paddingInline: [3.5, 'XXL'],\n className: 'shr-w-[calc(100%-theme(spacing[3.5])*2)]',\n },\n {\n paddingInline: [4, 'X3L'],\n className: 'shr-w-[calc(100%-theme(spacing[4])*2)]',\n },\n {\n paddingInline: 8,\n className: 'shr-w-[calc(100%-theme(spacing[8])*2)]',\n },\n ],\n})\n\nconst DEFAULT_PADDING = {\n block: 2,\n inline: 2,\n narrowModeBlock: 1.5,\n narrowModeInline: 1,\n} as const\n\nexport const Container: FC<Props> = ({\n size = 'DEFAULT',\n padding = DEFAULT_PADDING,\n className,\n ...rest\n}) => {\n const { mobile } = useEnvironment()\n const actualClassName = useMemo(() => {\n const actualPadding =\n padding instanceof Object\n ? padding\n : { block: padding, inline: padding, narrowModeBlock: padding, narrowModeInline: padding }\n return classNameGenerator({\n size,\n paddingBlock: mobile ? actualPadding.narrowModeBlock : actualPadding.block,\n paddingInline: mobile ? actualPadding.narrowModeInline : actualPadding.inline,\n className,\n })\n }, [size, className, padding, mobile])\n return <div {...rest} className={actualClassName} />\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AA0BA;AACE;AACA;AACE;AACE;AACA;AACA;AACA;AACD;;;AAGF;AACD;AACE;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACF;AACF;AAED;AACE;AACA;AACA;AACA;;;AASA;AACA;AACE;AAEI;AACA;AACJ;;AAEE;AACA;;AAED;;
|
|
1
|
+
{"version":3,"file":"Container.js","sources":["../../../../src/components/Layout/Container/Container.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, type FC, type PropsWithChildren, useMemo } from 'react'\nimport { type VariantProps, tv } from 'tailwind-variants'\n\nimport { useEnvironment } from '../../../hooks/useEnvironment'\nimport { paddingBlock, paddingInline } from '../../../tailwind'\n\nimport type { Gap } from '../../../types'\n\ntype BaseProps = PropsWithChildren<\n Omit<VariantProps<typeof classNameGenerator>, 'paddingBlock' | 'paddingInline'> & {\n padding?: Gap | SeparatePadding\n }\n>\ntype Props = BaseProps & Omit<ComponentProps<'div'>, keyof BaseProps>\n\ntype SeparatePadding = {\n block?: Gap\n inline?: Gap\n /** 画面幅が狭い時のブロック方向パディング */\n narrowModeBlock?: Gap\n /** 画面幅が狭い時のインライン方向パディング */\n narrowModeInline?: Gap\n}\n\nconst classNameGenerator = tv({\n base: 'shr-mx-auto shr-w-full',\n variants: {\n size: {\n NARROW: 'shr-max-w-col6',\n DEFAULT: 'shr-max-w-col8',\n WIDE: 'shr-max-w-col9',\n FULL: '',\n },\n paddingBlock,\n paddingInline,\n },\n compoundVariants: [\n {\n paddingInline: [0.25, 'X3S'],\n className: 'shr-w-[calc(100%-theme(spacing[0.25])*2)]',\n },\n {\n paddingInline: [0.5, 'XXS'],\n className: 'shr-w-[calc(100%-theme(spacing[0.5])*2)]',\n },\n {\n paddingInline: 0.75,\n className: 'shr-w-[calc(100%-theme(spacing[0.75])*2)]',\n },\n {\n paddingInline: [1, 'XS'],\n className: 'shr-w-[calc(100%-theme(spacing[1])*2)]',\n },\n {\n paddingInline: 1.25,\n className: 'shr-w-[calc(100%-theme(spacing[1.25])*2)]',\n },\n {\n paddingInline: [1.5, 'S'],\n className: 'shr-w-[calc(100%-theme(spacing[1.5])*2)]',\n },\n {\n paddingInline: [2, 'M'],\n className: 'shr-w-[calc(100%-theme(spacing[2])*2)]',\n },\n {\n paddingInline: [2.5, 'L'],\n className: 'shr-w-[calc(100%-theme(spacing[2.5])*2)]',\n },\n {\n paddingInline: [3, 'XL'],\n className: 'shr-w-[calc(100%-theme(spacing[3])*2)]',\n },\n {\n paddingInline: [3.5, 'XXL'],\n className: 'shr-w-[calc(100%-theme(spacing[3.5])*2)]',\n },\n {\n paddingInline: [4, 'X3L'],\n className: 'shr-w-[calc(100%-theme(spacing[4])*2)]',\n },\n {\n paddingInline: 8,\n className: 'shr-w-[calc(100%-theme(spacing[8])*2)]',\n },\n ],\n})\n\nconst DEFAULT_PADDING = {\n block: 2,\n inline: 2,\n narrowModeBlock: 1.5,\n narrowModeInline: 1,\n} as const\n\nexport const Container: FC<Props> = ({\n size = 'DEFAULT',\n padding = DEFAULT_PADDING,\n className,\n ...rest\n}) => {\n const { mobile } = useEnvironment()\n const actualClassName = useMemo(() => {\n const actualPadding =\n padding instanceof Object\n ? padding\n : { block: padding, inline: padding, narrowModeBlock: padding, narrowModeInline: padding }\n return classNameGenerator({\n size,\n paddingBlock: mobile ? actualPadding.narrowModeBlock : actualPadding.block,\n paddingInline: mobile ? actualPadding.narrowModeInline : actualPadding.inline,\n className,\n })\n }, [size, className, padding, mobile])\n\n return <div {...rest} className={actualClassName} />\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AA0BA;AACE;AACA;AACE;AACE;AACA;AACA;AACA;AACD;;;AAGF;AACD;AACE;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACF;AACF;AAED;AACE;AACA;AACA;AACA;;;AASA;AACA;AACE;AAEI;AACA;AACJ;;AAEE;AACA;;AAED;;AAGH;AACF;;"}
|
|
@@ -11,7 +11,8 @@ require('react-intl');
|
|
|
11
11
|
require('../../intl/Localizer.cjs');
|
|
12
12
|
require('../../_virtual/dayjs.min.cjs');
|
|
13
13
|
require('../../intl/TimeFormatter.cjs');
|
|
14
|
-
|
|
14
|
+
require('../../_virtual/index.cjs');
|
|
15
|
+
var index$1 = require('../../_virtual/index2.cjs');
|
|
15
16
|
require('../Layout/Stack/Stack.cjs');
|
|
16
17
|
var components_Layout_Cluster_Cluster = require('../Layout/Cluster/Cluster.cjs');
|
|
17
18
|
var components_Layout_Reel_Reel = require('../Layout/Reel/Reel.cjs');
|
|
@@ -107,7 +108,7 @@ const ItemButtons = React.memo(({ total, current, padding, withoutNumbers, hrefT
|
|
|
107
108
|
return [];
|
|
108
109
|
}
|
|
109
110
|
const actualPadding = padding ?? 4;
|
|
110
|
-
return
|
|
111
|
+
return index$1(Math.max(current - actualPadding, 1), Math.min(current + actualPadding, total) + 1);
|
|
111
112
|
}, [current, total, padding, withoutNumbers]);
|
|
112
113
|
const prevAttrs = {
|
|
113
114
|
disabled: current === 1,
|