@geckou/ui-react 0.1.0 → 0.2.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 (103) hide show
  1. package/README.md +46 -5
  2. package/dist/components/BasicButton.d.ts +14 -0
  3. package/dist/components/BasicButton.js +57 -0
  4. package/dist/components/CheckBox.d.ts +13 -0
  5. package/dist/components/CheckBox.js +74 -0
  6. package/dist/components/CheckBoxes.d.ts +12 -0
  7. package/dist/components/CheckBoxes.js +68 -0
  8. package/dist/components/CheckButton.d.ts +13 -0
  9. package/dist/components/CheckButton.js +56 -0
  10. package/dist/components/DatePicker.d.ts +18 -0
  11. package/dist/components/DatePicker.js +131 -0
  12. package/dist/components/DateRangePicker.d.ts +22 -0
  13. package/dist/components/DateRangePicker.js +65 -0
  14. package/dist/components/DateSelector.d.ts +13 -0
  15. package/dist/components/DateSelector.js +129 -0
  16. package/dist/components/DropdownUi.d.ts +16 -0
  17. package/dist/components/DropdownUi.js +88 -0
  18. package/dist/components/ErrorMessage.d.ts +9 -0
  19. package/dist/components/ErrorMessage.js +21 -0
  20. package/dist/components/FileInput.d.ts +7 -0
  21. package/dist/components/FileInput.js +91 -0
  22. package/dist/components/InputBox.d.ts +11 -0
  23. package/dist/components/InputBox.js +75 -0
  24. package/dist/components/InputGroup.d.ts +6 -0
  25. package/dist/components/InputGroup.js +7 -0
  26. package/dist/components/LabeledCheckbox.d.ts +12 -0
  27. package/dist/components/LabeledCheckbox.js +46 -0
  28. package/dist/components/LabeledFieldset.d.ts +8 -0
  29. package/dist/components/LabeledFieldset.js +10 -0
  30. package/dist/components/LoadingSpinner.d.ts +1 -0
  31. package/dist/components/LoadingSpinner.js +26 -0
  32. package/dist/components/ModalBox.d.ts +12 -0
  33. package/dist/components/ModalBox.js +83 -0
  34. package/dist/components/PopupBox.d.ts +14 -0
  35. package/dist/components/PopupBox.js +41 -0
  36. package/dist/components/RadioButtons.d.ts +13 -0
  37. package/dist/components/RadioButtons.js +64 -0
  38. package/dist/components/SearchableSelectBox.d.ts +14 -0
  39. package/dist/components/SearchableSelectBox.js +61 -0
  40. package/dist/components/SelectBox.d.ts +16 -0
  41. package/dist/components/SelectBox.js +107 -0
  42. package/dist/components/SlideDownUi.d.ts +17 -0
  43. package/dist/components/SlideDownUi.js +86 -0
  44. package/dist/components/TabUI.d.ts +19 -0
  45. package/dist/components/TabUI.js +76 -0
  46. package/dist/components/TextArea.d.ts +18 -0
  47. package/dist/components/TextArea.js +75 -0
  48. package/dist/components/TextBox.d.ts +20 -0
  49. package/dist/components/TextBox.js +90 -0
  50. package/dist/components/ToggleButton.d.ts +15 -0
  51. package/dist/components/ToggleButton.js +92 -0
  52. package/dist/components/icons/BackupIcon.d.ts +5 -0
  53. package/dist/components/icons/BackupIcon.js +16 -0
  54. package/dist/components/icons/CalendarIcon.d.ts +5 -0
  55. package/dist/components/icons/CalendarIcon.js +15 -0
  56. package/dist/components/icons/CheckIcon.d.ts +1 -0
  57. package/dist/components/icons/CheckIcon.js +7 -0
  58. package/dist/components/icons/CloseIcon.d.ts +5 -0
  59. package/dist/components/icons/CloseIcon.js +16 -0
  60. package/dist/components/icons/KeyboardArrowDownIcon.d.ts +5 -0
  61. package/dist/components/icons/KeyboardArrowDownIcon.js +16 -0
  62. package/dist/constants/index.d.ts +1 -0
  63. package/dist/hooks/useFormValidation.d.ts +33 -0
  64. package/dist/hooks/useFormValidation.js +28 -0
  65. package/dist/index.d.ts +38 -0
  66. package/dist/index.js +70 -0
  67. package/{src → dist}/styles/tokens.css +1 -1
  68. package/dist/types/index.d.ts +1 -0
  69. package/package.json +17 -12
  70. package/src/components/BasicButton.tsx +0 -81
  71. package/src/components/CheckBox.tsx +0 -87
  72. package/src/components/CheckBoxes.tsx +0 -93
  73. package/src/components/CheckButton.tsx +0 -66
  74. package/src/components/DatePicker.tsx +0 -154
  75. package/src/components/DateRangePicker.tsx +0 -59
  76. package/src/components/DateSelector.tsx +0 -162
  77. package/src/components/DropdownUi.tsx +0 -126
  78. package/src/components/ErrorMessage.tsx +0 -30
  79. package/src/components/FileInput.tsx +0 -93
  80. package/src/components/InputBox.tsx +0 -118
  81. package/src/components/InputGroup.tsx +0 -13
  82. package/src/components/LabeledCheckbox.tsx +0 -61
  83. package/src/components/LabeledFieldset.tsx +0 -18
  84. package/src/components/LoadingSpinner.tsx +0 -23
  85. package/src/components/ModalBox.tsx +0 -109
  86. package/src/components/PopupBox.tsx +0 -70
  87. package/src/components/RadioButtons.tsx +0 -94
  88. package/src/components/SearchableSelectBox.tsx +0 -108
  89. package/src/components/SelectBox.tsx +0 -152
  90. package/src/components/SlideDownUi.tsx +0 -123
  91. package/src/components/TabUI.tsx +0 -112
  92. package/src/components/TextArea.tsx +0 -102
  93. package/src/components/TextBox.tsx +0 -120
  94. package/src/components/ToggleButton.tsx +0 -102
  95. package/src/components/icons/BackupIcon.tsx +0 -16
  96. package/src/components/icons/CalendarIcon.tsx +0 -15
  97. package/src/components/icons/CheckIcon.tsx +0 -7
  98. package/src/components/icons/CloseIcon.tsx +0 -16
  99. package/src/components/icons/KeyboardArrowDownIcon.tsx +0 -16
  100. package/src/constants/index.ts +0 -2
  101. package/src/hooks/useFormValidation.ts +0 -69
  102. package/src/index.ts +0 -66
  103. package/src/types/index.ts +0 -23
@@ -1,81 +0,0 @@
1
- 'use client'
2
-
3
- import type { CSSProperties, MouseEventHandler, ReactNode } from 'react'
4
- import type { ButtonStyleForEachStatus } from '../types'
5
- import { LoadingSpinner } from './LoadingSpinner'
6
- import { COLOR } from '../constants'
7
-
8
- type Props = {
9
- cssStyle?: ButtonStyleForEachStatus
10
- duration?: number
11
- isLoading?: boolean
12
- isDisabled?: boolean
13
- buttonType?: 'button' | 'submit' | 'reset'
14
- onClick?: MouseEventHandler<HTMLButtonElement>
15
- loading?: ReactNode
16
- children?: ReactNode
17
- }
18
-
19
- export function BasicButton({
20
- cssStyle,
21
- duration = 0.3,
22
- isLoading,
23
- isDisabled,
24
- buttonType = 'button',
25
- onClick,
26
- loading,
27
- children,
28
- }: Props) {
29
- const baseStyle = isDisabled ? cssStyle?.disabled : cssStyle?.default
30
-
31
- const currentCssStyle = {
32
- textColor: COLOR.white,
33
- backgroundColor: isDisabled ? COLOR.darkGray : COLOR.blue,
34
- backgroundImage: 'none',
35
- border: {
36
- color: isDisabled ? COLOR.darkGray : COLOR.blue,
37
- size: '1px',
38
- radius: '.25rem',
39
- },
40
- boxShadow: '0 0 0 0 transparent',
41
- ...baseStyle,
42
- }
43
-
44
- const hoverStyle = cssStyle?.hover || {}
45
-
46
- const style = {
47
- '--text-color': currentCssStyle.textColor,
48
- '--background-color': currentCssStyle.backgroundColor,
49
- '--background-image': currentCssStyle.backgroundImage,
50
- '--radius-size': currentCssStyle.border?.radius,
51
- '--button-shadow': `0 0 0 ${currentCssStyle.border?.size} ${currentCssStyle.border?.color} inset, ${currentCssStyle.boxShadow}`,
52
- '--hover-text-color': hoverStyle.textColor || currentCssStyle.textColor,
53
- '--hover-background-color':
54
- hoverStyle.backgroundColor ||
55
- (currentCssStyle.backgroundColor &&
56
- `${currentCssStyle.backgroundColor}cc`),
57
- '--hover-background-image':
58
- hoverStyle.backgroundImage || currentCssStyle.backgroundImage,
59
- '--hover-radius-size':
60
- hoverStyle.border?.radius || currentCssStyle.border?.radius,
61
- '--hover-button-shadow': `0 0 0 ${hoverStyle.border?.size || currentCssStyle.border?.size} ${hoverStyle.border?.color || currentCssStyle.border?.color} inset, ${hoverStyle.boxShadow || currentCssStyle.boxShadow}`,
62
- '--duration': `${duration}s`,
63
- } as CSSProperties
64
-
65
- return (
66
- <button
67
- type={buttonType}
68
- disabled={isDisabled || isLoading}
69
- onClick={onClick}
70
- style={style}
71
- className="relative inline-flex w-max cursor-pointer items-center justify-center rounded-(--radius-size) border-none bg-(--background-color) px-8 py-4 leading-none text-(--text-color) shadow-(--button-shadow) transition-all duration-(--duration) enabled:hover:rounded-(--hover-radius-size) enabled:hover:bg-(--hover-background-color) enabled:hover:text-(--hover-text-color) enabled:hover:shadow-(--hover-button-shadow) disabled:pointer-events-none disabled:before:pointer-events-auto disabled:before:absolute disabled:before:inset-0 disabled:before:cursor-not-allowed disabled:before:content-['']"
72
- >
73
- {isLoading && (
74
- <span className="absolute inset-0 m-auto flex max-h-[calc(100%-1.5rem)] items-center justify-center fill-current text-current [&_*]:max-h-full [&_*]:fill-current">
75
- {loading ?? <LoadingSpinner />}
76
- </span>
77
- )}
78
- <span className={isLoading ? 'invisible' : undefined}>{children}</span>
79
- </button>
80
- )
81
- }
@@ -1,87 +0,0 @@
1
- 'use client'
2
-
3
- import type { CSSProperties, ReactNode } from 'react'
4
- import type { CheckBoxStyleForEachStatus } from '../types'
5
- import { CheckIcon } from './icons/CheckIcon'
6
- import { COLOR } from '../constants'
7
-
8
- type Props = {
9
- name: string
10
- checked?: boolean
11
- onChange?: (newValue: boolean) => void
12
- isDisabled?: boolean
13
- cssStyle?: CheckBoxStyleForEachStatus
14
- isDisableAnimation?: boolean
15
- check?: ReactNode
16
- }
17
-
18
- export function CheckBox({
19
- name,
20
- checked,
21
- onChange,
22
- isDisabled,
23
- cssStyle,
24
- isDisableAnimation,
25
- check,
26
- }: Props) {
27
- const isChecked = checked ?? false
28
- const baseStyle = isDisabled ? cssStyle?.disabled : cssStyle?.default
29
-
30
- const currentCssStyle = {
31
- textColor: isDisabled ? COLOR.darkGray : COLOR.blue,
32
- backgroundColor: isDisabled ? COLOR.lightGray : COLOR.white,
33
- border: {
34
- color: isDisabled ? COLOR.darkGray : COLOR.blue,
35
- size: '1px',
36
- radius: '.25rem',
37
- },
38
- ...baseStyle,
39
- }
40
-
41
- const style = {
42
- '--text-color': currentCssStyle.textColor,
43
- '--border-color': currentCssStyle.border?.color,
44
- '--border-size': currentCssStyle.border?.size,
45
- '--radius-size': currentCssStyle.border?.radius,
46
- '--background-color': currentCssStyle.backgroundColor,
47
- '--duration': isDisableAnimation ? '0s' : '.3s',
48
- } as CSSProperties
49
-
50
- return (
51
- <>
52
- <style>
53
- {
54
- '@keyframes uiCheckPop{0%{scale:1}10%{scale:.8}50%{scale:1.1}100%{scale:1}}'
55
- }
56
- </style>
57
- <button
58
- type="button"
59
- style={style}
60
- aria-label={name}
61
- aria-pressed={isChecked}
62
- disabled={isDisabled}
63
- onClick={(event) => {
64
- event.stopPropagation()
65
- if (!isDisabled) onChange?.(!isChecked)
66
- }}
67
- className={`relative flex h-6 w-6 cursor-pointer items-center justify-center rounded-(--radius-size) border-none shadow-[0_0_0_var(--border-size)_var(--border-color)_inset] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--border-color) has-[input:disabled]:pointer-events-none has-[input:disabled]:before:pointer-events-auto has-[input:disabled]:before:absolute has-[input:disabled]:before:inset-0 has-[input:disabled]:before:cursor-not-allowed has-[input:disabled]:before:content-[''] ${isChecked ? 'animate-[uiCheckPop_var(--duration)_ease-out] bg-(--border-color)' : 'bg-(--background-color)'}`}
68
- >
69
- <input
70
- type="checkbox"
71
- name={name}
72
- checked={isChecked}
73
- disabled={isDisabled}
74
- onChange={(event) => {
75
- if (!isDisabled) onChange?.(event.target.checked)
76
- }}
77
- className="hidden"
78
- />
79
- <div
80
- className={`flex h-4 w-4 items-center justify-center [&>*]:fill-current [&>*]:text-current ${isChecked ? 'text-(--background-color)' : 'text-(--border-color)'}`}
81
- >
82
- {check ?? <CheckIcon />}
83
- </div>
84
- </button>
85
- </>
86
- )
87
- }
@@ -1,93 +0,0 @@
1
- 'use client'
2
-
3
- import type { Option, CheckBoxStyleForEachStatus } from '../types'
4
- import { MESSAGES } from '@geckou/ui-core'
5
- import { useEffect, useRef, useState } from 'react'
6
- import { LabeledCheckbox } from './LabeledCheckbox'
7
- import { ErrorMessage } from './ErrorMessage'
8
- import { COLOR } from '../constants'
9
-
10
- type Props = {
11
- name: string
12
- options: Option[]
13
- value?: string[]
14
- onChange?: (newValue: string[]) => void
15
- isDisabled?: boolean
16
- isRequired?: boolean
17
- cssStyle?: CheckBoxStyleForEachStatus
18
- }
19
-
20
- export function CheckBoxes({
21
- name,
22
- options,
23
- value,
24
- onChange,
25
- isDisabled,
26
- isRequired,
27
- cssStyle,
28
- }: Props) {
29
- const [checkedValues, setCheckedValues] = useState<string[]>(value ?? [])
30
- const [errorMessage, setErrorMessage] = useState('')
31
-
32
- const validateInput = (newValues: string[]) =>
33
- setErrorMessage(isRequired && newValues.length === 0 ? MESSAGES.required : '')
34
-
35
- const isFirstRender = useRef(true)
36
-
37
- useEffect(() => {
38
- if (isFirstRender.current) {
39
- isFirstRender.current = false
40
- if (value?.length) validateInput(value)
41
- return
42
- }
43
-
44
- if (value) setCheckedValues(value)
45
- // eslint-disable-next-line react-hooks/exhaustive-deps -- Vue 版(@geckou/ui-vue)同様、外部からの値変更時のみ同期する
46
- }, [value])
47
-
48
- const toggleValue = (optionValue: string, checked: boolean) => {
49
- const newValues = options
50
- .map((option) => String(option.value))
51
- .filter((candidate) =>
52
- candidate === optionValue ? checked : checkedValues.includes(candidate),
53
- )
54
-
55
- setCheckedValues(newValues)
56
- validateInput(newValues)
57
- onChange?.(newValues)
58
- }
59
-
60
- const errorColor = {
61
- ...(cssStyle?.error ?? {}),
62
- textColor: COLOR.white,
63
- backgroundColor: COLOR.red,
64
- border: {
65
- color: COLOR.red,
66
- size: '1px',
67
- radius: '.25rem',
68
- },
69
- }
70
-
71
- return (
72
- <div className="relative flex flex-wrap gap-x-6 gap-y-4">
73
- {options.map((option) => (
74
- <LabeledCheckbox
75
- key={option.value}
76
- name={name}
77
- label={option.label}
78
- checked={checkedValues.includes(String(option.value))}
79
- onChange={(checked) => toggleValue(String(option.value), checked)}
80
- isDisabled={isDisabled}
81
- cssStyle={cssStyle}
82
- />
83
- ))}
84
- <ErrorMessage
85
- errorMessages={errorMessage ? [errorMessage] : []}
86
- cssStyle={{
87
- textColor: errorColor.textColor,
88
- backgroundColor: errorColor.backgroundColor,
89
- }}
90
- />
91
- </div>
92
- )
93
- }
@@ -1,66 +0,0 @@
1
- 'use client'
2
-
3
- import type { CSSProperties, ReactNode } from 'react'
4
- import type { CheckBoxStyleForEachStatus } from '../types'
5
- import { CheckIcon } from './icons/CheckIcon'
6
-
7
- type Props = {
8
- name: string
9
- checked?: boolean
10
- onChange?: (newValue: boolean) => void
11
- isDisabled?: boolean
12
- cssStyle?: CheckBoxStyleForEachStatus
13
- isDisableAnimation?: boolean
14
- check?: ReactNode
15
- }
16
-
17
- export function CheckButton({
18
- name,
19
- checked,
20
- onChange,
21
- isDisabled,
22
- cssStyle = { default: {} },
23
- isDisableAnimation,
24
- check,
25
- }: Props) {
26
- const isChecked = checked ?? false
27
- const currentCssStyle = isDisabled ? cssStyle.disabled : cssStyle.default
28
-
29
- const style = {
30
- '--border-color': currentCssStyle?.border?.color || 'blue',
31
- '--border-size': currentCssStyle?.border?.size || '1px',
32
- '--radius-size': currentCssStyle?.border?.radius || '0.25rem',
33
- '--background-color': currentCssStyle?.backgroundColor || '#fff',
34
- '--duration': isDisableAnimation ? '0s' : '.3s',
35
- } as CSSProperties
36
-
37
- return (
38
- <>
39
- <style>
40
- {
41
- '@keyframes uiCheckPop{0%{scale:1}10%{scale:.8}50%{scale:1.1}100%{scale:1}}'
42
- }
43
- </style>
44
- <label
45
- style={style}
46
- className={`relative flex h-6 w-6 cursor-pointer items-center justify-center rounded-(--radius-size) shadow-[0_0_0_var(--border-size)_var(--border-color)_inset] has-[input:disabled]:pointer-events-none has-[input:disabled]:before:pointer-events-auto has-[input:disabled]:before:absolute has-[input:disabled]:before:inset-0 has-[input:disabled]:before:cursor-not-allowed has-[input:disabled]:before:content-[''] has-[input:focus-visible]:outline-2 has-[input:focus-visible]:outline-offset-2 has-[input:focus-visible]:outline-(--border-color) ${isChecked ? 'animate-[uiCheckPop_var(--duration)_ease-out] bg-(--border-color)' : 'bg-(--background-color)'}`}
47
- >
48
- <input
49
- type="checkbox"
50
- name={name}
51
- checked={isChecked}
52
- disabled={isDisabled}
53
- onChange={(event) => {
54
- if (!isDisabled) onChange?.(event.target.checked)
55
- }}
56
- className="sr-only"
57
- />
58
- <div
59
- className={`flex h-4 w-4 items-center justify-center [&>*]:fill-current [&>*]:text-current ${isChecked ? 'text-(--background-color)' : 'text-(--border-color)'}`}
60
- >
61
- {check ?? <CheckIcon />}
62
- </div>
63
- </label>
64
- </>
65
- )
66
- }
@@ -1,154 +0,0 @@
1
- 'use client'
2
-
3
- import type { CSSProperties } from 'react'
4
- import type { DateObject, InputBoxStyleForEachStatus } from '../types'
5
- import {
6
- MESSAGES,
7
- composeDateValue,
8
- formatDateValue,
9
- splitDate,
10
- validateDateObject,
11
- } from '@geckou/ui-core'
12
- import { useEffect, useRef, useState } from 'react'
13
- import { InputBox } from './InputBox'
14
- import { ErrorMessage } from './ErrorMessage'
15
- import { CalendarIcon } from './icons/CalendarIcon'
16
- import { COLOR } from '../constants'
17
-
18
- type Props = {
19
- name: string
20
- value?: string
21
- onChange?: (newValue: string) => void
22
- cssStyle?: InputBoxStyleForEachStatus
23
- isDisabled?: boolean
24
- isRequired?: boolean
25
- minDate?: string
26
- maxDate?: string
27
- size?: 'small' | 'medium'
28
- type?: 'date' | 'month'
29
- }
30
-
31
- export function DatePicker({
32
- name,
33
- value,
34
- onChange,
35
- cssStyle,
36
- isDisabled,
37
- isRequired,
38
- minDate = '',
39
- maxDate = '',
40
- size = 'medium',
41
- type = 'date',
42
- }: Props) {
43
- const [dateValue, setDateValue] = useState(() =>
44
- value ? formatDateValue(value, type) : '',
45
- )
46
- const [dateObject, setDateObject] = useState<DateObject>(() =>
47
- value ? splitDate(formatDateValue(value, type)) : { year: '', month: '', day: '' },
48
- )
49
- const [errorMessage, setErrorMessage] = useState('')
50
-
51
- // prop が実際に変わったときだけ同期する(内部編集を上書きしないため)
52
- const lastValueProp = useRef(value)
53
-
54
- useEffect(() => {
55
- if (lastValueProp.current === value) return
56
- lastValueProp.current = value
57
-
58
- const normalized = value ? formatDateValue(value, type) : ''
59
- setDateValue(normalized)
60
- setDateObject(splitDate(normalized))
61
- }, [value, type])
62
-
63
- const validateInput = (newValue: string) => {
64
- if (!newValue && isRequired)
65
- {return { isValid: false, message: MESSAGES.required }}
66
- return { isValid: true, message: '' }
67
- }
68
-
69
- const validateObject = (object: DateObject) =>
70
- validateDateObject(object, { type, isRequired })
71
-
72
- const handleDateValueChange = (newValue: string) => {
73
- setDateValue(newValue)
74
- setDateObject(splitDate(newValue))
75
- const { message } = validateInput(newValue)
76
- setErrorMessage(message)
77
- onChange?.(newValue)
78
- }
79
-
80
- const handleObjectChange = (key: keyof DateObject, newValue: string) => {
81
- const next = { ...dateObject, [key]: newValue }
82
- setDateObject(next)
83
- const { isValid, message } = validateObject(next)
84
- setErrorMessage(message)
85
-
86
- if (isValid) {
87
- const joined = composeDateValue(next, type)
88
- setDateValue(joined)
89
- onChange?.(joined)
90
- }
91
- }
92
-
93
- const isSmall = size === 'small'
94
- const textInputClass = `flex-none! ${isSmall ? 'px-[var(--sp-small,0.375rem)]! py-[var(--sp-min,0.1875rem)]! text-[length:var(--fs-small,0.6875rem)]' : 'p-[var(--sp-medium,0.75rem)]!'}`
95
- const iconStyle = { '--icon-color': COLOR.blue } as CSSProperties
96
-
97
- return (
98
- <InputBox
99
- cssStyle={cssStyle}
100
- isDisabled={isDisabled}
101
- isErrored={!!errorMessage}
102
- className={`flex w-full items-center leading-none ${isSmall ? 'h-[calc(var(--bv,0.375rem)*5)] px-[var(--sp-min,0.1875rem)]' : 'h-[calc(var(--bv,0.375rem)*6)] px-[var(--sp-small,0.375rem)]'}`}
103
- >
104
- <div className="relative flex-none" style={iconStyle}>
105
- <CalendarIcon
106
- className={`pointer-events-none absolute inset-y-0 left-[var(--sp-small,0.375rem)] m-auto fill-(--icon-color) ${isSmall ? 'size-[var(--icon-small,0.9375rem)]' : 'size-[var(--icon-medium,1.125rem)]'}`}
107
- />
108
- <input
109
- type={type}
110
- name={name}
111
- value={dateValue}
112
- max={maxDate}
113
- min={minDate}
114
- required={isRequired}
115
- disabled={isDisabled}
116
- onChange={(event) => handleDateValueChange(event.target.value)}
117
- className={`w-[calc(var(--icon-medium,1.125rem)+var(--sp-small,0.375rem)*2)]! cursor-pointer px-[var(--sp-small,0.375rem)]! opacity-0 [&::-webkit-calendar-picker-indicator]:absolute [&::-webkit-calendar-picker-indicator]:left-0 [&::-webkit-calendar-picker-indicator]:h-full [&::-webkit-calendar-picker-indicator]:w-full [&::-webkit-calendar-picker-indicator]:cursor-pointer [&::-webkit-calendar-picker-indicator]:opacity-0 ${isSmall ? 'py-[var(--sp-min,0.1875rem)]!' : 'py-[var(--sp-medium,0.75rem)]!'}`}
118
- />
119
- </div>
120
- <input
121
- value={dateObject.year}
122
- placeholder="年"
123
- maxLength={4}
124
- type="text"
125
- disabled={isDisabled}
126
- onChange={(event) => handleObjectChange('year', event.target.value)}
127
- className={`w-[calc(var(--sp-medium,0.75rem)*2+5ch)]! ${textInputClass}`}
128
- />
129
- /
130
- <input
131
- value={dateObject.month}
132
- placeholder="月"
133
- maxLength={2}
134
- type="text"
135
- disabled={isDisabled}
136
- onChange={(event) => handleObjectChange('month', event.target.value)}
137
- className={`w-[calc(var(--sp-medium,0.75rem)*2+3ch)]! ${textInputClass}`}
138
- />
139
- {type === 'date' && <span>/</span>}
140
- {type === 'date' && (
141
- <input
142
- value={dateObject.day}
143
- placeholder="日"
144
- maxLength={2}
145
- type="text"
146
- disabled={isDisabled}
147
- onChange={(event) => handleObjectChange('day', event.target.value)}
148
- className={`w-[calc(var(--sp-medium,0.75rem)*2+3ch)]! ${textInputClass}`}
149
- />
150
- )}
151
- <ErrorMessage errorMessages={errorMessage ? [errorMessage] : undefined} />
152
- </InputBox>
153
- )
154
- }
@@ -1,59 +0,0 @@
1
- 'use client'
2
-
3
- import type { CSSProperties } from 'react'
4
- import { useState } from 'react'
5
- import { DatePicker } from './DatePicker'
6
- import { COLOR } from '../constants'
7
-
8
- type DateRange = {
9
- startDate: string
10
- endDate: string
11
- }
12
-
13
- type Props = {
14
- isDisabled?: boolean
15
- onChange?: (newValue: DateRange) => void
16
- }
17
-
18
- export function DateRangePicker({ isDisabled, onChange }: Props) {
19
- const [startDate, setStartDate] = useState('')
20
- const [endDate, setEndDate] = useState('')
21
-
22
- const handleStartChange = (newValue: string) => {
23
- setStartDate(newValue)
24
- onChange?.({ startDate: newValue, endDate })
25
- }
26
-
27
- const handleEndChange = (newValue: string) => {
28
- setEndDate(newValue)
29
- onChange?.({ startDate, endDate: newValue })
30
- }
31
-
32
- const style = {
33
- '--range-background-color': COLOR.white,
34
- '--range-border-color': COLOR.gray,
35
- } as CSSProperties
36
-
37
- return (
38
- <div
39
- style={style}
40
- className="flex bg-(--range-background-color) [&>*]:flex-auto [&>*]:rounded-none! [&>*:first-child]:rounded-s-[calc(var(--bv,0.375rem)/2)]! [&>*:last-child]:rounded-e-[calc(var(--bv,0.375rem)/2)]! [&>*:not(:last-child)]:border-e [&>*:not(:last-child)]:border-(--range-border-color)"
41
- >
42
- <DatePicker
43
- value={startDate}
44
- name="startDate"
45
- isDisabled={isDisabled}
46
- onChange={handleStartChange}
47
- />
48
- <div className="flex flex-none! items-center px-[var(--bv,0.375rem)]">
49
-
50
- </div>
51
- <DatePicker
52
- value={endDate}
53
- name="endDate"
54
- isDisabled={isDisabled}
55
- onChange={handleEndChange}
56
- />
57
- </div>
58
- )
59
- }