@stamcat/craftsman 0.0.27-alpha.13 → 0.0.27-alpha.15

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 (41) hide show
  1. package/Components.esm.js +11 -9
  2. package/Utilities.esm.js +2 -2
  3. package/package.json +6 -1
  4. package/src/components/{Input → Checkbox}/Checkbox.d.ts +2 -3
  5. package/src/components/{Input → Checkbox}/Checkbox.esm.js +2 -2
  6. package/src/components/DatePicker/DatePicker.css +1 -0
  7. package/src/components/DatePicker/DatePicker.d.ts +8 -0
  8. package/src/{styles/global/components/_reactDatePicker.scss → components/DatePicker/DatePicker.scss} +5 -4
  9. package/src/components/{Input/DatePicker.esm.js → DatePicker/DatePicker2.esm.js} +4 -4
  10. package/src/components/DatePicker/ReactCalendar.css +1 -0
  11. package/src/components/DatePicker/ReactCalendar.scss +239 -0
  12. package/src/components/DateTimePicker/DateTimePicker.d.ts +8 -0
  13. package/src/components/{Input → InputPassword}/InputPassword.d.ts +1 -1
  14. package/src/components/{Input → InputPassword}/InputPassword.esm.js +2 -2
  15. package/src/{styles/global/components/_reactPhone.css → components/InputPhone/InputPhone.css} +1 -1
  16. package/src/components/{Input → InputPhone}/InputPhone.d.ts +1 -1
  17. package/src/components/InputPhone/InputPhone.scss +266 -0
  18. package/src/components/{Input/InputPhone.esm.js → InputPhone/InputPhone2.esm.js} +3 -3
  19. package/src/components/{Input → RadioButton}/RadioButton.d.ts +1 -1
  20. package/src/components/{Input → RadioButton}/RadioButton.esm.js +2 -2
  21. package/src/components/{Input → Textarea}/Textarea.d.ts +1 -1
  22. package/src/components/{Input → Textarea}/Textarea.esm.js +2 -2
  23. package/src/components/TimePicker/TimePicker.css +1 -0
  24. package/src/components/TimePicker/TimePicker.d.ts +5 -4
  25. package/src/components/TimePicker/TimePicker.scss +29 -0
  26. package/src/components/TimePicker/TimePicker2.esm.js +129 -0
  27. package/src/components/TimePicker/TimePickerDisplay.d.ts +6 -1
  28. package/src/components/TimePicker/TimePickerWheel.esm.js +61 -0
  29. package/src/components/TimePicker/constants.esm.js +3 -0
  30. package/src/components/TimePicker/utilities.d.ts +1 -0
  31. package/src/components/TimePicker/utilities.esm.js +20 -0
  32. package/src/components/Tooltip/Tooltip.d.ts +12 -0
  33. package/src/components/Tooltip/Tooltip.scss +29 -0
  34. package/src/components/index.d.ts +7 -6
  35. package/src/utilities/validations.d.ts +1 -0
  36. package/src/utilities/validations.esm.js +7 -4
  37. package/src/components/Input/DatePicker.d.ts +0 -8
  38. package/src/styles/global/components/_reactCalendar.css +0 -1
  39. package/src/styles/global/components/_reactCalendar.scss +0 -237
  40. package/src/styles/global/components/_reactDatePicker.css +0 -1
  41. package/src/styles/global/components/_reactPhone.scss +0 -265
@@ -0,0 +1,266 @@
1
+ @use "../../styles/global/components/input";
2
+ @use "../../styles/utilities/functions" as u;
3
+ @layer craftsman-base {
4
+ .input-phone {
5
+ &[data-label-position="inside"] {
6
+ .input-label {
7
+ top: 15px;
8
+ left: 50px;
9
+ }
10
+ }
11
+
12
+ .react-international-phone-country-selector {
13
+ position: relative;
14
+ }
15
+
16
+ .react-international-phone-flag-emoji {
17
+ width: var(--react-international-phone-flag-width, 24px);
18
+ height: var(--react-international-phone-flag-height, 24px);
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ .react-international-phone-country-selector-button {
23
+ display: flex;
24
+ height: var(--react-international-phone-height, 36px);
25
+ box-sizing: border-box;
26
+ align-items: center;
27
+ justify-content: center;
28
+ padding: 0;
29
+ border: 1px solid
30
+ var(
31
+ --react-international-phone-country-selector-border-color,
32
+ var(--react-international-phone-border-color, gainsboro)
33
+ );
34
+ margin: 0;
35
+ appearance: button;
36
+ -webkit-appearance: button;
37
+ background-color: var(
38
+ --react-international-phone-country-selector-background-color,
39
+ var(--react-international-phone-background-color, white)
40
+ );
41
+ cursor: pointer;
42
+ text-transform: none;
43
+ user-select: none;
44
+
45
+ &:hover {
46
+ background-color: var(--react-international-phone-country-selector-background-color-hover, whitesmoke);
47
+ }
48
+
49
+ &--hide-dropdown {
50
+ cursor: auto;
51
+
52
+ &:hover {
53
+ background-color: transparent;
54
+ }
55
+ }
56
+
57
+ &--disabled {
58
+ background-color: var(
59
+ --react-international-phone-disabled-country-selector-background-color,
60
+ var(--react-international-phone-disabled-background-color, whitesmoke)
61
+ );
62
+ cursor: auto;
63
+
64
+ &:hover {
65
+ background-color: var(
66
+ --react-international-phone-disabled-country-selector-background-color,
67
+ var(--react-international-phone-disabled-background-color, whitesmoke)
68
+ );
69
+ }
70
+ }
71
+
72
+ &__button-content {
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ }
77
+
78
+ &__flag-emoji {
79
+ margin: 0 4px;
80
+
81
+ &--disabled {
82
+ opacity: 0.75;
83
+ }
84
+ }
85
+
86
+ &__dropdown-arrow {
87
+ border-top: var(--react-international-phone-country-selector-arrow-size, 4px) solid
88
+ var(--react-international-phone-country-selector-arrow-color, #777);
89
+ border-right: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent;
90
+ border-left: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent;
91
+ margin-right: 4px;
92
+ transition: all 0.1s ease-out;
93
+
94
+ &--active {
95
+ transform: rotateX(180deg);
96
+ }
97
+
98
+ &--disabled {
99
+ border-top-color: var(--react-international-phone-disabled-country-selector-arrow-color, #999);
100
+ }
101
+ }
102
+ }
103
+
104
+ .react-international-phone-country-selector-dropdown {
105
+ position: absolute;
106
+ z-index: 1000;
107
+ top: var(--react-international-phone-dropdown-top, 44px);
108
+ left: var(--react-international-phone-dropdown-left, 0);
109
+ display: flex;
110
+ width: 300px;
111
+ max-height: 200px;
112
+ flex-direction: column;
113
+ padding: 4px 0;
114
+ margin: 0;
115
+ background-color: var(
116
+ --react-international-phone-dropdown-item-background-color,
117
+ var(--react-international-phone-background-color, white)
118
+ );
119
+ box-shadow: var(--react-international-phone-dropdown-shadow, 2px 2px 16px rgba(0, 0, 0, 0.25));
120
+ color: var(
121
+ --react-international-phone-dropdown-item-text-color,
122
+ var(--react-international-phone-text-color, #222)
123
+ );
124
+ list-style: none;
125
+ overflow-y: scroll;
126
+
127
+ &__preferred-list-divider {
128
+ height: 1px;
129
+ border: none;
130
+ margin: var(--react-international-phone-dropdown-preferred-list-divider-margin, 0);
131
+ background: var(
132
+ --react-international-phone-dropdown-preferred-list-divider-color,
133
+ var(--react-international-phone-border-color, gainsboro)
134
+ );
135
+ }
136
+
137
+ &__list-item {
138
+ display: flex;
139
+ min-height: var(--react-international-phone-dropdown-item-height, 28px);
140
+ box-sizing: border-box;
141
+ align-items: center;
142
+ padding: 2px 8px;
143
+
144
+ &:hover {
145
+ background-color: var(
146
+ --react-international-phone-selected-dropdown-item-background-color,
147
+ var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke)
148
+ );
149
+ cursor: pointer;
150
+ }
151
+
152
+ &--selected,
153
+ &--focused {
154
+ background-color: var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke);
155
+ color: var(
156
+ --react-international-phone-selected-dropdown-item-text-color,
157
+ var(--react-international-phone-text-color, #222)
158
+ );
159
+
160
+ .react-international-phone-country-selector-dropdown__list-item-dial-code {
161
+ color: var(
162
+ --react-international-phone-selected-dropdown-item-dial-code-color,
163
+ var(--react-international-phone-dropdown-item-dial-code-color, gray)
164
+ );
165
+ }
166
+ }
167
+
168
+ &--focused {
169
+ background-color: var(
170
+ --react-international-phone-selected-dropdown-item-background-color,
171
+ var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke)
172
+ );
173
+ }
174
+
175
+ &-flag-emoji {
176
+ margin-right: 8px;
177
+ }
178
+
179
+ &-country-name {
180
+ overflow: hidden;
181
+ margin-right: 8px;
182
+ font-size: var(--react-international-phone-dropdown-item-font-size, 14px);
183
+ text-overflow: ellipsis;
184
+ white-space: nowrap;
185
+ }
186
+
187
+ &-dial-code {
188
+ color: var(--react-international-phone-dropdown-item-dial-code-color, gray);
189
+ font-size: var(--react-international-phone-dropdown-item-font-size, 14px);
190
+ }
191
+ }
192
+ }
193
+
194
+ .react-international-phone-dial-code-preview {
195
+ display: flex;
196
+ align-items: center;
197
+ justify-content: center;
198
+ padding: 0 8px;
199
+ border: 1px solid
200
+ var(
201
+ --react-international-phone-dial-code-preview-border-color,
202
+ var(--react-international-phone-border-color, gainsboro)
203
+ );
204
+ margin-right: -1px;
205
+ background-color: var(
206
+ --react-international-phone-dial-code-preview-background-color,
207
+ var(--react-international-phone-background-color, white)
208
+ );
209
+ color: var(
210
+ --react-international-phone-dial-code-preview-text-color,
211
+ var(--react-international-phone-text-color, #222)
212
+ );
213
+ font-size: var(
214
+ --react-international-phone-dial-code-preview-font-size,
215
+ var(--react-international-phone-font-size, 13px)
216
+ );
217
+
218
+ &--disabled {
219
+ background-color: var(
220
+ --react-international-phone-dial-code-preview-disabled-background-color,
221
+ var(--react-international-phone-disabled-background-color, whitesmoke)
222
+ );
223
+ color: var(
224
+ --react-international-phone-dial-code-preview-disabled-text-color,
225
+ var(--react-international-phone-disabled-text-color, #666)
226
+ );
227
+ }
228
+ }
229
+
230
+ .react-international-phone-input-container {
231
+ display: flex;
232
+
233
+ .react-international-phone-country-selector-button {
234
+ border-radius: var(--react-international-phone-border-radius, 4px);
235
+ margin-right: -1px;
236
+ border-bottom-right-radius: 0;
237
+ border-top-right-radius: 0;
238
+ }
239
+
240
+ .react-international-phone-input {
241
+ overflow: visible;
242
+ height: var(--react-international-phone-height, 36px);
243
+ box-sizing: border-box;
244
+ padding: 0 8px;
245
+ border: 1px solid var(--react-international-phone-border-color, gainsboro);
246
+ border-radius: var(--react-international-phone-border-radius, 4px);
247
+ margin: 0;
248
+ background-color: var(--react-international-phone-background-color, white);
249
+ border-bottom-left-radius: 0;
250
+ border-top-left-radius: 0;
251
+ color: var(--react-international-phone-text-color, #222);
252
+ font-family: inherit;
253
+ font-size: var(--react-international-phone-font-size, 13px);
254
+
255
+ &:focus {
256
+ outline: none;
257
+ }
258
+
259
+ &--disabled {
260
+ background-color: var(--react-international-phone-disabled-background-color, whitesmoke);
261
+ color: var(--react-international-phone-disabled-text-color, #666);
262
+ }
263
+ }
264
+ }
265
+ }
266
+ }
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- import { InputWrapper as e } from "./InputWrapper.esm.js";
3
- import '../../styles/global/components/_reactPhone.css';/* empty css */
2
+ import { InputWrapper as e } from "../Input/InputWrapper.esm.js";
3
+ import './InputPhone.css';/* empty css */
4
4
  import t from "clsx";
5
5
  import { jsx as n } from "react/jsx-runtime";
6
6
  import r, { useId as i } from "react";
7
7
  import { PhoneInput as a } from "react-international-phone";
8
- //#region src/components/Input/InputPhone.tsx
8
+ //#region src/components/InputPhone/InputPhone.tsx
9
9
  var o = ({ label: o, id: s, labelPosition: c = "top", required: l = !1, defaultCountry: u = "us", error: d, style: f, className: p, ...m }) => {
10
10
  let h = i(), g = s || h, _ = r.useRef(null);
11
11
  return /* @__PURE__ */ n(e, {
@@ -1,4 +1,4 @@
1
- import { InputProps } from './Input';
1
+ import { InputProps } from '../Input/Input';
2
2
  type RadioButtonProps = InputProps & {
3
3
  type?: "radio";
4
4
  labelPosition?: "left" | "right";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { Input as e } from "./Input2.esm.js";
2
+ import { Input as e } from "../Input/Input2.esm.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
- //#region src/components/Input/RadioButton.tsx
4
+ //#region src/components/RadioButton/RadioButton.tsx
5
5
  var n = ({ type: n = "radio", labelPosition: r = "right", ...i }) => /* @__PURE__ */ t(e, {
6
6
  type: n,
7
7
  labelPosition: r,
@@ -1,3 +1,3 @@
1
- import { LabeledInput } from './InputWrapper';
1
+ import { LabeledInput } from '../Input/InputWrapper';
2
2
  export type TextareaProps = React.ComponentProps<"textarea"> & LabeledInput;
3
3
  export declare const Textarea: React.FC<TextareaProps>;
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { InputWrapper as e } from "./InputWrapper.esm.js";
2
+ import { InputWrapper as e } from "../Input/InputWrapper.esm.js";
3
3
  import t from "clsx";
4
4
  import { jsx as n } from "react/jsx-runtime";
5
5
  import { useId as r } from "react";
6
- //#region src/components/Input/Textarea.tsx
6
+ //#region src/components/Textarea/Textarea.tsx
7
7
  var i = ({ labelPosition: i = "top", id: a, label: o, error: s, required: c, className: l, style: u, ...d }) => {
8
8
  let f = r(), p = a || f;
9
9
  return /* @__PURE__ */ n(e, {
@@ -0,0 +1 @@
1
+ @layer craftsman-base{.timePicker__wrapper .react-time-picker__clock{display:none}.timePicker__wrapper .timePicker__field{border:1px solid var(--gray400);background:var(--white);border-radius:4px;align-items:center;display:inline-flex;position:relative}.timePicker__wrapper .timePicker__field .input-view-toggle{padding:4px;line-height:1;position:absolute;top:50%;right:4px;transform:translateY(-50%)}.timePicker__wrapper .timePicker__field .react-time-picker__wrapper{border:none;padding-right:32px}.timePicker{background-color:var(--white);border:1px solid var(--gray400);z-index:1;border-radius:8px;height:160px;display:inline-flex;position:relative}.timePicker:before,.timePicker:after{content:"";z-index:1;pointer-events:none;height:calc(50% - 16px);display:block;position:absolute;left:0;right:0}.timePicker:before{border-bottom:.5px solid rgba(var(--text-high-contrast-rgb-value), .3);background:linear-gradient(to top, rgba(var(--background-site-rgb-value), .65) 0%, rgba(var(--background-site-rgb-value), 1) 100%);top:-.5px}.timePicker:after{border-top:.5px solid rgba(var(--text-high-contrast-rgb-value), .3);background:linear-gradient(to bottom, rgba(var(--background-site-rgb-value), .65) 0%, rgba(var(--background-site-rgb-value), 1) 100%);bottom:-.5px}.timePicker__display{border:1px solid var(--gray400);padding:calc(var(--w-gutter) * .25) 30px calc(var(--w-gutter) * .25) calc(var(--w-gutter) * .5);z-index:1;background-color:#fff;border-radius:4px;align-items:center;gap:2px;display:inline-flex;position:relative}.timePicker__display input,.timePicker__display select{padding:calc(var(--w-gutter) * .25);border:none}.timePicker__display select::picker-icon{display:none}.timePicker__display .input-view-toggle{right:calc(var(--w-gutter) * .5);position:absolute}.timePicker .ios-picker{flex-direction:row;align-items:center;gap:6px;height:100%;padding:0 12px;font-size:16px;line-height:1;display:flex}.timePicker .ios-picker--disabled{pointer-events:none;opacity:.5}.timePicker .ios-picker__scene{touch-action:pan-x;align-items:center;min-width:30px;height:100%;display:flex;overflow:hidden}.timePicker .ios-picker__viewport{perspective:1000px;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;-khtml-user-select:none;-webkit-tap-highlight-color:transparent;width:100%;height:32px}.timePicker .ios-picker__viewport--perspective-left{perspective-origin:calc(50% + 130px);transform:translate(27px)}.timePicker .ios-picker__viewport--perspective-right{perspective-origin:calc(50% - 130px);transform:translate(-27px)}.timePicker .ios-picker__viewport--perspective-center{perspective-origin:50%}.timePicker .ios-picker__container{width:100%;height:100%;transform-style:preserve-3d;will-change:transform}.timePicker .ios-picker__slide{text-align:center;backface-visibility:hidden;opacity:0;justify-content:center;align-items:center;width:100%;height:100%;display:flex}.timePicker .ios-picker__label{white-space:nowrap;pointer-events:none;font-weight:700}}
@@ -1,12 +1,13 @@
1
1
  import { default as React } from 'react';
2
+ import { TimePickerProps as ReactTimePickerProps } from 'react-time-picker';
2
3
  import { LabeledInput } from '../Input/InputWrapper';
3
- type PropType = Omit<React.ComponentProps<"input">, "type"> & LabeledInput & {
4
+ type TimePickerProps = Omit<ReactTimePickerProps, "locale"> & LabeledInput & {
4
5
  locale?: Intl.LocalesArgument;
5
6
  format?: 24 | 12;
6
7
  labels?: {
7
- hour?: "string";
8
- minute?: "string";
8
+ hour?: string;
9
+ minute?: string;
9
10
  };
10
11
  };
11
- export declare const TimePicker: (props: PropType) => React.JSX.Element;
12
+ export declare const TimePicker: React.FC<TimePickerProps>;
12
13
  export {};
@@ -2,6 +2,35 @@
2
2
 
3
3
  @layer craftsman-base {
4
4
 
5
+ .timePicker__wrapper {
6
+ // suppress the built-in clock popup — our custom wheel renders instead
7
+ .react-time-picker__clock { display: none; }
8
+
9
+ .timePicker__field {
10
+ display: inline-flex;
11
+ align-items: center;
12
+ position: relative;
13
+ border: 1px solid #{u.color("gray400")};
14
+ border-radius: 4px;
15
+ background: #{u.color("white")};
16
+
17
+ .input-view-toggle {
18
+ position: absolute;
19
+ right: 4px;
20
+ top: 50%;
21
+ transform: translateY(-50%);
22
+ padding: 4px;
23
+ line-height: 1;
24
+ }
25
+
26
+ // hand off the border to .timePicker__field and make room for the button
27
+ .react-time-picker__wrapper {
28
+ border: none;
29
+ padding-right: 32px;
30
+ }
31
+ }
32
+ }
33
+
5
34
  .timePicker {
6
35
  position: relative;
7
36
  display: inline-flex;
@@ -0,0 +1,129 @@
1
+ "use client";
2
+ import { getAmPmLabels as e, getUnitLabel as t, is24HourFormat as n, isEmpty as r } from "../../utilities/validations.esm.js";
3
+ import { Button as i } from "../Button/Button.esm.js";
4
+ import { InputWrapper as a } from "../Input/InputWrapper.esm.js";
5
+ import { padTime as o, parseTimeString as s, resolveLocale as c, resolveTimeFormat as l, to24Hour as u } from "./utilities.esm.js";
6
+ import { IosPickerItem as d } from "./TimePickerWheel.esm.js";
7
+ import '../../../node_modules/react-time-picker/dist/TimePicker.css';import './TimePicker.css';/* empty css */
8
+ /* empty css */
9
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
10
+ import { useEffect as m, useState as h } from "react";
11
+ import { FaClock as g, FaRegClock as _ } from "react-icons/fa6";
12
+ import { autoUpdate as v, flip as y, offset as b, shift as x, useFloating as S } from "@floating-ui/react-dom";
13
+ import { TimePicker as C } from "react-time-picker";
14
+ //#region src/components/TimePicker/TimePicker.tsx
15
+ var w = (e, t) => e ? t : void 0, T = (T) => {
16
+ let { labels: E, locale: D, format: O, value: k, onChange: A, label: j, labelPosition: M, error: N, required: P, name: F, ...I } = T, [L, R] = h(null), [z, B] = h(null), { floatingStyles: V } = S({
17
+ placement: "bottom-start",
18
+ strategy: "absolute",
19
+ whileElementsMounted: v,
20
+ middleware: [
21
+ b(4),
22
+ y(),
23
+ x()
24
+ ],
25
+ elements: {
26
+ reference: L,
27
+ floating: z
28
+ }
29
+ }), [H, U] = h(!1), W = c(D), [G, K] = s(k), q = !r(k), J = l(O, n(W)), Y = +(J === 12), X = J === 12 ? e(W) : null, Z = +(G >= 12), Q = J === 12 ? (G % 12 + 11) % 12 : G;
30
+ m(() => {
31
+ if (!H) return;
32
+ let e = (e) => {
33
+ L?.contains(e.target) || z?.contains(e.target) || U(!1);
34
+ };
35
+ return document.addEventListener("pointerdown", e), () => {
36
+ document.removeEventListener("pointerdown", e);
37
+ };
38
+ }, [
39
+ H,
40
+ L,
41
+ z
42
+ ]);
43
+ let $ = (e) => {
44
+ let t = u(e + Y, G >= 12, J === 12);
45
+ A?.(`${o(t)}:${o(K)}`);
46
+ }, ee = (e) => {
47
+ A?.(`${o(G)}:${o(e)}`);
48
+ }, te = (e) => {
49
+ let t = e === 1;
50
+ if (t === G >= 12) return;
51
+ let n = t ? G + 12 : G - 12;
52
+ A?.(`${o(n)}:${o(K)}`);
53
+ };
54
+ return /* @__PURE__ */ p("div", {
55
+ className: "timePicker__wrapper",
56
+ ref: R,
57
+ onFocus: (e) => {
58
+ e.target instanceof HTMLInputElement && U(!0);
59
+ },
60
+ children: [
61
+ F && /* @__PURE__ */ f("input", {
62
+ type: "hidden",
63
+ name: F,
64
+ value: typeof k == "string" ? k : "",
65
+ readOnly: !0
66
+ }),
67
+ /* @__PURE__ */ f(a, {
68
+ label: j,
69
+ labelPosition: M,
70
+ error: N,
71
+ required: P,
72
+ children: /* @__PURE__ */ p("div", {
73
+ className: "timePicker__field",
74
+ children: [/* @__PURE__ */ f(C, {
75
+ ...I,
76
+ value: k,
77
+ onChange: A,
78
+ locale: W,
79
+ required: P,
80
+ disableClock: !0
81
+ }), /* @__PURE__ */ f(i, {
82
+ type: "button",
83
+ variant: "text",
84
+ onClick: () => U((e) => !e),
85
+ "aria-label": H ? "Hide time picker" : "Show time picker",
86
+ "aria-pressed": H,
87
+ className: "input-view-toggle",
88
+ children: f(H ? g : _, { size: 16 })
89
+ })]
90
+ })
91
+ }),
92
+ H && /* @__PURE__ */ p("div", {
93
+ className: "timePicker",
94
+ ref: B,
95
+ style: V,
96
+ children: [
97
+ /* @__PURE__ */ f(d, {
98
+ slideCount: J,
99
+ perspective: "left",
100
+ loop: !0,
101
+ offset: Y,
102
+ selectedIndex: w(q, Q),
103
+ onSelect: $,
104
+ label: t(W, "hour", E?.hour)
105
+ }),
106
+ /* @__PURE__ */ f(d, {
107
+ slideCount: 60,
108
+ perspective: "right",
109
+ loop: !0,
110
+ selectedIndex: w(q, K),
111
+ onSelect: ee,
112
+ label: t(W, "minute", E?.minute)
113
+ }),
114
+ J === 12 && X && /* @__PURE__ */ f(d, {
115
+ slideCount: 2,
116
+ perspective: "center",
117
+ loop: !1,
118
+ slides: X,
119
+ selectedIndex: w(q, Z),
120
+ onSelect: te,
121
+ label: ""
122
+ })
123
+ ]
124
+ })
125
+ ]
126
+ });
127
+ };
128
+ //#endregion
129
+ export { T as TimePicker };
@@ -1,12 +1,17 @@
1
1
  type TimePickerDisplayProps = {
2
2
  hours: number;
3
3
  minutes: number;
4
- hasValue: boolean;
4
+ hourHasValue: boolean;
5
+ minuteHasValue: boolean;
5
6
  isReadOnly: boolean;
6
7
  timeFormat: 12 | 24;
7
8
  amPmLabels: string[] | null;
8
9
  visible: boolean;
9
10
  onToggleVisible: () => void;
11
+ onClear: {
12
+ hour: () => void;
13
+ minute: () => void;
14
+ };
10
15
  onChange: {
11
16
  hour: (e: React.ChangeEvent<HTMLInputElement>) => void;
12
17
  minute: (e: React.ChangeEvent<HTMLInputElement>) => void;
@@ -0,0 +1,61 @@
1
+ "use client";
2
+ import e from "../../../node_modules/embla-carousel-react/esm/embla-carousel-react.esm.esm.js";
3
+ import "./constants.esm.js";
4
+ import { inactivateEmblaTransform as t, setContainerStyles as n, setSlideStyles as r, snapOnPointerUp as i } from "./utilities.esm.js";
5
+ import a from "clsx";
6
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
+ import { useCallback as c, useEffect as l, useLayoutEffect as u, useRef as d } from "react";
8
+ //#region src/components/TimePicker/TimePickerWheel.tsx
9
+ var f = (f) => {
10
+ let { slideCount: p, perspective: m, label: h, loop: g = !1, offset: _ = 0, slides: v, selectedIndex: y, onSelect: b, disabled: x } = f, [S, C] = e({
11
+ loop: g,
12
+ axis: "y",
13
+ dragFree: !0,
14
+ containScroll: !1
15
+ }), w = d(null), T = d(b);
16
+ u(() => {
17
+ T.current = b;
18
+ });
19
+ let E = p * 20, D = g ? 0 : 20, O = c((e) => {
20
+ n(e, (p * 20 - D) * e.scrollProgress()), e.slideNodes().forEach((t, n) => {
21
+ r(e, n, g, p, E);
22
+ });
23
+ }, [
24
+ g,
25
+ p,
26
+ D,
27
+ E
28
+ ]);
29
+ return l(() => {
30
+ if (!C) return () => {};
31
+ let e = (e) => T.current?.(e.selectedScrollSnap());
32
+ return C.on("pointerUp", i), C.on("scroll", O), C.on("reInit", t), C.on("reInit", O), C.on("select", e), t(C), O(C), () => {
33
+ C.off("pointerUp", i), C.off("scroll", O), C.off("reInit", t), C.off("reInit", O), C.off("select", e);
34
+ };
35
+ }, [C, O]), l(() => {
36
+ !C || y === void 0 || C.selectedScrollSnap() !== y && C.scrollTo(y);
37
+ }, [C, y]), /* @__PURE__ */ s("div", {
38
+ className: a("ios-picker", { "ios-picker--disabled": x }),
39
+ "aria-disabled": x,
40
+ children: [/* @__PURE__ */ o("div", {
41
+ className: "ios-picker__scene",
42
+ ref: w,
43
+ children: /* @__PURE__ */ o("div", {
44
+ className: `ios-picker__viewport ios-picker__viewport--perspective-${m}`,
45
+ ref: S,
46
+ children: /* @__PURE__ */ o("div", {
47
+ className: "ios-picker__container",
48
+ children: Array.from({ length: p }, (e, t) => /* @__PURE__ */ o("div", {
49
+ className: "ios-picker__slide",
50
+ children: v ? v[t] : t + _
51
+ }, t))
52
+ })
53
+ })
54
+ }), /* @__PURE__ */ o("div", {
55
+ className: "ios-picker__label",
56
+ children: h
57
+ })]
58
+ });
59
+ };
60
+ //#endregion
61
+ export { f as IosPickerItem };
@@ -0,0 +1,3 @@
1
+ var e = Math.round(32 / 2 / Math.tan(Math.PI / 18));
2
+ //#endregion
3
+ export { e as WHEEL_RADIUS };
@@ -4,6 +4,7 @@ export declare const padTime: (n: number) => string;
4
4
  export declare const toDisplayHour: (hours: number, is12h: boolean) => number;
5
5
  export declare const to24Hour: (display: number, isPM: boolean, is12h: boolean) => number;
6
6
  export declare const resolveLocale: (locale?: Intl.LocalesArgument) => string;
7
+ export declare const resolveTimeFormat: (format: 24 | 12 | undefined, is24h: boolean) => 24 | 12;
7
8
  export declare const isInView: (wheelLocation: number, slidePosition: number) => boolean;
8
9
  export declare const setSlideStyles: (emblaApi: EmblaCarouselType, index: number, loop: boolean, slideCount: number, totalRadius: number) => void;
9
10
  export declare const setContainerStyles: (emblaApi: EmblaCarouselType, wheelRotation: number) => void;
@@ -0,0 +1,20 @@
1
+ import { WHEEL_RADIUS as e } from "./constants.esm.js";
2
+ //#region src/components/TimePicker/utilities.ts
3
+ var t = (e) => {
4
+ if (typeof e != "string" || !e.includes(":")) return [0, 0];
5
+ let [t, n] = e.split(":").map(Number);
6
+ return [isNaN(t) ? 0 : t, isNaN(n) ? 0 : n];
7
+ }, n = (e) => String(e).padStart(2, "0"), r = (e, t, n) => n ? e === 12 ? t ? 12 : 0 : t ? e + 12 : e : e, i = (e) => e ? String(Array.isArray(e) ? e[0] : e) : typeof navigator < "u" ? navigator.language : "en-US", a = (e, t) => e ?? (t ? 24 : 12), o = (e, t) => Math.abs(e - t) < 80, s = (t, n, r, i, a) => {
8
+ let s = t.slideNodes()[n], c = t.scrollProgress() * a, l = t.scrollSnapList()[n] * a, u = l + a, d = l - a, f = !1, p = n * -20;
9
+ o(c, l) && (f = !0), r && o(c, d) && (f = !0, p = -360 + (i - n) * 20), r && o(c, u) && (f = !0, p = -(a % 360) - n * 20), f ? (s.style.opacity = "1", s.style.transform = `translateY(-${n * 100}%) rotateX(${p}deg) translateZ(${e}px)`) : (s.style.opacity = "0", s.style.transform = "none");
10
+ }, c = (t, n) => {
11
+ t.containerNode().style.transform = `translateZ(${e}px) rotateX(${n}deg)`;
12
+ }, l = (e) => {
13
+ let { translate: t } = e.internalEngine();
14
+ t.clear(), t.toggleActive(!1);
15
+ }, u = (e) => {
16
+ let { scrollTo: t, target: n, location: r } = e.internalEngine(), i = n.get() - r.get(), a = Math.abs(i) < 32 / 2.5 ? 10 : .1;
17
+ t.distance(i * a, !0);
18
+ };
19
+ //#endregion
20
+ export { l as inactivateEmblaTransform, o as isInView, n as padTime, t as parseTimeString, i as resolveLocale, a as resolveTimeFormat, c as setContainerStyles, s as setSlideStyles, u as snapOnPointerUp, r as to24Hour };
@@ -0,0 +1,12 @@
1
+ import { Placement, Strategy } from '@floating-ui/react-dom';
2
+ import { default as React } from 'react';
3
+ export type TooltipProps = {
4
+ anchor: React.ReactNode;
5
+ content: React.ReactNode;
6
+ placement?: Placement;
7
+ strategy?: Strategy;
8
+ showContent?: "hover" | "click";
9
+ anchorStyles?: React.CSSProperties;
10
+ contentStyles?: React.CSSProperties;
11
+ };
12
+ export declare const Tooltip: React.FC<TooltipProps>;
@@ -0,0 +1,29 @@
1
+ @use "../../styles/utilities/functions" as u;
2
+
3
+ @layer craftsman-base {
4
+ .tooltip {
5
+ --tooltip-bg: #{u.color("gray800")};
6
+
7
+ &__floating {
8
+ position: relative;
9
+ background-color: var(--tooltip-bg);
10
+ color: #{u.color("white")};
11
+ padding: #{u.width("gutter", 0.25)} #{u.width("gutter", 0.5)};
12
+ border-radius: 6px;
13
+
14
+ &::before {
15
+ content: '';
16
+ position: absolute;
17
+ width: 8px;
18
+ height: 8px;
19
+ background-color: var(--tooltip-bg);
20
+ transform: rotate(45deg);
21
+ }
22
+
23
+ &[data-placement^="bottom"]::before { top: -4px; left: 50%; margin-left: -4px; }
24
+ &[data-placement^="top"]::before { bottom: -4px; left: 50%; margin-left: -4px; }
25
+ &[data-placement^="left"]::before { right: -4px; top: 50%; margin-top: -4px; }
26
+ &[data-placement^="right"]::before { left: -4px; top: 50%; margin-top: -4px; }
27
+ }
28
+ }
29
+ }