smarthr-ui 98.0.0 → 98.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/lib/components/Combobox/ItemButton.cjs +27 -26
  2. package/lib/components/Combobox/ItemButton.cjs.map +1 -1
  3. package/lib/components/Combobox/ItemButton.js +28 -27
  4. package/lib/components/Combobox/ItemButton.js.map +1 -1
  5. package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs +35 -52
  6. package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs.map +1 -1
  7. package/lib/components/Combobox/SingleCombobox/SingleCombobox.js +35 -52
  8. package/lib/components/Combobox/SingleCombobox/SingleCombobox.js.map +1 -1
  9. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.cjs +9 -3
  10. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.cjs.map +1 -1
  11. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.js +9 -3
  12. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.js.map +1 -1
  13. package/lib/components/Disclosure/DisclosureTrigger.cjs +8 -4
  14. package/lib/components/Disclosure/DisclosureTrigger.cjs.map +1 -1
  15. package/lib/components/Disclosure/DisclosureTrigger.js +8 -4
  16. package/lib/components/Disclosure/DisclosureTrigger.js.map +1 -1
  17. package/lib/components/FileViewer/FileViewer.cjs +35 -2
  18. package/lib/components/FileViewer/FileViewer.cjs.map +1 -1
  19. package/lib/components/FileViewer/FileViewer.js +37 -4
  20. package/lib/components/FileViewer/FileViewer.js.map +1 -1
  21. package/lib/components/FileViewer/PDFViewer.cjs +59 -2
  22. package/lib/components/FileViewer/PDFViewer.cjs.map +1 -1
  23. package/lib/components/FileViewer/PDFViewer.d.ts +6 -1
  24. package/lib/components/FileViewer/PDFViewer.js +60 -3
  25. package/lib/components/FileViewer/PDFViewer.js.map +1 -1
  26. package/lib/components/FileViewer/SearchController.cjs +105 -0
  27. package/lib/components/FileViewer/SearchController.cjs.map +1 -0
  28. package/lib/components/FileViewer/SearchController.d.ts +7 -0
  29. package/lib/components/FileViewer/SearchController.js +103 -0
  30. package/lib/components/FileViewer/SearchController.js.map +1 -0
  31. package/lib/components/FileViewer/buildCustomTextRenderer.cjs +55 -0
  32. package/lib/components/FileViewer/buildCustomTextRenderer.cjs.map +1 -0
  33. package/lib/components/FileViewer/buildCustomTextRenderer.d.ts +9 -0
  34. package/lib/components/FileViewer/buildCustomTextRenderer.js +50 -0
  35. package/lib/components/FileViewer/buildCustomTextRenderer.js.map +1 -0
  36. package/lib/components/FileViewer/types.d.ts +7 -0
  37. package/lib/components/FileViewer/usePDFSearch.cjs +148 -0
  38. package/lib/components/FileViewer/usePDFSearch.cjs.map +1 -0
  39. package/lib/components/FileViewer/usePDFSearch.d.ts +19 -0
  40. package/lib/components/FileViewer/usePDFSearch.js +143 -0
  41. package/lib/components/FileViewer/usePDFSearch.js.map +1 -0
  42. package/lib/components/Icon/FaIcon.js +1 -1
  43. package/lib/hooks/useLatest.cjs +33 -0
  44. package/lib/hooks/useLatest.cjs.map +1 -0
  45. package/lib/hooks/useLatest.d.ts +19 -0
  46. package/lib/hooks/useLatest.js +31 -0
  47. package/lib/hooks/useLatest.js.map +1 -0
  48. package/lib/intl/locales/en_us.json.cjs +3 -0
  49. package/lib/intl/locales/en_us.json.cjs.map +1 -1
  50. package/lib/intl/locales/en_us.json.js +3 -0
  51. package/lib/intl/locales/en_us.json.js.map +1 -1
  52. package/lib/intl/locales/id_id.json.cjs +3 -0
  53. package/lib/intl/locales/id_id.json.cjs.map +1 -1
  54. package/lib/intl/locales/id_id.json.js +3 -0
  55. package/lib/intl/locales/id_id.json.js.map +1 -1
  56. package/lib/intl/locales/index.d.ts +27 -0
  57. package/lib/intl/locales/ja.cjs +3 -0
  58. package/lib/intl/locales/ja.cjs.map +1 -1
  59. package/lib/intl/locales/ja.d.ts +3 -0
  60. package/lib/intl/locales/ja.js +3 -0
  61. package/lib/intl/locales/ja.js.map +1 -1
  62. package/lib/intl/locales/ja.json.cjs +3 -0
  63. package/lib/intl/locales/ja.json.cjs.map +1 -1
  64. package/lib/intl/locales/ja.json.js +3 -0
  65. package/lib/intl/locales/ja.json.js.map +1 -1
  66. package/lib/intl/locales/ja_easy.json.cjs +3 -0
  67. package/lib/intl/locales/ja_easy.json.cjs.map +1 -1
  68. package/lib/intl/locales/ja_easy.json.js +3 -0
  69. package/lib/intl/locales/ja_easy.json.js.map +1 -1
  70. package/lib/intl/locales/ko_kr.json.cjs +3 -0
  71. package/lib/intl/locales/ko_kr.json.cjs.map +1 -1
  72. package/lib/intl/locales/ko_kr.json.js +3 -0
  73. package/lib/intl/locales/ko_kr.json.js.map +1 -1
  74. package/lib/intl/locales/pt_br.json.cjs +3 -0
  75. package/lib/intl/locales/pt_br.json.cjs.map +1 -1
  76. package/lib/intl/locales/pt_br.json.js +3 -0
  77. package/lib/intl/locales/pt_br.json.js.map +1 -1
  78. package/lib/intl/locales/vi_vn.json.cjs +3 -0
  79. package/lib/intl/locales/vi_vn.json.cjs.map +1 -1
  80. package/lib/intl/locales/vi_vn.json.js +3 -0
  81. package/lib/intl/locales/vi_vn.json.js.map +1 -1
  82. package/lib/intl/locales/zh_hans_cn.json.cjs +3 -0
  83. package/lib/intl/locales/zh_hans_cn.json.cjs.map +1 -1
  84. package/lib/intl/locales/zh_hans_cn.json.js +3 -0
  85. package/lib/intl/locales/zh_hans_cn.json.js.map +1 -1
  86. package/lib/intl/locales/zh_hant_tw.json.cjs +3 -0
  87. package/lib/intl/locales/zh_hant_tw.json.cjs.map +1 -1
  88. package/lib/intl/locales/zh_hant_tw.json.js +3 -0
  89. package/lib/intl/locales/zh_hant_tw.json.js.map +1 -1
  90. package/metadata.json +1 -1
  91. package/package.json +1 -1
  92. package/smarthr-ui.css +35 -4
@@ -29,43 +29,44 @@ const classNameGenerator = index.tv({
29
29
  },
30
30
  });
31
31
  const ItemButton = ({ option, onAdd, onSelect, onMouseOver, activeRef }) => {
32
+ const unstableRef = React.useRef({ onAdd, onSelect, onMouseOver, option });
33
+ unstableRef.current = { onAdd, onSelect, onMouseOver, option };
32
34
  const handleMouseOver = React.useCallback(() => {
33
- onMouseOver(option);
34
- }, [onMouseOver, option]);
35
- const commonProps = {
36
- option,
37
- onMouseOver: handleMouseOver,
35
+ unstableRef.current.onMouseOver(unstableRef.current.option);
36
+ }, []);
37
+ const handleAddClick = React.useCallback(() => {
38
+ unstableRef.current.onAdd?.(unstableRef.current.option);
39
+ }, []);
40
+ const handleSelectClick = React.useCallback(() => {
41
+ unstableRef.current.onSelect(unstableRef.current.option);
42
+ }, []);
43
+ const commonAttrs = {
44
+ id: option.id,
45
+ label: option.item.label,
38
46
  activeRef,
47
+ onMouseOver: handleMouseOver,
39
48
  };
40
- return option.isNew ? (jsxRuntime.jsx(AddButton, { ...commonProps, onAdd: onAdd })) : (jsxRuntime.jsx(SelectButton, { ...commonProps, onSelect: onSelect }));
49
+ return option.isNew ? (jsxRuntime.jsx(AddButton, { ...commonAttrs, onClick: handleAddClick })) : (jsxRuntime.jsx(SelectButton, { ...commonAttrs, disabled: option.item.disabled, selected: option.selected, onClick: handleSelectClick }));
41
50
  };
42
51
  const typedMemo = React.memo;
43
52
  const Memoized = typedMemo(ItemButton);
44
- const AddButton = ({ activeRef, option, onAdd, onMouseOver, }) => {
45
- const className = React.useMemo(() => classNameGenerator({
53
+ const AddButton = React.memo(({ id, label, activeRef, onClick, onMouseOver }) => {
54
+ const className = classNameGenerator({
46
55
  new: true,
47
- }), []);
48
- const onClick = React.useMemo(() => onAdd
49
- ? () => {
50
- onAdd(option);
51
- }
52
- : undefined, [option, onAdd]);
53
- return (jsxRuntime.jsx("button", { ref: activeRef, type: "button", role: "option", "aria-selected": false, id: option.id, "data-active": !!activeRef, onClick: onClick,
56
+ });
57
+ return (jsxRuntime.jsx("button", { ref: activeRef, type: "button", role: "option", "aria-selected": false, id: id, "data-active": !!activeRef, onClick: onClick,
54
58
  // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
55
- onMouseOver: onMouseOver, className: className, children: jsxRuntime.jsx(MemoizedNewIconWithText, { label: option.item.label }) }));
56
- };
59
+ onMouseOver: onMouseOver, className: className, children: jsxRuntime.jsx(MemoizedNewIconWithText, { label: label }) }));
60
+ });
57
61
  const MemoizedNewIconWithText = React.memo(({ label }) => (jsxRuntime.jsx(components_Text_Text.Text, { color: "TEXT_LINK", icon: jsxRuntime.jsx(components_Icon_FaIcon.FaCirclePlusIcon, { color: "TEXT_LINK" }), children: jsxRuntime.jsx(intl_Localizer.Localizer, { id: "smarthr-ui/Combobox/addItemButtonLabel", defaultText: "\u300C{name}\u300D\u3092\u8FFD\u52A0", values: { name: label } }) })));
58
- const SelectButton = ({ activeRef, option, onSelect, onMouseOver, }) => {
59
- const className = React.useMemo(() => classNameGenerator({
62
+ const SelectButton = React.memo(({ id, label, disabled, selected, activeRef, onClick, onMouseOver }) => {
63
+ const className = classNameGenerator({
60
64
  new: false,
61
- }), []);
62
- const handleSelect = React.useCallback(() => {
63
- onSelect(option);
64
- }, [onSelect, option]);
65
- return (jsxRuntime.jsx("button", { ref: activeRef, type: "button", role: "option", id: option.id, disabled: option.item.disabled, "aria-selected": option.selected, "data-active": !!activeRef, onClick: handleSelect,
65
+ });
66
+ return (jsxRuntime.jsx("button", { ref: activeRef, type: "button", role: "option", id: id, disabled: disabled, "aria-selected": selected, "data-active": !!activeRef, onClick: onClick,
66
67
  // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
67
- onMouseOver: onMouseOver, className: className, children: option.item.label }));
68
- };
68
+ onMouseOver: onMouseOver, className: className, children: label }));
69
+ });
69
70
 
70
71
  exports.ItemButton = Memoized;
71
72
  //# sourceMappingURL=ItemButton.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ItemButton.cjs","sources":["../../../src/components/Combobox/ItemButton.tsx"],"sourcesContent":["import { type ReactNode, type RefObject, memo, useCallback, useMemo } from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { Localizer } from '../../intl'\nimport { FaCirclePlusIcon } from '../Icon'\nimport { Text } from '../Text'\n\nimport type { ComboboxOption } from './types'\n\ntype Props<T> = {\n option: ComboboxOption<T>\n onAdd?: (option: ComboboxOption<T>) => void\n onSelect: (option: ComboboxOption<T>) => void\n onMouseOver: (option: ComboboxOption<T>) => void\n activeRef: RefObject<HTMLButtonElement> | undefined\n}\n\nconst classNameGenerator = tv({\n base: [\n 'shr-block shr-min-w-full shr-cursor-pointer shr-border-none shr-px-1 shr-py-0.5 shr-text-left shr-text-base shr-leading-tight',\n 'aria-selected:shr-text-white',\n 'disabled:shr-cursor-not-allowed disabled:shr-text-disabled',\n 'data-[active=true]:shr-bg-white-darken data-[active=true]:aria-selected:shr-bg-main-darken',\n 'data-[active=false]:shr-bg-white data-[active=false]:aria-selected:shr-bg-main',\n ],\n variants: {\n new: {\n true: 'smarthr-ui-Combobox-addButton shr-flex shr-items-center',\n false: 'smarthr-ui-Combobox-selectButton',\n },\n },\n})\n\nconst ItemButton = <T,>({ option, onAdd, onSelect, onMouseOver, activeRef }: Props<T>) => {\n const handleMouseOver = useCallback(() => {\n onMouseOver(option)\n }, [onMouseOver, option])\n\n const commonProps = {\n option,\n onMouseOver: handleMouseOver,\n activeRef,\n }\n\n return option.isNew ? (\n <AddButton {...commonProps} onAdd={onAdd} />\n ) : (\n <SelectButton {...commonProps} onSelect={onSelect} />\n )\n}\nconst typedMemo: <T>(c: T) => T = memo\nconst Memoized = typedMemo(ItemButton)\nexport { Memoized as ItemButton }\n\ntype ButtonType<T> = Pick<Props<T>, 'option' | 'activeRef'> & {\n onMouseOver: () => void\n}\n\nconst AddButton = <T,>({\n activeRef,\n option,\n onAdd,\n onMouseOver,\n}: ButtonType<T> & Pick<Props<T>, 'onAdd'>) => {\n const className = useMemo(\n () =>\n classNameGenerator({\n new: true,\n }),\n [],\n )\n\n const onClick = useMemo(\n () =>\n onAdd\n ? () => {\n onAdd(option)\n }\n : undefined,\n [option, onAdd],\n )\n\n return (\n <button\n ref={activeRef}\n type=\"button\"\n role=\"option\"\n aria-selected={false}\n id={option.id}\n data-active={!!activeRef}\n onClick={onClick}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={onMouseOver}\n className={className}\n >\n <MemoizedNewIconWithText label={option.item.label} />\n </button>\n )\n}\n\nconst MemoizedNewIconWithText = memo<{ label: ReactNode }>(({ label }) => (\n <Text color=\"TEXT_LINK\" icon={<FaCirclePlusIcon color=\"TEXT_LINK\" />}>\n <Localizer\n id=\"smarthr-ui/Combobox/addItemButtonLabel\"\n defaultText=\"「{name}」を追加\"\n values={{ name: label }}\n />\n </Text>\n))\n\nconst SelectButton = <T,>({\n activeRef,\n option,\n onSelect,\n onMouseOver,\n}: ButtonType<T> & Pick<Props<T>, 'onSelect'>) => {\n const className = useMemo(\n () =>\n classNameGenerator({\n new: false,\n }),\n [],\n )\n\n const handleSelect = useCallback(() => {\n onSelect(option)\n }, [onSelect, option])\n\n return (\n <button\n ref={activeRef}\n type=\"button\"\n role=\"option\"\n id={option.id}\n disabled={option.item.disabled}\n aria-selected={option.selected}\n data-active={!!activeRef}\n onClick={handleSelect}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={onMouseOver}\n className={className}\n >\n {option.item.label}\n </button>\n )\n}\n"],"names":["tv","useCallback","_jsx","memo","useMemo","Text","FaCirclePlusIcon","Localizer"],"mappings":"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"}
1
+ {"version":3,"file":"ItemButton.cjs","sources":["../../../src/components/Combobox/ItemButton.tsx"],"sourcesContent":["import { type ReactNode, type RefObject, memo, useCallback, useRef } from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { Localizer } from '../../intl'\nimport { FaCirclePlusIcon } from '../Icon'\nimport { Text } from '../Text'\n\nimport type { ComboboxOption } from './types'\n\ntype Props<T> = {\n option: ComboboxOption<T>\n onAdd?: (option: ComboboxOption<T>) => void\n onSelect: (option: ComboboxOption<T>) => void\n onMouseOver: (option: ComboboxOption<T>) => void\n activeRef: RefObject<HTMLButtonElement> | undefined\n}\n\nconst classNameGenerator = tv({\n base: [\n 'shr-block shr-min-w-full shr-cursor-pointer shr-border-none shr-px-1 shr-py-0.5 shr-text-left shr-text-base shr-leading-tight',\n 'aria-selected:shr-text-white',\n 'disabled:shr-cursor-not-allowed disabled:shr-text-disabled',\n 'data-[active=true]:shr-bg-white-darken data-[active=true]:aria-selected:shr-bg-main-darken',\n 'data-[active=false]:shr-bg-white data-[active=false]:aria-selected:shr-bg-main',\n ],\n variants: {\n new: {\n true: 'smarthr-ui-Combobox-addButton shr-flex shr-items-center',\n false: 'smarthr-ui-Combobox-selectButton',\n },\n },\n})\n\nconst ItemButton = <T,>({ option, onAdd, onSelect, onMouseOver, activeRef }: Props<T>) => {\n const unstableRef = useRef({ onAdd, onSelect, onMouseOver, option })\n unstableRef.current = { onAdd, onSelect, onMouseOver, option }\n\n const handleMouseOver = useCallback(() => {\n unstableRef.current.onMouseOver(unstableRef.current.option)\n }, [])\n\n const handleAddClick = useCallback(() => {\n unstableRef.current.onAdd?.(unstableRef.current.option)\n }, [])\n\n const handleSelectClick = useCallback(() => {\n unstableRef.current.onSelect(unstableRef.current.option)\n }, [])\n\n const commonAttrs = {\n id: option.id,\n label: option.item.label,\n activeRef,\n onMouseOver: handleMouseOver,\n }\n\n return option.isNew ? (\n <AddButton {...commonAttrs} onClick={handleAddClick} />\n ) : (\n <SelectButton\n {...commonAttrs}\n disabled={option.item.disabled}\n selected={option.selected}\n onClick={handleSelectClick}\n />\n )\n}\nconst typedMemo: <T>(c: T) => T = memo\nconst Memoized = typedMemo(ItemButton)\nexport { Memoized as ItemButton }\n\nconst AddButton = memo<{\n id: string\n label: ReactNode\n activeRef: RefObject<HTMLButtonElement> | undefined\n onClick?: () => void\n onMouseOver: () => void\n}>(({ id, label, activeRef, onClick, onMouseOver }) => {\n const className = classNameGenerator({\n new: true,\n })\n\n return (\n <button\n ref={activeRef}\n type=\"button\"\n role=\"option\"\n aria-selected={false}\n id={id}\n data-active={!!activeRef}\n onClick={onClick}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={onMouseOver}\n className={className}\n >\n <MemoizedNewIconWithText label={label} />\n </button>\n )\n})\n\nconst MemoizedNewIconWithText = memo<{ label: ReactNode }>(({ label }) => (\n <Text color=\"TEXT_LINK\" icon={<FaCirclePlusIcon color=\"TEXT_LINK\" />}>\n <Localizer\n id=\"smarthr-ui/Combobox/addItemButtonLabel\"\n defaultText=\"「{name}」を追加\"\n values={{ name: label }}\n />\n </Text>\n))\n\nconst SelectButton = memo<{\n id: string\n label: ReactNode\n disabled?: boolean\n selected: boolean\n activeRef: RefObject<HTMLButtonElement> | undefined\n onClick: () => void\n onMouseOver: () => void\n}>(({ id, label, disabled, selected, activeRef, onClick, onMouseOver }) => {\n const className = classNameGenerator({\n new: false,\n })\n\n return (\n <button\n ref={activeRef}\n type=\"button\"\n role=\"option\"\n id={id}\n disabled={disabled}\n aria-selected={selected}\n data-active={!!activeRef}\n onClick={onClick}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={onMouseOver}\n className={className}\n >\n {label}\n </button>\n )\n})\n"],"names":["tv","useRef","useCallback","_jsx","memo","Text","FaCirclePlusIcon","Localizer"],"mappings":";;;;;;;;;;;;;;;AAiBA,MAAM,kBAAkB,GAAGA,QAAE,CAAC;AAC5B,IAAA,IAAI,EAAE;QACJ,+HAA+H;QAC/H,8BAA8B;QAC9B,4DAA4D;QAC5D,4FAA4F;QAC5F,gFAAgF;AACjF,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,GAAG,EAAE;AACH,YAAA,IAAI,EAAE,yDAAyD;AAC/D,YAAA,KAAK,EAAE,kCAAkC;AAC1C,SAAA;AACF,KAAA;AACF,CAAA,CAAC;AAEF,MAAM,UAAU,GAAG,CAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAY,KAAI;AACvF,IAAA,MAAM,WAAW,GAAGC,YAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AACpE,IAAA,WAAW,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE;AAE9D,IAAA,MAAM,eAAe,GAAGC,iBAAW,CAAC,MAAK;QACvC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7D,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,MAAM,cAAc,GAAGA,iBAAW,CAAC,MAAK;AACtC,QAAA,WAAW,CAAC,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;IACzD,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,MAAM,iBAAiB,GAAGA,iBAAW,CAAC,MAAK;QACzC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;IAC1D,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,MAAM,WAAW,GAAG;QAClB,EAAE,EAAE,MAAM,CAAC,EAAE;AACb,QAAA,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK;QACxB,SAAS;AACT,QAAA,WAAW,EAAE,eAAe;KAC7B;IAED,OAAO,MAAM,CAAC,KAAK,IACjBC,eAAC,SAAS,EAAA,EAAA,GAAK,WAAW,EAAE,OAAO,EAAE,cAAc,EAAA,CAAI,KAEvDA,cAAA,CAAC,YAAY,EAAA,EAAA,GACP,WAAW,EACf,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAC9B,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,OAAO,EAAE,iBAAiB,EAAA,CAC1B,CACH;AACH,CAAC;AACD,MAAM,SAAS,GAAmBC,UAAI;AACtC,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU;AAGrC,MAAM,SAAS,GAAGA,UAAI,CAMnB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,KAAI;IACpD,MAAM,SAAS,GAAG,kBAAkB,CAAC;AACnC,QAAA,GAAG,EAAE,IAAI;AACV,KAAA,CAAC;IAEF,QACED,cAAA,CAAA,QAAA,EAAA,EACE,GAAG,EAAE,SAAS,EACd,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,QAAQ,mBACE,KAAK,EACpB,EAAE,EAAE,EAAE,EAAA,aAAA,EACO,CAAC,CAAC,SAAS,EACxB,OAAO,EAAE,OAAO;;AAEhB,QAAA,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EAAA,QAAA,EAEpBA,cAAA,CAAC,uBAAuB,EAAA,EAAC,KAAK,EAAE,KAAK,EAAA,CAAI,EAAA,CAClC;AAEb,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAGC,UAAI,CAAuB,CAAC,EAAE,KAAK,EAAE,MACnED,cAAA,CAACE,yBAAI,EAAA,EAAC,KAAK,EAAC,WAAW,EAAC,IAAI,EAAEF,cAAA,CAACG,uCAAgB,EAAA,EAAC,KAAK,EAAC,WAAW,EAAA,CAAG,EAAA,QAAA,EAClEH,cAAA,CAACI,wBAAS,EAAA,EACR,EAAE,EAAC,wCAAwC,EAC3C,WAAW,EAAC,sCAAa,EACzB,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAA,CACvB,EAAA,CACG,CACR,CAAC;AAEF,MAAM,YAAY,GAAGH,UAAI,CAQtB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,KAAI;IACxE,MAAM,SAAS,GAAG,kBAAkB,CAAC;AACnC,QAAA,GAAG,EAAE,KAAK;AACX,KAAA,CAAC;AAEF,IAAA,QACED,cAAA,CAAA,QAAA,EAAA,EACE,GAAG,EAAE,SAAS,EACd,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,QAAQ,EACb,EAAE,EAAE,EAAE,EACN,QAAQ,EAAE,QAAQ,EAAA,eAAA,EACH,QAAQ,EAAA,aAAA,EACV,CAAC,CAAC,SAAS,EACxB,OAAO,EAAE,OAAO;;QAEhB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EAAA,QAAA,EAEnB,KAAK,EAAA,CACC;AAEb,CAAC,CAAC;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { memo, useCallback, useMemo } from 'react';
2
+ import { memo, useRef, useCallback } from 'react';
3
3
  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.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js';
4
4
  import '../../intl/IntlProvider.js';
5
5
  import 'react-intl';
@@ -27,43 +27,44 @@ const classNameGenerator = ce({
27
27
  },
28
28
  });
29
29
  const ItemButton = ({ option, onAdd, onSelect, onMouseOver, activeRef }) => {
30
+ const unstableRef = useRef({ onAdd, onSelect, onMouseOver, option });
31
+ unstableRef.current = { onAdd, onSelect, onMouseOver, option };
30
32
  const handleMouseOver = useCallback(() => {
31
- onMouseOver(option);
32
- }, [onMouseOver, option]);
33
- const commonProps = {
34
- option,
35
- onMouseOver: handleMouseOver,
33
+ unstableRef.current.onMouseOver(unstableRef.current.option);
34
+ }, []);
35
+ const handleAddClick = useCallback(() => {
36
+ unstableRef.current.onAdd?.(unstableRef.current.option);
37
+ }, []);
38
+ const handleSelectClick = useCallback(() => {
39
+ unstableRef.current.onSelect(unstableRef.current.option);
40
+ }, []);
41
+ const commonAttrs = {
42
+ id: option.id,
43
+ label: option.item.label,
36
44
  activeRef,
45
+ onMouseOver: handleMouseOver,
37
46
  };
38
- return option.isNew ? (jsx(AddButton, { ...commonProps, onAdd: onAdd })) : (jsx(SelectButton, { ...commonProps, onSelect: onSelect }));
47
+ return option.isNew ? (jsx(AddButton, { ...commonAttrs, onClick: handleAddClick })) : (jsx(SelectButton, { ...commonAttrs, disabled: option.item.disabled, selected: option.selected, onClick: handleSelectClick }));
39
48
  };
40
49
  const typedMemo = memo;
41
50
  const Memoized = typedMemo(ItemButton);
42
- const AddButton = ({ activeRef, option, onAdd, onMouseOver, }) => {
43
- const className = useMemo(() => classNameGenerator({
51
+ const AddButton = memo(({ id, label, activeRef, onClick, onMouseOver }) => {
52
+ const className = classNameGenerator({
44
53
  new: true,
45
- }), []);
46
- const onClick = useMemo(() => onAdd
47
- ? () => {
48
- onAdd(option);
49
- }
50
- : undefined, [option, onAdd]);
51
- return (jsx("button", { ref: activeRef, type: "button", role: "option", "aria-selected": false, id: option.id, "data-active": !!activeRef, onClick: onClick,
54
+ });
55
+ return (jsx("button", { ref: activeRef, type: "button", role: "option", "aria-selected": false, id: id, "data-active": !!activeRef, onClick: onClick,
52
56
  // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
53
- onMouseOver: onMouseOver, className: className, children: jsx(MemoizedNewIconWithText, { label: option.item.label }) }));
54
- };
57
+ onMouseOver: onMouseOver, className: className, children: jsx(MemoizedNewIconWithText, { label: label }) }));
58
+ });
55
59
  const MemoizedNewIconWithText = memo(({ label }) => (jsx(Text, { color: "TEXT_LINK", icon: jsx(FaCirclePlusIcon, { color: "TEXT_LINK" }), children: jsx(Localizer, { id: "smarthr-ui/Combobox/addItemButtonLabel", defaultText: "\u300C{name}\u300D\u3092\u8FFD\u52A0", values: { name: label } }) })));
56
- const SelectButton = ({ activeRef, option, onSelect, onMouseOver, }) => {
57
- const className = useMemo(() => classNameGenerator({
60
+ const SelectButton = memo(({ id, label, disabled, selected, activeRef, onClick, onMouseOver }) => {
61
+ const className = classNameGenerator({
58
62
  new: false,
59
- }), []);
60
- const handleSelect = useCallback(() => {
61
- onSelect(option);
62
- }, [onSelect, option]);
63
- return (jsx("button", { ref: activeRef, type: "button", role: "option", id: option.id, disabled: option.item.disabled, "aria-selected": option.selected, "data-active": !!activeRef, onClick: handleSelect,
63
+ });
64
+ return (jsx("button", { ref: activeRef, type: "button", role: "option", id: id, disabled: disabled, "aria-selected": selected, "data-active": !!activeRef, onClick: onClick,
64
65
  // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
65
- onMouseOver: onMouseOver, className: className, children: option.item.label }));
66
- };
66
+ onMouseOver: onMouseOver, className: className, children: label }));
67
+ });
67
68
 
68
69
  export { Memoized as ItemButton };
69
70
  //# sourceMappingURL=ItemButton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ItemButton.js","sources":["../../../src/components/Combobox/ItemButton.tsx"],"sourcesContent":["import { type ReactNode, type RefObject, memo, useCallback, useMemo } from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { Localizer } from '../../intl'\nimport { FaCirclePlusIcon } from '../Icon'\nimport { Text } from '../Text'\n\nimport type { ComboboxOption } from './types'\n\ntype Props<T> = {\n option: ComboboxOption<T>\n onAdd?: (option: ComboboxOption<T>) => void\n onSelect: (option: ComboboxOption<T>) => void\n onMouseOver: (option: ComboboxOption<T>) => void\n activeRef: RefObject<HTMLButtonElement> | undefined\n}\n\nconst classNameGenerator = tv({\n base: [\n 'shr-block shr-min-w-full shr-cursor-pointer shr-border-none shr-px-1 shr-py-0.5 shr-text-left shr-text-base shr-leading-tight',\n 'aria-selected:shr-text-white',\n 'disabled:shr-cursor-not-allowed disabled:shr-text-disabled',\n 'data-[active=true]:shr-bg-white-darken data-[active=true]:aria-selected:shr-bg-main-darken',\n 'data-[active=false]:shr-bg-white data-[active=false]:aria-selected:shr-bg-main',\n ],\n variants: {\n new: {\n true: 'smarthr-ui-Combobox-addButton shr-flex shr-items-center',\n false: 'smarthr-ui-Combobox-selectButton',\n },\n },\n})\n\nconst ItemButton = <T,>({ option, onAdd, onSelect, onMouseOver, activeRef }: Props<T>) => {\n const handleMouseOver = useCallback(() => {\n onMouseOver(option)\n }, [onMouseOver, option])\n\n const commonProps = {\n option,\n onMouseOver: handleMouseOver,\n activeRef,\n }\n\n return option.isNew ? (\n <AddButton {...commonProps} onAdd={onAdd} />\n ) : (\n <SelectButton {...commonProps} onSelect={onSelect} />\n )\n}\nconst typedMemo: <T>(c: T) => T = memo\nconst Memoized = typedMemo(ItemButton)\nexport { Memoized as ItemButton }\n\ntype ButtonType<T> = Pick<Props<T>, 'option' | 'activeRef'> & {\n onMouseOver: () => void\n}\n\nconst AddButton = <T,>({\n activeRef,\n option,\n onAdd,\n onMouseOver,\n}: ButtonType<T> & Pick<Props<T>, 'onAdd'>) => {\n const className = useMemo(\n () =>\n classNameGenerator({\n new: true,\n }),\n [],\n )\n\n const onClick = useMemo(\n () =>\n onAdd\n ? () => {\n onAdd(option)\n }\n : undefined,\n [option, onAdd],\n )\n\n return (\n <button\n ref={activeRef}\n type=\"button\"\n role=\"option\"\n aria-selected={false}\n id={option.id}\n data-active={!!activeRef}\n onClick={onClick}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={onMouseOver}\n className={className}\n >\n <MemoizedNewIconWithText label={option.item.label} />\n </button>\n )\n}\n\nconst MemoizedNewIconWithText = memo<{ label: ReactNode }>(({ label }) => (\n <Text color=\"TEXT_LINK\" icon={<FaCirclePlusIcon color=\"TEXT_LINK\" />}>\n <Localizer\n id=\"smarthr-ui/Combobox/addItemButtonLabel\"\n defaultText=\"「{name}」を追加\"\n values={{ name: label }}\n />\n </Text>\n))\n\nconst SelectButton = <T,>({\n activeRef,\n option,\n onSelect,\n onMouseOver,\n}: ButtonType<T> & Pick<Props<T>, 'onSelect'>) => {\n const className = useMemo(\n () =>\n classNameGenerator({\n new: false,\n }),\n [],\n )\n\n const handleSelect = useCallback(() => {\n onSelect(option)\n }, [onSelect, option])\n\n return (\n <button\n ref={activeRef}\n type=\"button\"\n role=\"option\"\n id={option.id}\n disabled={option.item.disabled}\n aria-selected={option.selected}\n data-active={!!activeRef}\n onClick={handleSelect}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={onMouseOver}\n className={className}\n >\n {option.item.label}\n </button>\n )\n}\n"],"names":["tv","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"ItemButton.js","sources":["../../../src/components/Combobox/ItemButton.tsx"],"sourcesContent":["import { type ReactNode, type RefObject, memo, useCallback, useRef } from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { Localizer } from '../../intl'\nimport { FaCirclePlusIcon } from '../Icon'\nimport { Text } from '../Text'\n\nimport type { ComboboxOption } from './types'\n\ntype Props<T> = {\n option: ComboboxOption<T>\n onAdd?: (option: ComboboxOption<T>) => void\n onSelect: (option: ComboboxOption<T>) => void\n onMouseOver: (option: ComboboxOption<T>) => void\n activeRef: RefObject<HTMLButtonElement> | undefined\n}\n\nconst classNameGenerator = tv({\n base: [\n 'shr-block shr-min-w-full shr-cursor-pointer shr-border-none shr-px-1 shr-py-0.5 shr-text-left shr-text-base shr-leading-tight',\n 'aria-selected:shr-text-white',\n 'disabled:shr-cursor-not-allowed disabled:shr-text-disabled',\n 'data-[active=true]:shr-bg-white-darken data-[active=true]:aria-selected:shr-bg-main-darken',\n 'data-[active=false]:shr-bg-white data-[active=false]:aria-selected:shr-bg-main',\n ],\n variants: {\n new: {\n true: 'smarthr-ui-Combobox-addButton shr-flex shr-items-center',\n false: 'smarthr-ui-Combobox-selectButton',\n },\n },\n})\n\nconst ItemButton = <T,>({ option, onAdd, onSelect, onMouseOver, activeRef }: Props<T>) => {\n const unstableRef = useRef({ onAdd, onSelect, onMouseOver, option })\n unstableRef.current = { onAdd, onSelect, onMouseOver, option }\n\n const handleMouseOver = useCallback(() => {\n unstableRef.current.onMouseOver(unstableRef.current.option)\n }, [])\n\n const handleAddClick = useCallback(() => {\n unstableRef.current.onAdd?.(unstableRef.current.option)\n }, [])\n\n const handleSelectClick = useCallback(() => {\n unstableRef.current.onSelect(unstableRef.current.option)\n }, [])\n\n const commonAttrs = {\n id: option.id,\n label: option.item.label,\n activeRef,\n onMouseOver: handleMouseOver,\n }\n\n return option.isNew ? (\n <AddButton {...commonAttrs} onClick={handleAddClick} />\n ) : (\n <SelectButton\n {...commonAttrs}\n disabled={option.item.disabled}\n selected={option.selected}\n onClick={handleSelectClick}\n />\n )\n}\nconst typedMemo: <T>(c: T) => T = memo\nconst Memoized = typedMemo(ItemButton)\nexport { Memoized as ItemButton }\n\nconst AddButton = memo<{\n id: string\n label: ReactNode\n activeRef: RefObject<HTMLButtonElement> | undefined\n onClick?: () => void\n onMouseOver: () => void\n}>(({ id, label, activeRef, onClick, onMouseOver }) => {\n const className = classNameGenerator({\n new: true,\n })\n\n return (\n <button\n ref={activeRef}\n type=\"button\"\n role=\"option\"\n aria-selected={false}\n id={id}\n data-active={!!activeRef}\n onClick={onClick}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={onMouseOver}\n className={className}\n >\n <MemoizedNewIconWithText label={label} />\n </button>\n )\n})\n\nconst MemoizedNewIconWithText = memo<{ label: ReactNode }>(({ label }) => (\n <Text color=\"TEXT_LINK\" icon={<FaCirclePlusIcon color=\"TEXT_LINK\" />}>\n <Localizer\n id=\"smarthr-ui/Combobox/addItemButtonLabel\"\n defaultText=\"「{name}」を追加\"\n values={{ name: label }}\n />\n </Text>\n))\n\nconst SelectButton = memo<{\n id: string\n label: ReactNode\n disabled?: boolean\n selected: boolean\n activeRef: RefObject<HTMLButtonElement> | undefined\n onClick: () => void\n onMouseOver: () => void\n}>(({ id, label, disabled, selected, activeRef, onClick, onMouseOver }) => {\n const className = classNameGenerator({\n new: false,\n })\n\n return (\n <button\n ref={activeRef}\n type=\"button\"\n role=\"option\"\n id={id}\n disabled={disabled}\n aria-selected={selected}\n data-active={!!activeRef}\n onClick={onClick}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={onMouseOver}\n className={className}\n >\n {label}\n </button>\n )\n})\n"],"names":["tv","_jsx"],"mappings":"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"}
@@ -6,6 +6,7 @@ var React = require('react');
6
6
  var index$1 = require('../../../_virtual/index3.cjs');
7
7
  var index = require('./../../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs');
8
8
  var hooks_useClick = require('../../../hooks/useClick.cjs');
9
+ var hooks_useLatest = require('../../../hooks/useLatest.cjs');
9
10
  var hooks_useTheme = require('../../../hooks/useTheme.cjs');
10
11
  require('../../../intl/IntlProvider.cjs');
11
12
  var intl_useIntl = require('../../../intl/useIntl.cjs');
@@ -78,7 +79,7 @@ const ActualSingleCombobox = ({ items, selectedItem, defaultItem, name, disabled
78
79
  const [inputValue, setInputValue] = React.useState('');
79
80
  const [isComposing, setIsComposing] = React.useState(false);
80
81
  const [isEditing, setIsEditing] = React.useState(false);
81
- const unstableRef = React.useRef({
82
+ const latest = hooks_useLatest.useLatest({
82
83
  onChange,
83
84
  onChangeInput,
84
85
  onAdd,
@@ -96,24 +97,6 @@ const ActualSingleCombobox = ({ items, selectedItem, defaultItem, name, disabled
96
97
  isComposing,
97
98
  isEditing,
98
99
  });
99
- unstableRef.current = {
100
- onChange,
101
- onChangeInput,
102
- onAdd,
103
- onSelect,
104
- onClear,
105
- onClearClick,
106
- onChangeSelected,
107
- onFocus,
108
- onBlur,
109
- onKeyPress,
110
- defaultItem,
111
- selectedItem,
112
- isFocused,
113
- isExpanded,
114
- isComposing,
115
- isEditing,
116
- };
117
100
  React.useImperativeHandle(ref, () => inputRef.current);
118
101
  const { options } = components_Combobox_useOptions.useSingleOptions({
119
102
  items,
@@ -128,8 +111,8 @@ const ActualSingleCombobox = ({ items, selectedItem, defaultItem, name, disabled
128
111
  dropdownWidth,
129
112
  onAdd,
130
113
  onSelect: React.useCallback((selected) => {
131
- unstableRef.current.onSelect?.(selected);
132
- unstableRef.current.onChangeSelected?.(selected);
114
+ latest.onSelect?.(selected);
115
+ latest.onChangeSelected?.(selected);
133
116
  // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう
134
117
  // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする
135
118
  requestAnimationFrame(() => {
@@ -140,46 +123,46 @@ const ActualSingleCombobox = ({ items, selectedItem, defaultItem, name, disabled
140
123
  // - 先にclearしてしまうと意図せずこの要素のドロップダウンを閉じる前に他要素の再レンダリングを引き起こす可能性がある
141
124
  // - 例えばFilterDropdownなどで当comboboxを使っている場合、レイアウト上comboboxのdropdown以下の要素がクリックされた扱いになってしまい
142
125
  // FilterDropdownを意図せず閉じてしまうなどの挙動のバグを引き起こす可能性がある
143
- unstableRef.current.onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT);
126
+ latest.onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT);
144
127
  });
145
128
  setIsEditing(false);
146
- }, []),
129
+ }, [latest]),
147
130
  isExpanded,
148
131
  isLoading,
149
132
  triggerRef: outerRef,
150
133
  noResultText,
151
134
  });
152
135
  const selectDefaultItem = React.useCallback(() => {
153
- if (unstableRef.current.onSelect && unstableRef.current.defaultItem) {
154
- unstableRef.current.onSelect(unstableRef.current.defaultItem);
136
+ if (latest.onSelect && latest.defaultItem) {
137
+ latest.onSelect(latest.defaultItem);
155
138
  }
156
- }, []);
139
+ }, [latest]);
157
140
  const focus = React.useCallback(() => {
158
- unstableRef.current.onFocus?.();
141
+ latest.onFocus?.();
159
142
  inputRef.current?.focus();
160
143
  setIsFocused(true);
161
- if (!unstableRef.current.isFocused) {
144
+ if (!latest.isFocused) {
162
145
  setIsExpanded(true);
163
146
  }
164
- }, []);
147
+ }, [latest]);
165
148
  const unfocus = React.useCallback(() => {
166
- if (!unstableRef.current.isFocused)
149
+ if (!latest.isFocused)
167
150
  return;
168
- unstableRef.current.onBlur?.();
151
+ latest.onBlur?.();
169
152
  setIsFocused(false);
170
153
  setIsExpanded(false);
171
154
  setIsEditing(false);
172
- if (unstableRef.current.selectedItem) {
173
- setInputValue(index$1(unstableRef.current.selectedItem.label));
155
+ if (latest.selectedItem) {
156
+ setInputValue(index$1(latest.selectedItem.label));
174
157
  }
175
158
  else {
176
159
  selectDefaultItem();
177
160
  }
178
- }, [selectDefaultItem]);
161
+ }, [selectDefaultItem, latest]);
179
162
  const onClickClear = React.useCallback((e) => {
180
163
  e.stopPropagation();
181
164
  let isExecutedPreventDefault = false;
182
- unstableRef.current.onClearClick?.({
165
+ latest.onClearClick?.({
183
166
  ...e,
184
167
  preventDefault: () => {
185
168
  e.preventDefault();
@@ -187,43 +170,43 @@ const ActualSingleCombobox = ({ items, selectedItem, defaultItem, name, disabled
187
170
  },
188
171
  });
189
172
  if (!isExecutedPreventDefault) {
190
- unstableRef.current.onClear?.();
191
- unstableRef.current.onChangeSelected?.(null);
173
+ latest.onClear?.();
174
+ latest.onChangeSelected?.(null);
192
175
  inputRef.current?.focus();
193
176
  setIsFocused(true);
194
177
  setIsExpanded(true);
195
178
  }
196
- }, []);
179
+ }, [latest]);
197
180
  const onClickInput = React.useCallback((e) => {
198
181
  if (disabled || readOnly) {
199
182
  e.stopPropagation();
200
183
  return;
201
184
  }
202
185
  inputRef.current?.focus();
203
- if (!unstableRef.current.isExpanded) {
186
+ if (!latest.isExpanded) {
204
187
  setIsExpanded(true);
205
188
  }
206
- }, [disabled, readOnly]);
189
+ }, [disabled, readOnly, latest]);
207
190
  const actualOnChangeInput = React.useCallback((e) => {
208
- unstableRef.current.onChange?.(e);
209
- unstableRef.current.onChangeInput?.(e);
210
- if (!unstableRef.current.isEditing)
191
+ latest.onChange?.(e);
192
+ latest.onChangeInput?.(e);
193
+ if (!latest.isEditing)
211
194
  setIsEditing(true);
212
195
  const { value } = e.currentTarget;
213
196
  setInputValue(value);
214
197
  if (value === '') {
215
- unstableRef.current.onClear?.();
216
- unstableRef.current.onChangeSelected?.(null);
198
+ latest.onClear?.();
199
+ latest.onChangeSelected?.(null);
217
200
  }
218
- }, []);
201
+ }, [latest]);
219
202
  const onCompositionStart = React.useCallback(() => setIsComposing(true), []);
220
203
  const onCompositionEnd = React.useCallback(() => setIsComposing(false), []);
221
204
  const onKeyDownInput = React.useCallback((e) => {
222
- if (unstableRef.current.isComposing) {
205
+ if (latest.isComposing) {
223
206
  return;
224
207
  }
225
208
  if (ESCAPE_KEY_REGEX.test(e.key)) {
226
- if (unstableRef.current.isExpanded) {
209
+ if (latest.isExpanded) {
227
210
  e.stopPropagation();
228
211
  setIsExpanded(false);
229
212
  }
@@ -236,20 +219,20 @@ const ActualSingleCombobox = ({ items, selectedItem, defaultItem, name, disabled
236
219
  e.preventDefault();
237
220
  }
238
221
  inputRef.current?.focus();
239
- if (!unstableRef.current.isExpanded) {
222
+ if (!latest.isExpanded) {
240
223
  setIsExpanded(true);
241
224
  }
242
225
  }
243
226
  onKeyDownListBox(e);
244
- }, [unfocus, onKeyDownListBox]);
227
+ }, [unfocus, onKeyDownListBox, latest]);
245
228
  // HINT: form内にcomboboxを設置 & 検索inputにfocusした状態で
246
229
  // アイテムをキーボードで選択し、Enterを押すとinput上でEnterを押したことになるため、
247
230
  // submitイベントが発生し、formが送信される場合がある
248
231
  const handleKeyPress = React.useCallback((e) => {
249
232
  if (e.key === 'Enter')
250
233
  e.preventDefault();
251
- unstableRef.current.onKeyPress?.(e);
252
- }, []);
234
+ latest.onKeyPress?.(e);
235
+ }, [latest]);
253
236
  const caretIconColor = isFocused
254
237
  ? theme.textColor.black
255
238
  : disabled || readOnly
@@ -1 +1 @@
1
- {"version":3,"file":"SingleCombobox.cjs","sources":["../../../../src/components/Combobox/SingleCombobox/SingleCombobox.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n type RefObject,\n memo,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useClick } from '../../../hooks/useClick'\nimport { useTheme } from '../../../hooks/useTheme'\nimport { useIntl } from '../../../intl'\nimport { genericsForwardRef } from '../../../libs/util'\nimport { UnstyledButton } from '../../Button'\nimport { FaCaretDownIcon, FaCircleXmarkIcon } from '../../Icon'\nimport { Input } from '../../Input'\nimport { useListbox } from '../useListbox'\nimport { useSingleOptions } from '../useOptions'\n\nimport type { ComboboxItem, AbstractProps as ComboboxProps } from '../types'\n\ntype AbstractProps<T> = ComboboxProps<T> & {\n /**\n * 選択されているアイテム\n */\n selectedItem: ComboboxItem<T> | null\n /**\n * デフォルトで選択されるアイテム\n */\n defaultItem?: ComboboxItem<T>\n /**\n * コンポーネント内の先頭に表示する内容\n */\n prefix?: ReactNode\n /**\n * 選択されているアイテムがクリアされた時に発火するコールバック関数\n */\n onClear?: () => void\n /**\n * 選択されているアイテムがクリアされた時に発火するコールバック関数\n * 指定している場合、クリア時にonClickを実行せずにonClearClickのみ実行する\n */\n onClearClick?: (e: MouseEvent) => void\n /**\n * 選択されているアイテムのリストが変わった時に発火するコールバック関数\n */\n onChangeSelected?: (selectedItem: ComboboxItem<T> | null) => void\n /**\n * コンポーネントがフォーカスされたときに発火するコールバック関数\n */\n onFocus?: () => void\n /**\n * コンポーネントからフォーカスが外れた時に発火するコールバック関数\n */\n onBlur?: () => void\n /**\n * 検索結果が0件の時に表示するコンテンツ\n */\n noResultText?: ReactNode\n}\ntype Props<T> = AbstractProps<T> &\n Omit<ComponentPropsWithoutRef<'input'>, keyof AbstractProps<unknown>>\n\nconst NOOP = () => undefined\n\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\nconst ARROW_UP_DOWN_REGEX = /^(Arrow)?(Up|Down)$/\n\nconst EMPTY_INPUT_CHANGE_EVENT = {\n currentTarget: { value: '' },\n target: { value: '' },\n} as ChangeEvent<HTMLInputElement>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: 'smarthr-ui-SingleCombobox shr-inline-block',\n input: 'smarthr-ui-SingleCombobox-input shr-w-full',\n caretDownLayout: [\n 'shr-relative -shr-me-0.5 shr-p-0.5',\n 'before:shr-border-0',\n 'before:shr-absolute before:shr-inset-x-0 before:shr-inset-y-0.25 before:shr-w-0 before:shr-border-l before:shr-border-solid before:shr-border-default before:shr-content-[\"\"]',\n ],\n caretDownIcon: 'shr-block',\n clearButton: [\n 'smarthr-ui-SingleCombobox-clearButton',\n 'shr-group/clearButton',\n 'shr-me-0.5',\n 'focus-visible:shr-shadow-none',\n ],\n clearButtonIcon: [\n 'shr-block',\n 'group-focus-visible/clearButton:shr-focus-indicator group-focus-visible/clearButton:shr-rounded-full',\n ],\n },\n variants: {\n disabled: {\n true: {\n wrapper: 'shr-cursor-not-allowed',\n },\n },\n hidden: {\n true: {\n clearButton: 'shr-hidden',\n },\n },\n },\n})\n\ntype SuffixButtonsProps = {\n onClickClear: (e: MouseEvent) => void\n clearButtonRef: RefObject<HTMLButtonElement>\n onClickIcon: (e: MouseEvent) => void\n caretIconColor: string\n destroyButtonIconAlt: string\n classNames: {\n clearButton: string\n clearButtonIcon: string\n caretDownLayout: string\n caretDownIcon: string\n }\n}\n\nconst SuffixButtons = memo<SuffixButtonsProps>(\n ({\n onClickClear,\n clearButtonRef,\n onClickIcon: onDelegateClickIcon,\n caretIconColor,\n destroyButtonIconAlt,\n classNames,\n }) => (\n <>\n <UnstyledButton\n onClick={onClickClear}\n ref={clearButtonRef}\n className={classNames.clearButton}\n >\n <FaCircleXmarkIcon\n color=\"TEXT_BLACK\"\n alt={destroyButtonIconAlt}\n className={classNames.clearButtonIcon}\n />\n </UnstyledButton>\n <span\n role=\"presentation\"\n onClick={onDelegateClickIcon}\n className={classNames.caretDownLayout}\n >\n <FaCaretDownIcon color={caretIconColor} className={classNames.caretDownIcon} />\n </span>\n </>\n ),\n)\n\nconst ActualSingleCombobox = <T,>(\n {\n items,\n selectedItem,\n defaultItem,\n name,\n disabled,\n readOnly,\n required,\n prefix,\n error,\n creatable,\n placeholder,\n autoComplete,\n dropdownHelpMessage,\n isLoading,\n width,\n dropdownWidth = 'auto',\n className,\n onChange,\n onChangeInput,\n onAdd,\n onSelect,\n onClear,\n onClearClick,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n noResultText,\n style,\n ...rest\n }: Props<T>,\n ref: Ref<HTMLInputElement>,\n) => {\n const theme = useTheme()\n const { localize } = useIntl()\n const outerRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const clearButtonRef = useRef<HTMLButtonElement>(null)\n const [isFocused, setIsFocused] = useState(false)\n const [isExpanded, setIsExpanded] = useState(false)\n const [inputValue, setInputValue] = useState('')\n const [isComposing, setIsComposing] = useState(false)\n const [isEditing, setIsEditing] = useState(false)\n\n const unstableRef = useRef({\n onChange,\n onChangeInput,\n onAdd,\n onSelect,\n onClear,\n onClearClick,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n defaultItem,\n selectedItem,\n isFocused,\n isExpanded,\n isComposing,\n isEditing,\n })\n unstableRef.current = {\n onChange,\n onChangeInput,\n onAdd,\n onSelect,\n onClear,\n onClearClick,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n defaultItem,\n selectedItem,\n isFocused,\n isExpanded,\n isComposing,\n isEditing,\n }\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(ref, () => inputRef.current)\n\n const { options } = useSingleOptions({\n items,\n selected: selectedItem,\n creatable,\n inputValue,\n isFilteringDisabled: !isEditing,\n })\n\n const { renderListBox, activeOption, onKeyDownListBox, listBoxId, listBoxRef } = useListbox<T>({\n options,\n dropdownHelpMessage,\n dropdownWidth,\n onAdd,\n onSelect: useCallback((selected: ComboboxItem<T>) => {\n unstableRef.current.onSelect?.(selected)\n unstableRef.current.onChangeSelected?.(selected)\n\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n setIsExpanded(false)\n // HINT:\n // - 制御コンポーネントの場合に親側でinputValueを更新できるように、選択時にonChangeInputを空文字で発火する\n // - 対応するdropdownを閉じて以降にonChangeInputを発火する必要がある\n // - 先にclearしてしまうと意図せずこの要素のドロップダウンを閉じる前に他要素の再レンダリングを引き起こす可能性がある\n // - 例えばFilterDropdownなどで当comboboxを使っている場合、レイアウト上comboboxのdropdown以下の要素がクリックされた扱いになってしまい\n // FilterDropdownを意図せず閉じてしまうなどの挙動のバグを引き起こす可能性がある\n unstableRef.current.onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT)\n })\n\n setIsEditing(false)\n }, []),\n isExpanded,\n isLoading,\n triggerRef: outerRef,\n noResultText,\n })\n\n const selectDefaultItem = useCallback(() => {\n if (unstableRef.current.onSelect && unstableRef.current.defaultItem) {\n unstableRef.current.onSelect(unstableRef.current.defaultItem)\n }\n }, [])\n\n const focus = useCallback(() => {\n unstableRef.current.onFocus?.()\n inputRef.current?.focus()\n setIsFocused(true)\n\n if (!unstableRef.current.isFocused) {\n setIsExpanded(true)\n }\n }, [])\n const unfocus = useCallback(() => {\n if (!unstableRef.current.isFocused) return\n\n unstableRef.current.onBlur?.()\n\n setIsFocused(false)\n setIsExpanded(false)\n setIsEditing(false)\n\n if (unstableRef.current.selectedItem) {\n setInputValue(innerText(unstableRef.current.selectedItem.label))\n } else {\n selectDefaultItem()\n }\n }, [selectDefaultItem])\n const onClickClear = useCallback((e: MouseEvent) => {\n e.stopPropagation()\n\n let isExecutedPreventDefault = false\n\n unstableRef.current.onClearClick?.({\n ...e,\n preventDefault: () => {\n e.preventDefault()\n isExecutedPreventDefault = true\n },\n })\n\n if (!isExecutedPreventDefault) {\n unstableRef.current.onClear?.()\n unstableRef.current.onChangeSelected?.(null)\n\n inputRef.current?.focus()\n\n setIsFocused(true)\n setIsExpanded(true)\n }\n }, [])\n const onClickInput = useCallback(\n (e: MouseEvent) => {\n if (disabled || readOnly) {\n e.stopPropagation()\n\n return\n }\n\n inputRef.current?.focus()\n\n if (!unstableRef.current.isExpanded) {\n setIsExpanded(true)\n }\n },\n [disabled, readOnly],\n )\n const actualOnChangeInput = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n unstableRef.current.onChange?.(e)\n unstableRef.current.onChangeInput?.(e)\n\n if (!unstableRef.current.isEditing) setIsEditing(true)\n\n const { value } = e.currentTarget\n\n setInputValue(value)\n\n if (value === '') {\n unstableRef.current.onClear?.()\n unstableRef.current.onChangeSelected?.(null)\n }\n }, [])\n const onCompositionStart = useCallback(() => setIsComposing(true), [])\n const onCompositionEnd = useCallback(() => setIsComposing(false), [])\n const onKeyDownInput = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (unstableRef.current.isComposing) {\n return\n }\n\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n if (unstableRef.current.isExpanded) {\n e.stopPropagation()\n setIsExpanded(false)\n }\n } else if (e.key === 'Tab') {\n unfocus()\n } else {\n if (ARROW_UP_DOWN_REGEX.test(e.key)) {\n e.preventDefault()\n }\n\n inputRef.current?.focus()\n\n if (!unstableRef.current.isExpanded) {\n setIsExpanded(true)\n }\n }\n onKeyDownListBox(e)\n },\n [unfocus, onKeyDownListBox],\n )\n\n // HINT: form内にcomboboxを設置 & 検索inputにfocusした状態で\n // アイテムをキーボードで選択し、Enterを押すとinput上でEnterを押したことになるため、\n // submitイベントが発生し、formが送信される場合がある\n const handleKeyPress = useCallback((e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') e.preventDefault()\n\n unstableRef.current.onKeyPress?.(e)\n }, [])\n\n const caretIconColor = isFocused\n ? theme.textColor.black\n : disabled || readOnly\n ? theme.textColor.disabled\n : theme.textColor.grey\n\n useClick(\n useMemo(() => [outerRef, listBoxRef, clearButtonRef], [listBoxRef]),\n isFocused || selectedItem ? NOOP : selectDefaultItem,\n unfocus,\n )\n\n // selectedItem.label はプリミティブ値でないデータ型の可能性があり、そのまま useEffect の依存配列に入れると意図せぬエフェクトの実行を引き起こしてしまう可能性があるので、プリミティブ値である string 型に変換したものを依存配列に入れています。\n const selectedItemLabelText = innerText(selectedItem?.label)\n useEffect(() => {\n setInputValue(selectedItemLabelText)\n }, [selectedItemLabelText])\n\n const wrapperStyle = useMemo(\n () => ({\n ...style,\n width: typeof width === 'number' ? `${width}px` : width,\n }),\n [style, width],\n )\n\n const hasSelectedItem = selectedItem !== null\n\n const classNames = useMemo(() => {\n const { wrapper, input, caretDownLayout, caretDownIcon, clearButton, clearButtonIcon } =\n classNameGenerator()\n\n return {\n wrapper: wrapper({ disabled, className }),\n input: input(),\n caretDownLayout: caretDownLayout(),\n caretDownIcon: caretDownIcon(),\n clearButton: clearButton({\n hidden: !hasSelectedItem || disabled || readOnly,\n }),\n clearButtonIcon: clearButtonIcon(),\n }\n }, [hasSelectedItem, disabled, readOnly, className])\n\n const destroyButtonIconAlt = useMemo(\n () =>\n localize({\n id: 'smarthr-ui/SingleCombobox/destroyButtonIconAlt',\n defaultText: 'クリア',\n }),\n [localize],\n )\n\n return (\n <div role=\"group\" className={classNames.wrapper} style={wrapperStyle} ref={outerRef}>\n <Input\n {...rest}\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n name={name}\n value={inputValue}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoComplete={autoComplete ?? 'off'}\n aria-haspopup=\"listbox\"\n aria-controls={listBoxId}\n aria-expanded={isFocused}\n aria-activedescendant={activeOption?.id}\n aria-autocomplete=\"list\"\n /* eslint-disable-next-line smarthr/a11y-prohibit-input-placeholder */\n placeholder={placeholder}\n onClick={onClickInput}\n onChange={actualOnChangeInput}\n onFocus={isFocused ? undefined : focus}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n onKeyDown={onKeyDownInput}\n onKeyPress={handleKeyPress}\n error={error}\n prefix={prefix}\n suffix={\n <SuffixButtons\n onClickClear={onClickClear}\n clearButtonRef={clearButtonRef}\n onClickIcon={onClickInput}\n caretIconColor={caretIconColor}\n destroyButtonIconAlt={destroyButtonIconAlt}\n classNames={{\n clearButton: classNames.clearButton,\n clearButtonIcon: classNames.clearButtonIcon,\n caretDownLayout: classNames.caretDownLayout,\n caretDownIcon: classNames.caretDownIcon,\n }}\n />\n }\n className={classNames.input}\n data-smarthr-ui-input=\"true\"\n />\n {!readOnly && renderListBox()}\n </div>\n )\n}\n\nexport const SingleCombobox = genericsForwardRef(ActualSingleCombobox)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA2EA;AAEA;AACA;AAEA;AACE;AACA;;AAGF;AACE;AACE;AACA;AACA;;;;AAIC;AACD;AACA;;;;;AAKC;AACD;;;AAGC;AACF;AACD;AACE;AACE;AACE;AACD;AACF;AACD;AACE;AACE;AACD;AACF;AACF;AACF;AAgBD;AAgCA;AAmCE;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;AAwBC;;;;;;;;;;;;;;;;;;;;AAsBD;;AAEE;;;;AAID;AAED;;;;;AAKE;;;;;;;;;;;;;;AAeE;;;;;AAMF;;AAED;AAED;AACE;;;;AAKF;AACE;AACA;;AAGA;;;;AAIF;AACE;;AAEA;;;;AAMA;AACE;;;AAEA;;AAEJ;AACA;;;AAKE;AACE;;;;;AAKD;;AAGC;;AAGA;;;;;AAMJ;AAEI;;;;AAMA;AAEA;;;AAGF;AAGF;;;AAIE;;AAEA;;AAIA;AACE;;;;AAIJ;AACA;AACA;AAEI;;;;AAKE;;;;;AAIK;AACL;;;;;;AAMA;AAEA;;;;;AAKJ;;;;AAOF;AACE;;;;;AAMA;;AAEE;AACA;AAEJ;;;;;AAUA;AAEA;AAEI;AACA;AACD;AAIH;AAEA;AACE;;;;;;;AASI;;;;;;AASA;AACA;AACD;AAIL;;AAmBM;;;;;AAsBK;AASb;;;"}
1
+ {"version":3,"file":"SingleCombobox.cjs","sources":["../../../../src/components/Combobox/SingleCombobox/SingleCombobox.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n type RefObject,\n memo,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useClick } from '../../../hooks/useClick'\nimport { useLatest } from '../../../hooks/useLatest'\nimport { useTheme } from '../../../hooks/useTheme'\nimport { useIntl } from '../../../intl'\nimport { genericsForwardRef } from '../../../libs/util'\nimport { UnstyledButton } from '../../Button'\nimport { FaCaretDownIcon, FaCircleXmarkIcon } from '../../Icon'\nimport { Input } from '../../Input'\nimport { useListbox } from '../useListbox'\nimport { useSingleOptions } from '../useOptions'\n\nimport type { ComboboxItem, AbstractProps as ComboboxProps } from '../types'\n\ntype AbstractProps<T> = ComboboxProps<T> & {\n /**\n * 選択されているアイテム\n */\n selectedItem: ComboboxItem<T> | null\n /**\n * デフォルトで選択されるアイテム\n */\n defaultItem?: ComboboxItem<T>\n /**\n * コンポーネント内の先頭に表示する内容\n */\n prefix?: ReactNode\n /**\n * 選択されているアイテムがクリアされた時に発火するコールバック関数\n */\n onClear?: () => void\n /**\n * 選択されているアイテムがクリアされた時に発火するコールバック関数\n * 指定している場合、クリア時にonClickを実行せずにonClearClickのみ実行する\n */\n onClearClick?: (e: MouseEvent) => void\n /**\n * 選択されているアイテムのリストが変わった時に発火するコールバック関数\n */\n onChangeSelected?: (selectedItem: ComboboxItem<T> | null) => void\n /**\n * コンポーネントがフォーカスされたときに発火するコールバック関数\n */\n onFocus?: () => void\n /**\n * コンポーネントからフォーカスが外れた時に発火するコールバック関数\n */\n onBlur?: () => void\n /**\n * 検索結果が0件の時に表示するコンテンツ\n */\n noResultText?: ReactNode\n}\ntype Props<T> = AbstractProps<T> &\n Omit<ComponentPropsWithoutRef<'input'>, keyof AbstractProps<unknown>>\n\nconst NOOP = () => undefined\n\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\nconst ARROW_UP_DOWN_REGEX = /^(Arrow)?(Up|Down)$/\n\nconst EMPTY_INPUT_CHANGE_EVENT = {\n currentTarget: { value: '' },\n target: { value: '' },\n} as ChangeEvent<HTMLInputElement>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: 'smarthr-ui-SingleCombobox shr-inline-block',\n input: 'smarthr-ui-SingleCombobox-input shr-w-full',\n caretDownLayout: [\n 'shr-relative -shr-me-0.5 shr-p-0.5',\n 'before:shr-border-0',\n 'before:shr-absolute before:shr-inset-x-0 before:shr-inset-y-0.25 before:shr-w-0 before:shr-border-l before:shr-border-solid before:shr-border-default before:shr-content-[\"\"]',\n ],\n caretDownIcon: 'shr-block',\n clearButton: [\n 'smarthr-ui-SingleCombobox-clearButton',\n 'shr-group/clearButton',\n 'shr-me-0.5',\n 'focus-visible:shr-shadow-none',\n ],\n clearButtonIcon: [\n 'shr-block',\n 'group-focus-visible/clearButton:shr-focus-indicator group-focus-visible/clearButton:shr-rounded-full',\n ],\n },\n variants: {\n disabled: {\n true: {\n wrapper: 'shr-cursor-not-allowed',\n },\n },\n hidden: {\n true: {\n clearButton: 'shr-hidden',\n },\n },\n },\n})\n\ntype SuffixButtonsProps = {\n onClickClear: (e: MouseEvent) => void\n clearButtonRef: RefObject<HTMLButtonElement>\n onClickIcon: (e: MouseEvent) => void\n caretIconColor: string\n destroyButtonIconAlt: string\n classNames: {\n clearButton: string\n clearButtonIcon: string\n caretDownLayout: string\n caretDownIcon: string\n }\n}\n\nconst SuffixButtons = memo<SuffixButtonsProps>(\n ({\n onClickClear,\n clearButtonRef,\n onClickIcon: onDelegateClickIcon,\n caretIconColor,\n destroyButtonIconAlt,\n classNames,\n }) => (\n <>\n <UnstyledButton\n onClick={onClickClear}\n ref={clearButtonRef}\n className={classNames.clearButton}\n >\n <FaCircleXmarkIcon\n color=\"TEXT_BLACK\"\n alt={destroyButtonIconAlt}\n className={classNames.clearButtonIcon}\n />\n </UnstyledButton>\n <span\n role=\"presentation\"\n onClick={onDelegateClickIcon}\n className={classNames.caretDownLayout}\n >\n <FaCaretDownIcon color={caretIconColor} className={classNames.caretDownIcon} />\n </span>\n </>\n ),\n)\n\nconst ActualSingleCombobox = <T,>(\n {\n items,\n selectedItem,\n defaultItem,\n name,\n disabled,\n readOnly,\n required,\n prefix,\n error,\n creatable,\n placeholder,\n autoComplete,\n dropdownHelpMessage,\n isLoading,\n width,\n dropdownWidth = 'auto',\n className,\n onChange,\n onChangeInput,\n onAdd,\n onSelect,\n onClear,\n onClearClick,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n noResultText,\n style,\n ...rest\n }: Props<T>,\n ref: Ref<HTMLInputElement>,\n) => {\n const theme = useTheme()\n const { localize } = useIntl()\n const outerRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const clearButtonRef = useRef<HTMLButtonElement>(null)\n const [isFocused, setIsFocused] = useState(false)\n const [isExpanded, setIsExpanded] = useState(false)\n const [inputValue, setInputValue] = useState('')\n const [isComposing, setIsComposing] = useState(false)\n const [isEditing, setIsEditing] = useState(false)\n\n const latest = useLatest({\n onChange,\n onChangeInput,\n onAdd,\n onSelect,\n onClear,\n onClearClick,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n defaultItem,\n selectedItem,\n isFocused,\n isExpanded,\n isComposing,\n isEditing,\n })\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(ref, () => inputRef.current)\n\n const { options } = useSingleOptions({\n items,\n selected: selectedItem,\n creatable,\n inputValue,\n isFilteringDisabled: !isEditing,\n })\n\n const { renderListBox, activeOption, onKeyDownListBox, listBoxId, listBoxRef } = useListbox<T>({\n options,\n dropdownHelpMessage,\n dropdownWidth,\n onAdd,\n onSelect: useCallback(\n (selected: ComboboxItem<T>) => {\n latest.onSelect?.(selected)\n latest.onChangeSelected?.(selected)\n\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n setIsExpanded(false)\n // HINT:\n // - 制御コンポーネントの場合に親側でinputValueを更新できるように、選択時にonChangeInputを空文字で発火する\n // - 対応するdropdownを閉じて以降にonChangeInputを発火する必要がある\n // - 先にclearしてしまうと意図せずこの要素のドロップダウンを閉じる前に他要素の再レンダリングを引き起こす可能性がある\n // - 例えばFilterDropdownなどで当comboboxを使っている場合、レイアウト上comboboxのdropdown以下の要素がクリックされた扱いになってしまい\n // FilterDropdownを意図せず閉じてしまうなどの挙動のバグを引き起こす可能性がある\n latest.onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT)\n })\n\n setIsEditing(false)\n },\n [latest],\n ),\n isExpanded,\n isLoading,\n triggerRef: outerRef,\n noResultText,\n })\n\n const selectDefaultItem = useCallback(() => {\n if (latest.onSelect && latest.defaultItem) {\n latest.onSelect(latest.defaultItem)\n }\n }, [latest])\n\n const focus = useCallback(() => {\n latest.onFocus?.()\n inputRef.current?.focus()\n setIsFocused(true)\n\n if (!latest.isFocused) {\n setIsExpanded(true)\n }\n }, [latest])\n const unfocus = useCallback(() => {\n if (!latest.isFocused) return\n\n latest.onBlur?.()\n\n setIsFocused(false)\n setIsExpanded(false)\n setIsEditing(false)\n\n if (latest.selectedItem) {\n setInputValue(innerText(latest.selectedItem.label))\n } else {\n selectDefaultItem()\n }\n }, [selectDefaultItem, latest])\n const onClickClear = useCallback(\n (e: MouseEvent) => {\n e.stopPropagation()\n\n let isExecutedPreventDefault = false\n\n latest.onClearClick?.({\n ...e,\n preventDefault: () => {\n e.preventDefault()\n isExecutedPreventDefault = true\n },\n })\n\n if (!isExecutedPreventDefault) {\n latest.onClear?.()\n latest.onChangeSelected?.(null)\n\n inputRef.current?.focus()\n\n setIsFocused(true)\n setIsExpanded(true)\n }\n },\n [latest],\n )\n const onClickInput = useCallback(\n (e: MouseEvent) => {\n if (disabled || readOnly) {\n e.stopPropagation()\n\n return\n }\n\n inputRef.current?.focus()\n\n if (!latest.isExpanded) {\n setIsExpanded(true)\n }\n },\n [disabled, readOnly, latest],\n )\n const actualOnChangeInput = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n latest.onChange?.(e)\n latest.onChangeInput?.(e)\n\n if (!latest.isEditing) setIsEditing(true)\n\n const { value } = e.currentTarget\n\n setInputValue(value)\n\n if (value === '') {\n latest.onClear?.()\n latest.onChangeSelected?.(null)\n }\n },\n [latest],\n )\n const onCompositionStart = useCallback(() => setIsComposing(true), [])\n const onCompositionEnd = useCallback(() => setIsComposing(false), [])\n const onKeyDownInput = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (latest.isComposing) {\n return\n }\n\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n if (latest.isExpanded) {\n e.stopPropagation()\n setIsExpanded(false)\n }\n } else if (e.key === 'Tab') {\n unfocus()\n } else {\n if (ARROW_UP_DOWN_REGEX.test(e.key)) {\n e.preventDefault()\n }\n\n inputRef.current?.focus()\n\n if (!latest.isExpanded) {\n setIsExpanded(true)\n }\n }\n onKeyDownListBox(e)\n },\n [unfocus, onKeyDownListBox, latest],\n )\n\n // HINT: form内にcomboboxを設置 & 検索inputにfocusした状態で\n // アイテムをキーボードで選択し、Enterを押すとinput上でEnterを押したことになるため、\n // submitイベントが発生し、formが送信される場合がある\n const handleKeyPress = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') e.preventDefault()\n\n latest.onKeyPress?.(e)\n },\n [latest],\n )\n\n const caretIconColor = isFocused\n ? theme.textColor.black\n : disabled || readOnly\n ? theme.textColor.disabled\n : theme.textColor.grey\n\n useClick(\n useMemo(() => [outerRef, listBoxRef, clearButtonRef], [listBoxRef]),\n isFocused || selectedItem ? NOOP : selectDefaultItem,\n unfocus,\n )\n\n // selectedItem.label はプリミティブ値でないデータ型の可能性があり、そのまま useEffect の依存配列に入れると意図せぬエフェクトの実行を引き起こしてしまう可能性があるので、プリミティブ値である string 型に変換したものを依存配列に入れています。\n const selectedItemLabelText = innerText(selectedItem?.label)\n useEffect(() => {\n setInputValue(selectedItemLabelText)\n }, [selectedItemLabelText])\n\n const wrapperStyle = useMemo(\n () => ({\n ...style,\n width: typeof width === 'number' ? `${width}px` : width,\n }),\n [style, width],\n )\n\n const hasSelectedItem = selectedItem !== null\n\n const classNames = useMemo(() => {\n const { wrapper, input, caretDownLayout, caretDownIcon, clearButton, clearButtonIcon } =\n classNameGenerator()\n\n return {\n wrapper: wrapper({ disabled, className }),\n input: input(),\n caretDownLayout: caretDownLayout(),\n caretDownIcon: caretDownIcon(),\n clearButton: clearButton({\n hidden: !hasSelectedItem || disabled || readOnly,\n }),\n clearButtonIcon: clearButtonIcon(),\n }\n }, [hasSelectedItem, disabled, readOnly, className])\n\n const destroyButtonIconAlt = useMemo(\n () =>\n localize({\n id: 'smarthr-ui/SingleCombobox/destroyButtonIconAlt',\n defaultText: 'クリア',\n }),\n [localize],\n )\n\n return (\n <div role=\"group\" className={classNames.wrapper} style={wrapperStyle} ref={outerRef}>\n <Input\n {...rest}\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n name={name}\n value={inputValue}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoComplete={autoComplete ?? 'off'}\n aria-haspopup=\"listbox\"\n aria-controls={listBoxId}\n aria-expanded={isFocused}\n aria-activedescendant={activeOption?.id}\n aria-autocomplete=\"list\"\n /* eslint-disable-next-line smarthr/a11y-prohibit-input-placeholder */\n placeholder={placeholder}\n onClick={onClickInput}\n onChange={actualOnChangeInput}\n onFocus={isFocused ? undefined : focus}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n onKeyDown={onKeyDownInput}\n onKeyPress={handleKeyPress}\n error={error}\n prefix={prefix}\n suffix={\n <SuffixButtons\n onClickClear={onClickClear}\n clearButtonRef={clearButtonRef}\n onClickIcon={onClickInput}\n caretIconColor={caretIconColor}\n destroyButtonIconAlt={destroyButtonIconAlt}\n classNames={{\n clearButton: classNames.clearButton,\n clearButtonIcon: classNames.clearButtonIcon,\n caretDownLayout: classNames.caretDownLayout,\n caretDownIcon: classNames.caretDownIcon,\n }}\n />\n }\n className={classNames.input}\n data-smarthr-ui-input=\"true\"\n />\n {!readOnly && renderListBox()}\n </div>\n )\n}\n\nexport const SingleCombobox = genericsForwardRef(ActualSingleCombobox)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA;AAEA;AACA;AAEA;AACE;AACA;;AAGF;AACE;AACE;AACA;AACA;;;;AAIC;AACD;AACA;;;;;AAKC;AACD;;;AAGC;AACF;AACD;AACE;AACE;AACE;AACD;AACF;AACD;AACE;AACE;AACD;AACF;AACF;AACF;AAgBD;AAgCA;AAmCE;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;AAwBC;;AAID;;AAEE;;;;AAID;AAED;;;;;AAKE;AAEI;AACA;;;;;;;;;;;AAYE;AACF;;AAGF;;;AAKF;;AAED;AAED;;AAEI;;AAEJ;AAEA;AACE;AACA;;AAGA;;;AAGF;AACA;;;AAGE;;;;AAMA;;;;AAGE;;AAEJ;AACA;;;;AAOM;;;;;AAKD;;AAGC;AACA;AAEA;;;;AAKJ;AAGF;AAEI;;;;AAMA;AAEA;;;;AAMJ;AAEI;AACA;;;AAIA;;AAIA;AACE;AACA;;AAEJ;AAGF;AACA;AACA;AAEI;;;;AAKE;;;;;AAIK;AACL;;;;;;AAMA;AAEA;;;;;;;;;AAYN;AAEI;;AAEA;AACF;;AAKA;;AAEE;AACA;AAEJ;;;;;AAUA;AAEA;AAEI;AACA;AACD;AAIH;AAEA;AACE;;;;;;;AASI;;;;;;AASA;AACA;AACD;AAIL;;AAmBM;;;;;AAsBK;AASb;;;"}