@semcore/time-picker 3.0.13 → 3.0.16

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/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  CHANGELOG.md standards are inspired by [keepachangelog.com](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
+ ## [3.0.16] - 2022-07-21
6
+
7
+ ### Changed
8
+
9
+ - Version patch update due to children dependencies update (`@semcore/select` [3.0.13 ~> 3.0.14]).
10
+
11
+ ## [3.0.15] - 2022-07-18
12
+
13
+ ### Changed
14
+
15
+ - Version patch update due to children dependencies update (`@semcore/select` [3.0.12 ~> 3.0.13]).
16
+
17
+ ## [3.0.14] - 2022-07-14
18
+
19
+ ### Changed
20
+
21
+ - Version patch update due to children dependencies update (`@semcore/input` [3.0.7 ~> 3.0.8], `@semcore/select` [3.0.11 ~> 3.0.12]).
22
+
5
23
  ## [3.0.13] - 2022-07-14
6
24
 
7
25
  ### Changed
@@ -61,22 +61,22 @@ var style = (
61
61
  /*__reshadow_css_start__*/
62
62
  _core.sstyled.insert(
63
63
  /*__inner_css_start__*/
64
- ".___STimePicker_1yro5_gg_{position:relative;width:auto}.___STimePicker_1yro5_gg_.__disabled_1yro5_gg_{color:rgba(25,27,35,.3);cursor:default}.___SPickerInput_1yro5_gg_{box-sizing:content-box;text-align:center;z-index:1}.___SPickerInput_1yro5_gg_.__placeholder_1yro5_gg_{text-overflow:clip}.___SPickerInput_1yro5_gg_._size_m_1yro5_gg_{width:19px}.___SPickerInput_1yro5_gg_._size_l_1yro5_gg_{width:21px}.___SPickerFormat_1yro5_gg_{flex-shrink:0;position:relative;display:inline-flex;padding:0;white-space:nowrap;font-family:inherit;font-weight:500;line-height:normal;text-decoration:none;align-items:center;border:1px solid #c4c7cf;border-radius:0 6px 6px 0;outline:0;box-shadow:none;cursor:pointer;box-sizing:border-box;overflow:visible;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;touch-action:manipulation;-webkit-tap-highlight-color:transparent;color:#6c6e79;background-color:rgba(138,142,155,.1)}.___SPickerFormat_1yro5_gg_:hover{color:#6c6e79;background-color:rgba(138,142,155,.2)}.___SPickerFormat_1yro5_gg_:active,.___SPickerFormat_1yro5_gg_.__active_1yro5_gg_{color:#6c6e79;background-color:rgba(138,142,155,.3)}.___SPickerFormat_1yro5_gg_._size_m_1yro5_gg_{height:28px;font-size:14px;margin:0 -1px 0 0}.___SPickerFormat_1yro5_gg_._size_m_1yro5_gg_ .___SPickerFormatText_1yro5_gg_{margin:0 8px}.___SPickerFormat_1yro5_gg_._size_l_1yro5_gg_{height:40px;font-size:16px;margin:0 -4px 0 0}.___SPickerFormat_1yro5_gg_._size_l_1yro5_gg_ .___SPickerFormatText_1yro5_gg_{margin:0 12px}.___SPickerFormat_1yro5_gg_.__disabled_1yro5_gg_{opacity:0.3;cursor:default;pointer-events:none;border-color:transparent transparent transparent #c4c7cf}.___SPickerFormat_1yro5_gg_.__keyboardFocused_1yro5_gg_{box-shadow:0 0 0 3px rgba(0, 143, 248, 0.2)}.___STimePickerSeparator_1yro5_gg_.__disabled_1yro5_gg_{opacity:0.3;pointer-events:none}"
64
+ ".___STimePicker_18gcr_gg_{position:relative;width:auto}.___STimePicker_18gcr_gg_.__disabled_18gcr_gg_{color:rgba(25,27,35,.3);cursor:default}.___SPickerInput_18gcr_gg_{box-sizing:content-box;text-align:center;z-index:1}.___SPickerInput_18gcr_gg_.__placeholder_18gcr_gg_{text-overflow:clip}.___SPickerInput_18gcr_gg_._size_m_18gcr_gg_{width:19px}.___SPickerInput_18gcr_gg_._size_l_18gcr_gg_{width:21px}.___SPickerFormat_18gcr_gg_{flex-shrink:0;position:relative;display:inline-flex;padding:0;white-space:nowrap;font-family:inherit;font-weight:500;line-height:normal;text-decoration:none;align-items:center;border:1px solid #c4c7cf;border-radius:0 6px 6px 0;outline:0;box-shadow:none;cursor:pointer;box-sizing:border-box;overflow:visible;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;touch-action:manipulation;-webkit-tap-highlight-color:transparent;color:#6c6e79;background-color:rgba(138,142,155,.1)}.___SPickerFormat_18gcr_gg_:hover{color:#6c6e79;background-color:rgba(138,142,155,.2)}.___SPickerFormat_18gcr_gg_:active,.___SPickerFormat_18gcr_gg_.__active_18gcr_gg_{color:#6c6e79;background-color:rgba(138,142,155,.3)}.___SPickerFormat_18gcr_gg_._size_m_18gcr_gg_{height:28px;font-size:14px;margin:0 -1px 0 0}.___SPickerFormat_18gcr_gg_._size_m_18gcr_gg_ .___SPickerFormatText_18gcr_gg_{margin:0 8px}.___SPickerFormat_18gcr_gg_._size_l_18gcr_gg_{height:40px;font-size:16px;margin:0 -4px 0 0}.___SPickerFormat_18gcr_gg_._size_l_18gcr_gg_ .___SPickerFormatText_18gcr_gg_{margin:0 12px}.___SPickerFormat_18gcr_gg_.__disabled_18gcr_gg_{opacity:0.3;cursor:default;pointer-events:none;border-color:transparent transparent transparent #c4c7cf}.___SPickerFormat_18gcr_gg_.__keyboardFocused_18gcr_gg_{box-shadow:0 0 0 3px rgba(0, 143, 248, 0.2)}.___STimePickerSeparator_18gcr_gg_.__disabled_18gcr_gg_{opacity:0.3;pointer-events:none}"
65
65
  /*__inner_css_end__*/
66
- , "m3tn0e_gg_")
66
+ , "18gcr_gg_")
67
67
  /*__reshadow_css_end__*/
68
68
  , {
69
- "__STimePicker": "___STimePicker_1yro5_gg_",
70
- "_disabled": "__disabled_1yro5_gg_",
71
- "__SPickerInput": "___SPickerInput_1yro5_gg_",
72
- "_placeholder": "__placeholder_1yro5_gg_",
73
- "_size_m": "_size_m_1yro5_gg_",
74
- "_size_l": "_size_l_1yro5_gg_",
75
- "__SPickerFormat": "___SPickerFormat_1yro5_gg_",
76
- "_active": "__active_1yro5_gg_",
77
- "__SPickerFormatText": "___SPickerFormatText_1yro5_gg_",
78
- "_keyboardFocused": "__keyboardFocused_1yro5_gg_",
79
- "__STimePickerSeparator": "___STimePickerSeparator_1yro5_gg_"
69
+ "__STimePicker": "___STimePicker_18gcr_gg_",
70
+ "_disabled": "__disabled_18gcr_gg_",
71
+ "__SPickerInput": "___SPickerInput_18gcr_gg_",
72
+ "_placeholder": "__placeholder_18gcr_gg_",
73
+ "_size_m": "_size_m_18gcr_gg_",
74
+ "_size_l": "_size_l_18gcr_gg_",
75
+ "__SPickerFormat": "___SPickerFormat_18gcr_gg_",
76
+ "_active": "__active_18gcr_gg_",
77
+ "__SPickerFormatText": "___SPickerFormatText_18gcr_gg_",
78
+ "_keyboardFocused": "__keyboardFocused_18gcr_gg_",
79
+ "__STimePickerSeparator": "___STimePickerSeparator_18gcr_gg_"
80
80
  });
81
81
  var MAP_MERIDIEM = {
82
82
  AM: 'PM',
@@ -30,22 +30,22 @@ var style = (
30
30
  /*__reshadow_css_start__*/
31
31
  _sstyled.insert(
32
32
  /*__inner_css_start__*/
33
- ".___STimePicker_1yro5_gg_{position:relative;width:auto}.___STimePicker_1yro5_gg_.__disabled_1yro5_gg_{color:rgba(25,27,35,.3);cursor:default}.___SPickerInput_1yro5_gg_{box-sizing:content-box;text-align:center;z-index:1}.___SPickerInput_1yro5_gg_.__placeholder_1yro5_gg_{text-overflow:clip}.___SPickerInput_1yro5_gg_._size_m_1yro5_gg_{width:19px}.___SPickerInput_1yro5_gg_._size_l_1yro5_gg_{width:21px}.___SPickerFormat_1yro5_gg_{flex-shrink:0;position:relative;display:inline-flex;padding:0;white-space:nowrap;font-family:inherit;font-weight:500;line-height:normal;text-decoration:none;align-items:center;border:1px solid #c4c7cf;border-radius:0 6px 6px 0;outline:0;box-shadow:none;cursor:pointer;box-sizing:border-box;overflow:visible;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;touch-action:manipulation;-webkit-tap-highlight-color:transparent;color:#6c6e79;background-color:rgba(138,142,155,.1)}.___SPickerFormat_1yro5_gg_:hover{color:#6c6e79;background-color:rgba(138,142,155,.2)}.___SPickerFormat_1yro5_gg_:active,.___SPickerFormat_1yro5_gg_.__active_1yro5_gg_{color:#6c6e79;background-color:rgba(138,142,155,.3)}.___SPickerFormat_1yro5_gg_._size_m_1yro5_gg_{height:28px;font-size:14px;margin:0 -1px 0 0}.___SPickerFormat_1yro5_gg_._size_m_1yro5_gg_ .___SPickerFormatText_1yro5_gg_{margin:0 8px}.___SPickerFormat_1yro5_gg_._size_l_1yro5_gg_{height:40px;font-size:16px;margin:0 -4px 0 0}.___SPickerFormat_1yro5_gg_._size_l_1yro5_gg_ .___SPickerFormatText_1yro5_gg_{margin:0 12px}.___SPickerFormat_1yro5_gg_.__disabled_1yro5_gg_{opacity:0.3;cursor:default;pointer-events:none;border-color:transparent transparent transparent #c4c7cf}.___SPickerFormat_1yro5_gg_.__keyboardFocused_1yro5_gg_{box-shadow:0 0 0 3px rgba(0, 143, 248, 0.2)}.___STimePickerSeparator_1yro5_gg_.__disabled_1yro5_gg_{opacity:0.3;pointer-events:none}"
33
+ ".___STimePicker_18gcr_gg_{position:relative;width:auto}.___STimePicker_18gcr_gg_.__disabled_18gcr_gg_{color:rgba(25,27,35,.3);cursor:default}.___SPickerInput_18gcr_gg_{box-sizing:content-box;text-align:center;z-index:1}.___SPickerInput_18gcr_gg_.__placeholder_18gcr_gg_{text-overflow:clip}.___SPickerInput_18gcr_gg_._size_m_18gcr_gg_{width:19px}.___SPickerInput_18gcr_gg_._size_l_18gcr_gg_{width:21px}.___SPickerFormat_18gcr_gg_{flex-shrink:0;position:relative;display:inline-flex;padding:0;white-space:nowrap;font-family:inherit;font-weight:500;line-height:normal;text-decoration:none;align-items:center;border:1px solid #c4c7cf;border-radius:0 6px 6px 0;outline:0;box-shadow:none;cursor:pointer;box-sizing:border-box;overflow:visible;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;touch-action:manipulation;-webkit-tap-highlight-color:transparent;color:#6c6e79;background-color:rgba(138,142,155,.1)}.___SPickerFormat_18gcr_gg_:hover{color:#6c6e79;background-color:rgba(138,142,155,.2)}.___SPickerFormat_18gcr_gg_:active,.___SPickerFormat_18gcr_gg_.__active_18gcr_gg_{color:#6c6e79;background-color:rgba(138,142,155,.3)}.___SPickerFormat_18gcr_gg_._size_m_18gcr_gg_{height:28px;font-size:14px;margin:0 -1px 0 0}.___SPickerFormat_18gcr_gg_._size_m_18gcr_gg_ .___SPickerFormatText_18gcr_gg_{margin:0 8px}.___SPickerFormat_18gcr_gg_._size_l_18gcr_gg_{height:40px;font-size:16px;margin:0 -4px 0 0}.___SPickerFormat_18gcr_gg_._size_l_18gcr_gg_ .___SPickerFormatText_18gcr_gg_{margin:0 12px}.___SPickerFormat_18gcr_gg_.__disabled_18gcr_gg_{opacity:0.3;cursor:default;pointer-events:none;border-color:transparent transparent transparent #c4c7cf}.___SPickerFormat_18gcr_gg_.__keyboardFocused_18gcr_gg_{box-shadow:0 0 0 3px rgba(0, 143, 248, 0.2)}.___STimePickerSeparator_18gcr_gg_.__disabled_18gcr_gg_{opacity:0.3;pointer-events:none}"
34
34
  /*__inner_css_end__*/
35
- , "m3tn0e_gg_")
35
+ , "18gcr_gg_")
36
36
  /*__reshadow_css_end__*/
37
37
  , {
38
- "__STimePicker": "___STimePicker_1yro5_gg_",
39
- "_disabled": "__disabled_1yro5_gg_",
40
- "__SPickerInput": "___SPickerInput_1yro5_gg_",
41
- "_placeholder": "__placeholder_1yro5_gg_",
42
- "_size_m": "_size_m_1yro5_gg_",
43
- "_size_l": "_size_l_1yro5_gg_",
44
- "__SPickerFormat": "___SPickerFormat_1yro5_gg_",
45
- "_active": "__active_1yro5_gg_",
46
- "__SPickerFormatText": "___SPickerFormatText_1yro5_gg_",
47
- "_keyboardFocused": "__keyboardFocused_1yro5_gg_",
48
- "__STimePickerSeparator": "___STimePickerSeparator_1yro5_gg_"
38
+ "__STimePicker": "___STimePicker_18gcr_gg_",
39
+ "_disabled": "__disabled_18gcr_gg_",
40
+ "__SPickerInput": "___SPickerInput_18gcr_gg_",
41
+ "_placeholder": "__placeholder_18gcr_gg_",
42
+ "_size_m": "_size_m_18gcr_gg_",
43
+ "_size_l": "_size_l_18gcr_gg_",
44
+ "__SPickerFormat": "___SPickerFormat_18gcr_gg_",
45
+ "_active": "__active_18gcr_gg_",
46
+ "__SPickerFormatText": "___SPickerFormatText_18gcr_gg_",
47
+ "_keyboardFocused": "__keyboardFocused_18gcr_gg_",
48
+ "__STimePickerSeparator": "___STimePickerSeparator_18gcr_gg_"
49
49
  });
50
50
  var MAP_MERIDIEM = {
51
51
  AM: 'PM',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@semcore/time-picker",
3
3
  "description": "SEMRush TimePicker Component",
4
- "version": "3.0.13",
4
+ "version": "3.0.16",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/es6/index.js",
7
7
  "typings": "lib/types/index.d.ts",
@@ -1,21 +0,0 @@
1
- import React from 'react';
2
- import { Component, sstyled, Root } from '@semcore/core';
3
- import { Box } from '@semcore/flex-box';
4
- import keyboardFocusEnhance from '@semcore/utils/lib/enhances/keyboardFocusEnhance';
5
-
6
- class TimePickerFormat extends Component {
7
- static enhance = [keyboardFocusEnhance()];
8
- render() {
9
- const SPickerFormat = Root;
10
- const { Children, meridiem, styles } = this.asProps;
11
- const SPickerFormatText = 'span';
12
-
13
- return sstyled(styles)(
14
- <SPickerFormat render={Box} type="button" tag="button">
15
- {Children.origin ? <Children /> : <SPickerFormatText>{meridiem}</SPickerFormatText>}
16
- </SPickerFormat>,
17
- );
18
- }
19
- }
20
-
21
- export default TimePickerFormat;
@@ -1,217 +0,0 @@
1
- import React from 'react';
2
- import Input from '@semcore/input';
3
- import Select from '@semcore/select';
4
- import { intOrDefault, nextInput, prevInput, withLeadingZero } from './TimePicker';
5
- import { Component, sstyled, Root } from '@semcore/core';
6
- import { callAllEventHandlers } from '@semcore/utils/lib/assignProps';
7
-
8
- const MAP_FIELD_TO_TIME = {
9
- hours: 0,
10
- minutes: 1,
11
- };
12
-
13
- const MAP_SIZE_SELECT = {
14
- m: 'm',
15
- l: 'l',
16
- };
17
-
18
- function getOptions(min, max, step = 1) {
19
- const length = Number(((max + 1 - min) / step).toFixed(0));
20
- const options = Array(length).fill('');
21
- let numValue = min;
22
- return options.map((i, index) => {
23
- numValue = index === 0 ? numValue : numValue + step;
24
- const value = withLeadingZero(String(numValue));
25
- return (
26
- <Select.Option value={value} key={value}>
27
- {value}
28
- </Select.Option>
29
- );
30
- });
31
- }
32
-
33
- class ItemPicker extends Component {
34
- static defaultProps = {
35
- placeholder: '00',
36
- };
37
-
38
- $input = React.createRef();
39
-
40
- minMax() {
41
- return [];
42
- }
43
-
44
- state = {
45
- dirtyValue: undefined,
46
- visible: false,
47
- };
48
-
49
- parseValueWithMinMax = (value) => {
50
- const [min, max] = this.minMax();
51
- return String(Math.max(min, Math.min(max, value)));
52
- };
53
-
54
- dispatchOnChange(value, event) {
55
- this.setState({ dirtyValue: undefined });
56
- this.asProps.$onValueChange(value, this.field, event);
57
- }
58
-
59
- submitChanges(event) {
60
- let { dirtyValue } = this.state;
61
- if (dirtyValue !== undefined) {
62
- // if changes value
63
- if (dirtyValue) dirtyValue = this.parseValueWithMinMax(dirtyValue); // if not ""
64
- this.dispatchOnChange(dirtyValue, event);
65
- }
66
- }
67
-
68
- handleChange = (value, e) => {
69
- /* hide props for bubbling events */
70
- e.stopPropagation();
71
- const numberValue = intOrDefault(Number(value), NaN);
72
-
73
- if (!Number.isNaN(numberValue)) {
74
- this.setState({ dirtyValue: value.slice(-2) });
75
- }
76
- };
77
-
78
- handleBlur = (e) => this.submitChanges(e);
79
-
80
- handleFocus = () => {
81
- this.$input?.current.select();
82
- };
83
-
84
- /* rewrite method */
85
- handleKeyDown = () => {};
86
-
87
- handleSelect = (value, e) => {
88
- this.dispatchOnChange(value, e);
89
- };
90
-
91
- handleVisibleChange = (visible) => this.setState({ visible });
92
-
93
- render() {
94
- const SPickerInput = Root;
95
- const { styles, step, onSelect, time, size, disabled, onVisibleChange, ...other } =
96
- this.asProps;
97
- const { dirtyValue, visible } = this.state;
98
- const timeValue = time[MAP_FIELD_TO_TIME[this.field]];
99
- const value = dirtyValue === undefined ? timeValue : dirtyValue;
100
- const [min, max] = this.minMax();
101
-
102
- return sstyled(styles)(
103
- <Select
104
- {...other}
105
- interaction="focus"
106
- size={size ? MAP_SIZE_SELECT[size] : false}
107
- onChange={callAllEventHandlers(onSelect, this.handleSelect)}
108
- onVisibleChange={callAllEventHandlers(onVisibleChange, this.handleVisibleChange)}
109
- visible={visible}
110
- value={timeValue}
111
- >
112
- <SPickerInput
113
- interaction="focus"
114
- render={Select.Trigger}
115
- tag={Input.Value}
116
- ref={this.$input}
117
- size={size}
118
- disabled={disabled}
119
- neighborLocation={false}
120
- value={value}
121
- aria-label={`Search ${this.field}`}
122
- onChange={this.handleChange}
123
- onBlur={this.handleBlur}
124
- onFocus={this.handleFocus}
125
- onKeyDown={this.handleKeyDown}
126
- />
127
- <Select.Menu hMax={180}>{getOptions(min, max, step)}</Select.Menu>
128
- </Select>,
129
- );
130
- }
131
- }
132
-
133
- class Hours extends ItemPicker {
134
- field = 'hours';
135
-
136
- minMax() {
137
- const { is12Hour } = this.asProps;
138
- if (is12Hour) {
139
- return [1, 12];
140
- } else {
141
- return [0, 23];
142
- }
143
- }
144
-
145
- nextInput() {
146
- if (this.$input.current) {
147
- const $input = nextInput(this.$input.current);
148
- if ($input) {
149
- this.setState({ visible: false });
150
- $input.focus();
151
- }
152
- }
153
- }
154
-
155
- handleKeyDown = (e) => {
156
- const { currentTarget } = e;
157
- if (e.keyCode === 13) this.submitChanges(e);
158
- if (e.keyCode === 39) {
159
- if (
160
- currentTarget.selectionStart >= currentTarget.value.length &&
161
- currentTarget.selectionStart === currentTarget.selectionEnd
162
- ) {
163
- e.preventDefault();
164
- this.nextInput();
165
- }
166
- }
167
- };
168
-
169
- componentDidUpdate(prevProps, prevState) {
170
- const { dirtyValue } = this.state;
171
- if (prevState.dirtyValue === undefined || dirtyValue === undefined) return;
172
-
173
- if (prevState.dirtyValue.length === 1 && dirtyValue.length === 2) {
174
- this.nextInput();
175
- }
176
- }
177
- }
178
-
179
- class Minutes extends ItemPicker {
180
- field = 'minutes';
181
-
182
- minMax() {
183
- return [0, 59];
184
- }
185
-
186
- prevFocus() {
187
- if (this.$input.current) {
188
- const $input = prevInput(this.$input.current);
189
- if ($input) {
190
- this.setState({ visible: false });
191
- $input.focus();
192
- }
193
- }
194
- }
195
-
196
- handleKeyDown = (e) => {
197
- const { currentTarget } = e;
198
- if (e.keyCode === 13) this.submitChanges(e);
199
- if (e.keyCode === 37) {
200
- if (
201
- currentTarget.selectionStart <= 0 &&
202
- currentTarget.selectionStart === currentTarget.selectionEnd
203
- ) {
204
- e.preventDefault();
205
- this.prevFocus();
206
- }
207
- }
208
- if (e.keyCode === 8) {
209
- if (currentTarget.value.length === 0) {
210
- e.preventDefault();
211
- this.prevFocus();
212
- }
213
- }
214
- };
215
- }
216
-
217
- export { Hours, Minutes };
@@ -1,243 +0,0 @@
1
- import React from 'react';
2
- import createComponent, { Component, sstyled, Root } from '@semcore/core';
3
- import Input from '@semcore/input';
4
- import { Box } from '@semcore/flex-box';
5
- import { Hours, Minutes } from './PickerInput';
6
- import Format from './PickerFormat';
7
-
8
- import style from './style/time-picker.shadow.css';
9
-
10
- const MAP_MERIDIEM = {
11
- AM: 'PM',
12
- PM: 'AM',
13
- };
14
- const MAP_FIELD_TO_TIME = {
15
- hours: 0,
16
- minutes: 1,
17
- };
18
-
19
- export function nextInput(element) {
20
- do {
21
- element = element.nextElementSibling;
22
- } while (element && element.tagName !== 'INPUT');
23
- return element;
24
- }
25
-
26
- export function prevInput(element) {
27
- do {
28
- element = element.previousElementSibling;
29
- } while (element && element.tagName !== 'INPUT');
30
- return element;
31
- }
32
-
33
- export function intOrDefault(value, def = 0) {
34
- const number = Number.parseInt(value);
35
- return Number.isNaN(number) ? def : number;
36
- }
37
-
38
- export function withLeadingZero(value) {
39
- value = String(value);
40
- if (value.length === 1) return `0${value}`;
41
- return String(value);
42
- }
43
-
44
- export function meridiemByHours(hours) {
45
- return hours >= 12 ? 'PM' : 'AM';
46
- }
47
-
48
- export function formatHoursTo12(hours /* hours by 24 */) {
49
- const nHours = intOrDefault(hours, NaN); // if not (:00)
50
- if (Number.isNaN(nHours)) return hours;
51
-
52
- // if not (HH:00)
53
- if (nHours === 0) return 12; // 0 => 12 PM
54
- if (nHours > 12) return nHours - 12; // 22 => 12 PM
55
-
56
- return hours;
57
- }
58
-
59
- export function formatHoursTo24(hours /* hours by 12 */, meridiem) {
60
- const nHours = intOrDefault(hours, NaN); // if not (:00)
61
-
62
- if (Number.isNaN(nHours)) return hours;
63
-
64
- if (meridiem === 'AM') {
65
- if (nHours === 12) return 0; // 12 AM => 0
66
- }
67
-
68
- if (meridiem === 'PM') {
69
- if (nHours < 12) return nHours + 12; // 10 PM => 22
70
- }
71
-
72
- return hours;
73
- }
74
-
75
- class TimePickerRoot extends Component {
76
- static displayName = 'TimePicker';
77
- static style = style;
78
- static defaultProps = ({ is12Hour }) => ({
79
- defaultValue: '',
80
- size: 'm',
81
- children: (
82
- <>
83
- <TimePicker.Hours />
84
- <TimePicker.Separator />
85
- <TimePicker.Minutes />
86
- {is12Hour && <TimePicker.Format />}
87
- </>
88
- ),
89
- });
90
-
91
- _lastMeridiem = 'AM'; // default AM
92
-
93
- uncontrolledProps() {
94
- return {
95
- value: null,
96
- };
97
- }
98
-
99
- get value() {
100
- const { value } = this.asProps;
101
- return value === null || value === undefined ? ':' : value;
102
- }
103
-
104
- get meridiem() {
105
- const { value } = this.asProps;
106
- const [hours = ''] = value.split(':');
107
-
108
- const nHours = intOrDefault(hours, NaN);
109
-
110
- if (!Number.isNaN(nHours)) {
111
- this._lastMeridiem = meridiemByHours(nHours);
112
- }
113
-
114
- return this._lastMeridiem;
115
- }
116
-
117
- valueToTime(value) {
118
- const { is12Hour } = this.asProps;
119
- let [hours = '', minutes = ''] = value.split(':');
120
-
121
- if (is12Hour) hours = formatHoursTo12(hours);
122
-
123
- hours = withLeadingZero(hours);
124
- minutes = withLeadingZero(minutes);
125
-
126
- return [hours, minutes];
127
- }
128
-
129
- timeToValue(time, meridiem) {
130
- const { is12Hour } = this.asProps;
131
- let [hours = '', minutes = ''] = time;
132
-
133
- hours = intOrDefault(hours, hours); // 03 => 3
134
- minutes = intOrDefault(minutes, minutes); // MM => MM
135
-
136
- if (is12Hour) hours = formatHoursTo24(hours, meridiem); // 12 PM -> 0
137
-
138
- return `${hours}:${minutes}`;
139
- }
140
-
141
- handleValueChange = (value, field, event) => {
142
- const { is12Hour } = this.asProps;
143
- const { meridiem } = this;
144
-
145
- let time;
146
- if (field) {
147
- time = this.value.split(':');
148
- time[MAP_FIELD_TO_TIME[field]] = value;
149
- } else {
150
- time = value.split(':');
151
- }
152
-
153
- let [hours = '', minutes = ''] = time;
154
-
155
- if (is12Hour) hours = String(formatHoursTo12(hours));
156
-
157
- value = this.timeToValue([hours, minutes], meridiem);
158
- this.handlers.value(value, event);
159
- };
160
-
161
- handleMeridiemClick = (event) => {
162
- const { is12Hour } = this.asProps;
163
- let { value, meridiem } = this;
164
- let [hours = '', minutes = ''] = value.split(':');
165
-
166
- if (is12Hour) hours = String(formatHoursTo12(hours));
167
-
168
- value = this.timeToValue([hours, minutes], MAP_MERIDIEM[meridiem]);
169
- this.handlers.value(value, event);
170
- };
171
-
172
- _getHoursAndMinutesProps = () => {
173
- const { is12Hour, size, disabled } = this.asProps;
174
- const time = this.valueToTime(this.value);
175
-
176
- return {
177
- time,
178
- size,
179
- is12Hour,
180
- disabled,
181
- $onValueChange: this.handleValueChange,
182
- };
183
- };
184
-
185
- getHoursProps = this._getHoursAndMinutesProps;
186
- getMinutesProps = this._getHoursAndMinutesProps;
187
-
188
- getSeparatorProps() {
189
- return {
190
- disabled: this.asProps.disabled,
191
- };
192
- }
193
-
194
- getFormatProps() {
195
- const { size, disabled, disablePortal } = this.asProps;
196
- return {
197
- size,
198
- disabled,
199
- disablePortal,
200
- meridiem: this.meridiem,
201
- onClick: this.handleMeridiemClick,
202
- };
203
- }
204
-
205
- render() {
206
- const STimePicker = Root;
207
- const { styles, Children } = this.asProps;
208
-
209
- return sstyled(styles)(
210
- <STimePicker render={Input}>
211
- <Children />
212
- </STimePicker>,
213
- );
214
- }
215
- }
216
-
217
- class Separator extends Component {
218
- static defaultProps = {
219
- children: ':',
220
- };
221
-
222
- $el = React.createRef();
223
-
224
- handlerClick = () => {
225
- if (this.$el.current) {
226
- prevInput(this.$el.current)?.focus();
227
- }
228
- };
229
-
230
- render() {
231
- const STimePickerSeparator = Root;
232
- return <STimePickerSeparator render={Box} ref={this.$el} onClick={this.handlerClick} />;
233
- }
234
- }
235
-
236
- const TimePicker = createComponent(TimePickerRoot, {
237
- Hours,
238
- Minutes,
239
- Separator,
240
- Format,
241
- });
242
-
243
- export default TimePicker;
package/src/index.d.ts DELETED
@@ -1,47 +0,0 @@
1
- import React from 'react';
2
- import { CProps, PropGetterFn, ReturnEl } from '@semcore/core';
3
- import { IInputProps, IInputValueProps } from '@semcore/input';
4
- import { Box, IBoxProps } from '@semcore/flex-box';
5
- import { IKeyboardFocusProps } from '@semcore/utils/lib/enhances/keyboardFocusEnhance';
6
-
7
- export interface ITimePickerProps extends Omit<IInputProps, 'size'> {
8
- /** Time in the hh:mm format */
9
- value?: string;
10
- /** The event responses upon time changing */
11
- onChange?: (time: string, event?: React.SyntheticEvent) => void;
12
- /** In charge of the component blocking */
13
- disabled?: boolean;
14
- /** Control size
15
- * @default m */
16
- size?: 'm' | 'l';
17
- /** 12-hour time format */
18
- is12Hour?: boolean;
19
- }
20
-
21
- export interface ITimePickerItemProps extends IInputValueProps {
22
- /** Step for changing of the values in the dropdown list */
23
- step?: number;
24
- }
25
-
26
- export interface ITimePickerFormatProps extends IBoxProps, IKeyboardFocusProps {}
27
-
28
- export interface ITimePickerContext {
29
- getHoursProps: PropGetterFn;
30
- getFormatProps: PropGetterFn;
31
- getMinutesProps: PropGetterFn;
32
- }
33
-
34
- export interface ITimePickerHandlers {
35
- value: (value: string) => void;
36
- }
37
-
38
- declare const TimePicker: (<T>(
39
- props: CProps<ITimePickerProps & T, ITimePickerContext, ITimePickerHandlers>,
40
- ) => ReturnEl) & {
41
- Hours: <T>(props: ITimePickerItemProps & T) => ReturnEl;
42
- Minutes: <T>(props: ITimePickerItemProps & T) => ReturnEl;
43
- Separator: typeof Box;
44
- Format: <T>(props: ITimePickerFormatProps & T) => ReturnEl;
45
- };
46
-
47
- export default TimePicker;
package/src/index.js DELETED
@@ -1,2 +0,0 @@
1
- export { default } from './TimePicker';
2
- export * from './TimePicker';
@@ -1,99 +0,0 @@
1
- @import '@semcore/utils/style/var.css';
2
-
3
- STimePicker {
4
- position: relative;
5
- width: auto;
6
- }
7
-
8
- STimePicker[disabled] {
9
- color: color-mod(var(--gray-800) a(30%));
10
- cursor: default;
11
- }
12
-
13
- SPickerInput {
14
- box-sizing: content-box;
15
- text-align: center;
16
- z-index: 1;
17
-
18
- &[placeholder] {
19
- text-overflow: initial;
20
- }
21
- }
22
-
23
- SPickerInput[size='m'] {
24
- width: 19px;
25
- }
26
-
27
- SPickerInput[size='l'] {
28
- width: 21px;
29
- }
30
-
31
- SPickerFormat {
32
- flex-shrink: 0;
33
- position: relative;
34
- display: inline-flex;
35
- padding: 0;
36
- white-space: nowrap;
37
- font-family: inherit;
38
- font-weight: 500;
39
- line-height: normal;
40
- text-decoration: none;
41
- align-items: center;
42
- border: 1px solid var(--gray-200);
43
- border-radius: 0 var(--rounded-m) var(--rounded-m) 0;
44
- outline: 0;
45
- box-shadow: none;
46
- cursor: pointer;
47
- box-sizing: border-box;
48
- overflow: visible;
49
- user-select: none;
50
- touch-action: manipulation;
51
- -webkit-tap-highlight-color: transparent;
52
- color: var(--gray-500);
53
- background-color: color-mod(var(--gray-400) a(10%));
54
-
55
- &:hover {
56
- color: var(--gray-500);
57
- background-color: color-mod(var(--gray-400) a(20%));
58
- }
59
-
60
- &:active,
61
- &[active] {
62
- color: var(--gray-500);
63
- background-color: color-mod(var(--gray-400) a(30%));
64
- }
65
- }
66
-
67
- SPickerFormat[size='m'] {
68
- height: var(--form-control-m);
69
- font-size: var(--fs-200);
70
- margin: 0 -1px 0 0;
71
- & SPickerFormatText {
72
- margin: 0 8px;
73
- }
74
- }
75
-
76
- SPickerFormat[size='l'] {
77
- height: var(--form-control-l);
78
- font-size: var(--fs-300);
79
- margin: 0 -4px 0 0;
80
- & SPickerFormatText {
81
- margin: 0 12px;
82
- }
83
- }
84
-
85
- SPickerFormat[disabled] {
86
- opacity: var(--disabled-opacity);
87
- cursor: default;
88
- pointer-events: none;
89
- border-color: transparent transparent transparent var(--gray-200);
90
- }
91
-
92
- SPickerFormat[keyboardFocused] {
93
- box-shadow: var(--keyboard-focus);
94
- }
95
-
96
- STimePickerSeparator[disabled] {
97
- opacity: var(--disabled-opacity);
98
- pointer-events: none;
99
- }