@stamcat/craftsman 0.0.27-alpha.2 → 0.0.27-alpha.21

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 (221) hide show
  1. package/AGENTS.md +19 -344
  2. package/Components.esm.js +72 -11
  3. package/README.md +5 -0
  4. package/Styles.esm.js +7 -7
  5. package/Utilities.esm.js +2 -2
  6. package/_virtual/_rolldown/runtime.esm.js +18 -6
  7. package/package.json +75 -6
  8. package/src/components/Button/AGENTS.md +65 -0
  9. package/src/components/{Button.d.ts → Button/Button.d.ts} +1 -1
  10. package/src/components/Button/Button.esm.js +20 -0
  11. package/src/components/Carousel/AGENTS.md +41 -0
  12. package/src/components/Carousel/Carousel.css +1 -0
  13. package/src/components/Carousel/Carousel.d.ts +11 -0
  14. package/src/components/Carousel/Carousel.scss +34 -0
  15. package/src/components/Carousel/Carousel2.esm.js +75 -0
  16. package/src/components/Checkbox/AGENTS.md +34 -0
  17. package/src/components/Checkbox/Checkbox.d.ts +8 -0
  18. package/src/components/Checkbox/Checkbox.esm.js +18 -0
  19. package/src/components/DatePicker/AGENTS.md +36 -0
  20. package/src/components/DatePicker/DatePicker.css +1 -0
  21. package/src/components/DatePicker/DatePicker.d.ts +8 -0
  22. package/src/components/DatePicker/DatePicker.scss +61 -0
  23. package/src/components/DatePicker/DatePicker2.esm.js +29 -0
  24. package/src/components/DatePicker/ReactCalendar.css +1 -0
  25. package/src/components/DatePicker/ReactCalendar.scss +158 -0
  26. package/src/components/DatePicker/_DatePicker.scss +73 -0
  27. package/src/components/DateRangePicker/AGENTS.md +38 -0
  28. package/src/components/DateRangePicker/DateRangePicker.css +1 -0
  29. package/src/components/DateRangePicker/DateRangePicker.d.ts +8 -0
  30. package/src/components/DateRangePicker/DateRangePicker.scss +62 -0
  31. package/src/components/DateRangePicker/DateRangePicker2.esm.js +29 -0
  32. package/src/components/DateTimePicker/AGENTS.md +41 -0
  33. package/src/components/DateTimePicker/DateTimePicker.css +1 -0
  34. package/src/components/DateTimePicker/DateTimePicker.d.ts +13 -0
  35. package/src/components/DateTimePicker/DateTimePicker.scss +86 -0
  36. package/src/components/DateTimePicker/DateTimePicker2.esm.js +82 -0
  37. package/src/components/Icons/IconAmazonPay.d.ts +2 -0
  38. package/src/components/Icons/IconAmazonPay.esm.js +76 -0
  39. package/src/components/Icons/IconAmex.d.ts +2 -0
  40. package/src/components/Icons/IconAmex.esm.js +87 -0
  41. package/src/components/Icons/IconApplePay.d.ts +2 -0
  42. package/src/components/Icons/IconApplePay.esm.js +26 -0
  43. package/src/components/Icons/IconDiscover.d.ts +2 -0
  44. package/src/components/Icons/IconDiscover.esm.js +129 -0
  45. package/src/components/Icons/IconGooglePay.d.ts +2 -0
  46. package/src/components/Icons/IconGooglePay.esm.js +64 -0
  47. package/src/components/Icons/IconMaestro.d.ts +2 -0
  48. package/src/components/Icons/IconMaestro.esm.js +38 -0
  49. package/src/components/Icons/IconMastercard.d.ts +2 -0
  50. package/src/components/Icons/IconMastercard.esm.js +27 -0
  51. package/src/components/Icons/IconPayPal.d.ts +2 -0
  52. package/src/components/Icons/IconPayPal.esm.js +52 -0
  53. package/src/components/Icons/IconSepa.d.ts +2 -0
  54. package/src/components/Icons/IconSepa.esm.js +272 -0
  55. package/src/components/Icons/IconShopPay.d.ts +2 -0
  56. package/src/components/Icons/IconShopPay.esm.js +35 -0
  57. package/src/components/Icons/IconSquare.d.ts +2 -0
  58. package/src/components/Icons/IconSquare.esm.js +11 -0
  59. package/src/components/Icons/IconStripe.d.ts +2 -0
  60. package/src/components/Icons/IconStripe.esm.js +57 -0
  61. package/src/components/Icons/IconUnionPay.d.ts +2 -0
  62. package/src/components/Icons/IconUnionPay.esm.js +28 -0
  63. package/src/components/Icons/IconVenmo.d.ts +2 -0
  64. package/src/components/Icons/IconVenmo.esm.js +21 -0
  65. package/src/components/Icons/IconVisa.d.ts +2 -0
  66. package/src/components/Icons/IconVisa.esm.js +14 -0
  67. package/src/components/Icons/index.d.ts +15 -0
  68. package/src/components/Icons/index.esm.js +16 -0
  69. package/src/components/Icons/types.d.ts +4 -0
  70. package/src/components/Input/AGENTS.md +30 -0
  71. package/src/components/Input/Input.css +1 -0
  72. package/src/components/Input/Input.d.ts +6 -0
  73. package/src/components/Input/Input.scss +176 -0
  74. package/src/components/Input/Input2.esm.js +42 -0
  75. package/src/components/Input/InputWrapper.d.ts +11 -0
  76. package/src/components/Input/InputWrapper.esm.js +22 -0
  77. package/src/components/InputNumber/AGENTS.md +37 -0
  78. package/src/components/InputNumber/InputNumber.css +1 -0
  79. package/src/components/InputNumber/InputNumber.d.ts +10 -0
  80. package/src/components/InputNumber/InputNumber.scss +29 -0
  81. package/src/components/InputNumber/InputNumber2.esm.js +36 -0
  82. package/src/components/InputPassword/AGENTS.md +29 -0
  83. package/src/components/{InputPassword.d.ts → InputPassword/InputPassword.d.ts} +2 -2
  84. package/src/components/InputPassword/InputPassword.esm.js +30 -0
  85. package/src/components/InputPhone/AGENTS.md +35 -0
  86. package/src/components/InputPhone/InputPhone.css +1 -0
  87. package/src/components/InputPhone/InputPhone.d.ts +7 -0
  88. package/src/components/InputPhone/InputPhone.scss +266 -0
  89. package/src/components/InputPhone/InputPhone2.esm.js +27 -0
  90. package/src/components/Loader/AGENTS.md +31 -0
  91. package/src/components/{Loader.d.ts → Loader/Loader.d.ts} +1 -2
  92. package/src/components/Loader/Loader.esm.js +19 -0
  93. package/src/components/Loader/loaders.module.css +1 -0
  94. package/src/components/Loader/loaders.module.esm.js +21 -0
  95. package/src/{styles/global/components → components/Loader}/loaders.module.scss +2 -1
  96. package/src/components/Modal/AGENTS.md +47 -0
  97. package/src/components/Modal/Modal.css +1 -0
  98. package/src/components/{Modal.d.ts → Modal/Modal.d.ts} +0 -1
  99. package/src/components/Modal/Modal.scss +150 -0
  100. package/src/components/Modal/Modal2.esm.js +53 -0
  101. package/src/components/Notice/AGENTS.md +42 -0
  102. package/src/components/Notice/Notice.css +1 -0
  103. package/src/components/Notice/Notice.d.ts +13 -0
  104. package/src/components/Notice/Notice.scss +76 -0
  105. package/src/components/Notice/Notice2.esm.js +56 -0
  106. package/src/components/Pagination/AGENTS.md +38 -0
  107. package/src/components/Pagination/Pagination.css +1 -0
  108. package/src/components/Pagination/Pagination.d.ts +10 -0
  109. package/src/components/Pagination/Pagination.scss +22 -0
  110. package/src/components/Pagination/Pagination2.esm.js +64 -0
  111. package/src/components/RadioButton/AGENTS.md +44 -0
  112. package/src/components/RadioButton/RadioButton.d.ts +9 -0
  113. package/src/components/RadioButton/RadioButton.esm.js +18 -0
  114. package/src/components/Select/AGENTS.md +36 -0
  115. package/src/components/Select/Select.d.ts +14 -0
  116. package/src/components/Select/Select.esm.js +26 -0
  117. package/src/components/SortableList/AGENTS.md +45 -0
  118. package/src/components/SortableList/ListItem.d.ts +10 -0
  119. package/src/components/SortableList/ListItem.esm.js +67 -0
  120. package/src/components/SortableList/SortableList.css +1 -0
  121. package/src/components/SortableList/SortableList.d.ts +23 -0
  122. package/src/components/SortableList/SortableList.scss +41 -0
  123. package/src/components/SortableList/SortableList2.esm.js +54 -0
  124. package/src/components/SortableList/utilities.d.ts +7 -0
  125. package/src/components/SortableList/utilities.esm.js +4 -0
  126. package/src/components/Text/AGENTS.md +32 -0
  127. package/src/components/Text/Text.css +1 -0
  128. package/src/components/Text/Text.d.ts +10 -0
  129. package/src/components/Text/Text.scss +80 -0
  130. package/src/components/Text/Text2.esm.js +23 -0
  131. package/src/components/Textarea/AGENTS.md +32 -0
  132. package/src/components/Textarea/Textarea.d.ts +3 -0
  133. package/src/components/Textarea/Textarea.esm.js +23 -0
  134. package/src/components/TimePicker/AGENTS.md +42 -0
  135. package/src/components/TimePicker/TimePicker.css +1 -0
  136. package/src/components/TimePicker/TimePicker.d.ts +13 -0
  137. package/src/components/TimePicker/TimePicker.scss +226 -0
  138. package/src/components/TimePicker/TimePicker2.esm.js +98 -0
  139. package/src/components/TimePicker/TimePickerDisplay.d.ts +16 -0
  140. package/src/components/TimePicker/TimePickerDisplay.esm.js +54 -0
  141. package/src/components/TimePicker/TimePickerWheel.d.ts +13 -0
  142. package/src/components/TimePicker/TimePickerWheel.esm.js +61 -0
  143. package/src/components/TimePicker/constants.d.ts +7 -0
  144. package/src/components/TimePicker/constants.esm.js +3 -0
  145. package/src/components/TimePicker/utilities.d.ts +15 -0
  146. package/src/components/TimePicker/utilities.esm.js +20 -0
  147. package/src/components/Toggle/AGENTS.md +33 -0
  148. package/src/components/Toggle/Toggle.css +1 -0
  149. package/src/components/Toggle/Toggle.d.ts +5 -0
  150. package/src/components/Toggle/Toggle.scss +64 -0
  151. package/src/components/Toggle/Toggle2.esm.js +19 -0
  152. package/src/components/Tooltip/AGENTS.md +41 -0
  153. package/src/components/Tooltip/Tooltip.css +1 -0
  154. package/src/components/Tooltip/Tooltip.d.ts +12 -0
  155. package/src/components/Tooltip/Tooltip.scss +29 -0
  156. package/src/components/Tooltip/Tooltip2.esm.js +65 -0
  157. package/src/components/index.d.ts +23 -7
  158. package/src/stories/assets/Stam.jpg +0 -0
  159. package/src/stories/assets/kaluah.jpg +0 -0
  160. package/src/stories/assets/stam2.jpg +0 -0
  161. package/src/stories/assets/tito.jpg +0 -0
  162. package/src/stories/documentation/AboutUs.mdx +21 -0
  163. package/src/stories/documentation/GettingStarted.mdx +117 -0
  164. package/src/stories/documentation/Introduction.mdx +29 -0
  165. package/src/stories/documentation/Themes.mdx +264 -0
  166. package/src/stories/documentation/ToDo.mdx +15 -0
  167. package/src/stories/molecules/Carousel.scss +21 -0
  168. package/src/stories/utilities/DeviceDetection.mdx +59 -0
  169. package/src/styles/_config.scss +30 -0
  170. package/src/styles/components/ThemeProvider.esm.js +1 -1
  171. package/src/styles/global/components/_button.scss +56 -52
  172. package/src/styles/global/components/_checkbox.scss +64 -59
  173. package/src/styles/global/components/_code.scss +19 -15
  174. package/src/styles/global/components/_input.scss +29 -37
  175. package/src/styles/global/components/_radioButton.scss +30 -26
  176. package/src/styles/global/components/_select.scss +56 -0
  177. package/src/styles/global/components/_typography.scss +97 -6
  178. package/src/styles/global/globalStyles.module.scss +1 -129
  179. package/src/styles/global/globalStyles.scss +87 -1
  180. package/src/styles/index.d.ts +1 -1
  181. package/src/styles/theme/components.esm.js +11 -7
  182. package/src/styles/theme/theme.esm.js +31 -41
  183. package/src/styles/theme/types.d.ts +4 -1
  184. package/src/styles/utilities/_functions.scss +117 -0
  185. package/src/styles/utilities/_mixins.scss +0 -0
  186. package/src/styles/utilities/_placeholders.scss +6 -0
  187. package/src/styles/utilities/color.d.ts +1 -1
  188. package/src/styles/utilities/constants.d.ts +1 -1
  189. package/src/styles/utilities/layout.d.ts +1 -1
  190. package/src/styles/utilities/layout.esm.js +3 -3
  191. package/src/{styles/utilities → utilities}/types.d.ts +61 -3
  192. package/src/utilities/types.esm.js +85 -0
  193. package/src/utilities/validations.d.ts +5 -0
  194. package/src/utilities/validations.esm.js +19 -1
  195. package/src/components/Button.esm.js +0 -28
  196. package/src/components/Button.module.css +0 -1
  197. package/src/components/Button.module.esm.js +0 -9
  198. package/src/components/Button.module.scss +0 -5
  199. package/src/components/Checkbox.d.ts +0 -7
  200. package/src/components/Checkbox.esm.js +0 -11
  201. package/src/components/Input.d.ts +0 -11
  202. package/src/components/Input.esm.js +0 -41
  203. package/src/components/Input.module.css +0 -1
  204. package/src/components/Input.module.esm.js +0 -11
  205. package/src/components/Input.module.scss +0 -141
  206. package/src/components/InputPassword.esm.js +0 -33
  207. package/src/components/Loader.esm.js +0 -21
  208. package/src/components/Modal.esm.js +0 -62
  209. package/src/components/Modal.module.css +0 -1
  210. package/src/components/Modal.module.esm.js +0 -13
  211. package/src/components/Modal.module.scss +0 -133
  212. package/src/components/RadioButton.d.ts +0 -7
  213. package/src/components/RadioButton.esm.js +0 -11
  214. package/src/styles/global/components/_mixins.scss +0 -2
  215. package/src/styles/global/components/button.d.ts +0 -7
  216. package/src/styles/global/components/loaders.module.css +0 -1
  217. package/src/styles/global/components/loaders.module.esm.js +0 -21
  218. package/src/styles/utilities/types.esm.js +0 -54
  219. package/src/{styles/global/components/loaders.d.ts → components/Loader/types.d.ts} +1 -1
  220. /package/src/{styles/global/components/loaders.esm.js → components/Loader/types.esm.js} +0 -0
  221. /package/src/components/{Progress.d.ts → Progress/Progress.d.ts} +0 -0
@@ -0,0 +1,15 @@
1
+ export { IconAmazonPay } from './IconAmazonPay';
2
+ export { IconAmex } from './IconAmex';
3
+ export { IconApplePay } from './IconApplePay';
4
+ export { IconDiscover } from './IconDiscover';
5
+ export { IconGooglePay } from './IconGooglePay';
6
+ export { IconMaestro } from './IconMaestro';
7
+ export { IconMastercard } from './IconMastercard';
8
+ export { IconPayPal } from './IconPayPal';
9
+ export { IconSepa } from './IconSepa';
10
+ export { IconShopPay } from './IconShopPay';
11
+ export { IconSquare } from './IconSquare';
12
+ export { IconStripe } from './IconStripe';
13
+ export { IconUnionPay } from './IconUnionPay';
14
+ export { IconVenmo } from './IconVenmo';
15
+ export { IconVisa } from './IconVisa';
@@ -0,0 +1,16 @@
1
+ import { IconAmazonPay as e } from "./IconAmazonPay.esm.js";
2
+ import { IconAmex as t } from "./IconAmex.esm.js";
3
+ import { IconApplePay as n } from "./IconApplePay.esm.js";
4
+ import { IconDiscover as r } from "./IconDiscover.esm.js";
5
+ import { IconGooglePay as i } from "./IconGooglePay.esm.js";
6
+ import { IconMaestro as a } from "./IconMaestro.esm.js";
7
+ import { IconMastercard as o } from "./IconMastercard.esm.js";
8
+ import { IconPayPal as s } from "./IconPayPal.esm.js";
9
+ import { IconSepa as c } from "./IconSepa.esm.js";
10
+ import { IconShopPay as l } from "./IconShopPay.esm.js";
11
+ import { IconSquare as u } from "./IconSquare.esm.js";
12
+ import { IconStripe as d } from "./IconStripe.esm.js";
13
+ import { IconUnionPay as f } from "./IconUnionPay.esm.js";
14
+ import { IconVenmo as p } from "./IconVenmo.esm.js";
15
+ import { IconVisa as m } from "./IconVisa.esm.js";
16
+ export { e as IconAmazonPay, t as IconAmex, n as IconApplePay, r as IconDiscover, i as IconGooglePay, a as IconMaestro, o as IconMastercard, s as IconPayPal, c as IconSepa, l as IconShopPay, u as IconSquare, d as IconStripe, f as IconUnionPay, p as IconVenmo, m as IconVisa };
@@ -0,0 +1,4 @@
1
+ import { SVGProps } from 'react';
2
+ export type SVGIconProps = Omit<SVGProps<SVGSVGElement>, 'width'> & {
3
+ width?: number;
4
+ };
@@ -0,0 +1,30 @@
1
+ # Input — Agent Usage Notes
2
+
3
+ Import:
4
+
5
+ ```tsx
6
+ import { Input } from "@stamcat/craftsman/Input";
7
+ ```
8
+
9
+ Props:
10
+
11
+ - Inherits native `<input>` props.
12
+ - `label?: string | ReactNode`
13
+ - `labelPosition?: "top" | "left" | "bottom" | "right" | "inside" | "hidden"` (default: `"top"`)
14
+ - `error?: string | boolean | ReactNode`
15
+ - `required?: boolean`
16
+ - `styles?: React.CSSProperties` (wrapper override)
17
+ - `type?: TextInputType` (checkbox/radio excluded)
18
+
19
+ Behavior notes:
20
+
21
+ - `id` is preserved; if omitted, a stable React `useId` value is used.
22
+ - Floating-label behavior is supported when `labelPosition="inside"`.
23
+ - `endAdornment` exists as an internal extension point used by `InputPassword`; consumer apps should prefer `InputPassword` rather than wiring password toggles on `Input`.
24
+ - `preAdornment` is an internal extension point used by `InputNumber` for its decrement button; consumer apps should prefer `InputNumber` rather than wiring stepper buttons on `Input` directly.
25
+
26
+ Example:
27
+
28
+ ```tsx
29
+ <Input type="email" placeholder="you@company.com" required />
30
+ ```
@@ -0,0 +1 @@
1
+ @layer craftsman-base{.input-pre-adornment,.input-end-adornment{z-index:1;align-items:center;margin-top:0;display:inline-flex;position:absolute;top:50%;transform:translateY(-50%)}.input-wrapper label .input-label{margin-bottom:calc(var(--w-gutter) * .25)}.input-wrapper[data-required=true] label .input-label:after{content:"*";color:var(--red700)}.input-wrapper[data-label-position=left] label{align-items:center;display:inline-flex}.input-wrapper[data-label-position=left] label .input-label{width:fit-content;margin-right:calc(var(--w-gutter) * .75)}.input-wrapper[data-label-position=left].textarea label{align-items:flex-start}.input-wrapper[data-label-position=bottom] label{flex-direction:column-reverse;align-items:flex-start;display:inline-flex}.input-wrapper[data-label-position=bottom] label .input-label{margin-bottom:0;margin-top:calc(var(--w-gutter) * .25)}.input-wrapper[data-label-position=right] label{flex-direction:row-reverse;align-items:baseline;display:inline-flex}.input-wrapper[data-label-position=right] label .input-label{margin-left:calc(var(--w-gutter) * .25);margin-bottom:0}.input-wrapper[data-label-position=inside]{--react-international-phone-height:50px;--react-international-phone-border-radius:8px;--react-international-phone-border-color:silver;position:relative}.input-wrapper[data-label-position=inside] .input-label{background-color:var(--white);z-index:1;width:fit-content;top:calc(var(--w-gutter) * .45);left:calc(var(--w-gutter) * .25);pointer-events:none;padding:0 5px;transition:top .15s,left .15s,font-size .15s,color .15s;position:absolute}.input-wrapper[data-label-position=inside]>label>.input-field>.input,.input-wrapper[data-label-position=inside]>.input{transition:border-color .2s}.input-wrapper[data-label-position=inside]:focus-within .input-label{top:-.5rem;left:calc(var(--w-gutter) * .125);font-size:calc(var(--w-text) * .75);color:var(--blue500)}.input-wrapper[data-label-position=inside]:focus-within .input{border-color:var(--blue500)}.input-wrapper[data-label-position=inside]:focus-within .input::placeholder{opacity:1}.input-wrapper[data-label-position=inside][data-has-input=true] .input-label{top:-.5rem;left:calc(var(--w-gutter) * .125);font-size:calc(var(--w-text) * .75)}.input-wrapper[data-label-position=inside] .input[type=tel]{width:100%}.input-wrapper[data-label-position=inside] .input::placeholder{opacity:0;transition:opacity .2s}.input-field{align-items:center;display:inline-flex;position:relative}.input-field[data-has-end-adornment=true]>.input{padding-right:calc(var(--w-gutter) * 1.5)}.input-field[data-has-pre-adornment=true]>.input{padding-left:calc(var(--w-gutter) * 2.25)}.input-end-adornment{right:calc(var(--w-gutter) * .5)}.input-pre-adornment{left:calc(var(--w-gutter) * .5)}.input-error{margin-top:calc(var(--w-gutter) * .25);font-size:calc(var(--w-text) * .75);color:var(--red600)}.input-view-toggle{align-items:"center";padding:0;line-height:1;display:inline-flex}}
@@ -0,0 +1,6 @@
1
+ import { LabeledInput } from './InputWrapper';
2
+ import { TextInputType } from '../../utilities/types';
3
+ export type InputProps = React.ComponentProps<"input"> & LabeledInput & {
4
+ type?: TextInputType;
5
+ };
6
+ export declare const Input: React.FC<InputProps>;
@@ -0,0 +1,176 @@
1
+ @use "../../styles/global/components/input";
2
+ @use "../../styles/utilities/_functions" as u;
3
+
4
+ @mixin inside-input-label-floating {
5
+ top: -0.5rem;
6
+ left: #{u.width("gutter", 0.125)};
7
+ font-size: #{u.width("text", 0.75)};
8
+ }
9
+ // This is in base layer because many components implement it.
10
+ @layer craftsman-base {
11
+ %input-adornment {
12
+ position: absolute;
13
+ top: 50%;
14
+ transform: translateY(-50%);
15
+ margin-top: 0;
16
+ z-index: 1;
17
+ display: inline-flex;
18
+ align-items: center;
19
+ }
20
+ .input-wrapper {
21
+ label {
22
+ .input-label {
23
+ margin-bottom: #{u.width("gutter", 0.25)};
24
+ }
25
+ }
26
+
27
+ &[data-required="true"] {
28
+ label {
29
+ .input-label {
30
+ &::after {
31
+ content: "*";
32
+ color: var(--red700);
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ &[data-label-position="left"] {
39
+ label {
40
+ display: inline-flex;
41
+ align-items: center;
42
+
43
+ .input-label {
44
+ width: fit-content;
45
+ margin-right: #{u.width("gutter", 0.75)};
46
+ }
47
+ }
48
+ &.textarea {
49
+ label {
50
+ align-items: flex-start;
51
+ }
52
+ }
53
+ }
54
+
55
+ &[data-label-position="bottom"] {
56
+ label {
57
+ display: inline-flex;
58
+ flex-direction: column-reverse;
59
+ align-items: flex-start;
60
+
61
+ .input-label {
62
+ margin-bottom: 0;
63
+ margin-top: #{u.width("gutter", 0.25)};
64
+ }
65
+ }
66
+ }
67
+
68
+ &[data-label-position="right"] {
69
+ label {
70
+ display: inline-flex;
71
+ flex-direction: row-reverse;
72
+ align-items: baseline;
73
+
74
+ .input-label {
75
+ margin-left: #{u.width("gutter", 0.25)};
76
+ margin-bottom: 0;
77
+ }
78
+ }
79
+ }
80
+
81
+ &[data-label-position="inside"] {
82
+ --react-international-phone-height: 50px;
83
+ --react-international-phone-border-radius: 8px;
84
+ --react-international-phone-border-color: #c0c0c0ff;
85
+ position: relative;
86
+
87
+ .input-label {
88
+ position: absolute;
89
+ background-color: var(--white);
90
+ z-index: 1;
91
+ width: fit-content;
92
+ padding: 0 5px;
93
+ top: #{u.width(gutter, 0.45)};
94
+ left: #{u.width(gutter, 0.25)};
95
+ pointer-events: none;
96
+ transition:
97
+ top 150ms ease,
98
+ left 150ms ease,
99
+ font-size 150ms ease,
100
+ color 150ms ease;
101
+ }
102
+
103
+ > label > .input-field > .input,
104
+ > .input {
105
+ transition: border-color 200ms ease;
106
+ }
107
+
108
+ &:focus-within {
109
+ .input-label {
110
+ @include inside-input-label-floating;
111
+ color: var(--blue500);
112
+ }
113
+
114
+ .input {
115
+ border-color: var(--blue500);
116
+ }
117
+
118
+ .input::placeholder {
119
+ opacity: 1;
120
+ }
121
+ }
122
+
123
+ &[data-has-input="true"] {
124
+ .input-label {
125
+ @include inside-input-label-floating;
126
+ }
127
+ }
128
+
129
+ .input[type="tel"] {
130
+ width: 100%;
131
+ }
132
+
133
+ .input::placeholder {
134
+ opacity: 0;
135
+ transition: opacity 200ms ease;
136
+ }
137
+ }
138
+ }
139
+ .input-field {
140
+ position: relative;
141
+ display: inline-flex;
142
+ align-items: center;
143
+ &[data-has-end-adornment="true"] {
144
+ > .input {
145
+ padding-right: #{u.width("gutter", 1.5)};
146
+ }
147
+ }
148
+ &[data-has-pre-adornment="true"] {
149
+ > .input {
150
+ padding-left: #{u.width("gutter", 2.25)};
151
+ }
152
+ }
153
+ }
154
+
155
+
156
+ .input-end-adornment {
157
+ @extend %input-adornment;
158
+ right: #{u.width("gutter", 0.5)};
159
+ }
160
+ .input-pre-adornment {
161
+ @extend %input-adornment;
162
+ left: #{u.width("gutter", 0.5)};
163
+ }
164
+
165
+ .input-error {
166
+ margin-top: #{u.width("gutter", 0.25)};
167
+ font-size: #{u.width("text", 0.75)};
168
+ color: var(--red600);
169
+ }
170
+ .input-view-toggle {
171
+ padding: 0;
172
+ display: inline-flex;
173
+ align-items: "center";
174
+ line-height: 1;
175
+ }
176
+ }
@@ -0,0 +1,42 @@
1
+ "use client";
2
+ import { isEmpty as e } from "../../utilities/validations.esm.js";
3
+ import { InputWrapper as t } from "./InputWrapper.esm.js";
4
+ import "../../utilities/types.esm.js";
5
+ import n from "clsx";
6
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
7
+ import { useId as a } from "react";
8
+ //#region src/components/Input/Input.tsx
9
+ var o = (o) => {
10
+ let { label: s, id: c, labelPosition: l = "top", required: u = !1, type: d = "text", error: f, endAdornment: p, preAdornment: m, style: h, className: g, ..._ } = o, v = a(), y = c || v;
11
+ return /* @__PURE__ */ r(t, {
12
+ className: g,
13
+ label: s,
14
+ labelPosition: l,
15
+ error: f,
16
+ required: u,
17
+ style: h,
18
+ children: /* @__PURE__ */ i("span", {
19
+ className: "input-field",
20
+ "data-has-end-adornment": !e(p),
21
+ "data-has-pre-adornment": !e(m),
22
+ children: [
23
+ !e(m) && /* @__PURE__ */ r("span", {
24
+ className: "input-pre-adornment",
25
+ children: m
26
+ }),
27
+ /* @__PURE__ */ r("input", {
28
+ id: y,
29
+ type: d,
30
+ className: n("input", d),
31
+ ..._
32
+ }),
33
+ !e(p) && /* @__PURE__ */ r("span", {
34
+ className: "input-end-adornment",
35
+ children: p
36
+ })
37
+ ]
38
+ })
39
+ });
40
+ };
41
+ //#endregion
42
+ export { o as Input };
@@ -0,0 +1,11 @@
1
+ import { LabelPosition } from '../../utilities/types';
2
+ export type LabeledInput = {
3
+ label?: string | React.ReactNode;
4
+ labelPosition?: LabelPosition;
5
+ error?: string | boolean | React.ReactNode;
6
+ required?: boolean;
7
+ endAdornment?: React.ReactNode;
8
+ preAdornment?: React.ReactNode;
9
+ };
10
+ export type InputWrapperProps = React.ComponentProps<"input" | "textarea" | "select"> & LabeledInput;
11
+ export declare const InputWrapper: React.FC<InputWrapperProps>;
@@ -0,0 +1,22 @@
1
+ "use client";
2
+ import { isEmpty as e } from "../../utilities/validations.esm.js";
3
+ import './Input.css';/* empty css */
4
+ import t from "clsx";
5
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
6
+ //#region src/components/Input/InputWrapper.tsx
7
+ var i = ({ label: i, labelPosition: a = "top", required: o = !1, error: s, className: c, style: l, children: u, value: d, defaultValue: f }) => /* @__PURE__ */ r("div", {
8
+ "data-label-position": a,
9
+ "data-required": o,
10
+ "data-has-input": !e(d) || !e(f),
11
+ className: t("input-wrapper", c),
12
+ style: l,
13
+ children: [e(i) ? u : /* @__PURE__ */ r("label", { children: [a !== "hidden" && /* @__PURE__ */ n("div", {
14
+ className: "input-label",
15
+ children: i
16
+ }), u] }), !e(s) && /* @__PURE__ */ n("div", {
17
+ className: "input-error",
18
+ children: s
19
+ })]
20
+ });
21
+ //#endregion
22
+ export { i as InputWrapper };
@@ -0,0 +1,37 @@
1
+ # InputNumber — Agent Usage Notes
2
+
3
+ Import:
4
+
5
+ ```tsx
6
+ import { InputNumber } from "@stamcat/craftsman/InputNumber";
7
+ ```
8
+
9
+ Props:
10
+
11
+ - Extends `Input` props (`Omit<InputProps, "type" | "endAdornment">`).
12
+ - `type?: "number"` (fixed, default: `"number"`)
13
+ - `onDecrement?: (e: React.MouseEvent<HTMLButtonElement>) => void`
14
+ - `onIncrement?: (e: React.MouseEvent<HTMLButtonElement>) => void`
15
+ - `iconIncrement?: React.ReactNode` — overrides the icon rendered in the increment button.
16
+ - `iconDecrement?: React.ReactNode` — overrides the icon rendered in the decrement button.
17
+
18
+ Behavior notes:
19
+
20
+ - Renders an `Input` with a decrement button as `preAdornment` and an increment button as `endAdornment`.
21
+ - Clicking a button calls the native `stepDown()` / `stepUp()` on the underlying `<input type="number">` (honoring `min`, `max`, and `step`), then dispatches a native `input` event so a controlled `onChange` fires exactly like a real number input's spinner.
22
+ - `onDecrement` / `onIncrement` are optional callbacks invoked after the native step — they do not replace `value`/`onChange` control.
23
+ - Use standard controlled `<input type="number">` patterns (`value` + `onChange`) to own the number's state.
24
+
25
+ Example:
26
+
27
+ ```tsx
28
+ const [count, setCount] = useState(0);
29
+
30
+ <InputNumber
31
+ label="Quantity"
32
+ value={count}
33
+ min={0}
34
+ max={10}
35
+ onChange={(e) => setCount(Number(e.currentTarget.value))}
36
+ />
37
+ ```
@@ -0,0 +1 @@
1
+ @layer craftsman-base;@layer craftsman-component{.inputNumber.input-wrapper[data-label-position=inside] .input-label{left:40px}.inputNumber .input-field{gap:calc(var(--w-gutter) * .5)}.inputNumber .input-field[data-has-end-adornment=true]>.input{padding-right:calc(var(--w-gutter) * .75)}.inputNumber .input-field[data-has-pre-adornment=true]>.input{padding-left:calc(var(--w-gutter) * .75)}.inputNumber .input-end-adornment,.inputNumber .input-pre-adornment{position:unset;transform:unset;top:unset}}
@@ -0,0 +1,10 @@
1
+ import { TextInputType } from '../../utilities/types';
2
+ import { InputProps } from '../Input/Input';
3
+ export type InputNumberProps = React.ComponentProps<"input"> & {} & Omit<InputProps, "type" | "endAdornment"> & {
4
+ type?: Extract<TextInputType, "number">;
5
+ onDecrement?: (e: React.MouseEvent<HTMLButtonElement>) => void;
6
+ onIncrement?: (e: React.MouseEvent<HTMLButtonElement>) => void;
7
+ iconIncrement?: React.ReactNode;
8
+ iconDecrement?: React.ReactNode;
9
+ };
10
+ export declare const InputNumber: React.FC<InputNumberProps>;
@@ -0,0 +1,29 @@
1
+ @use "../../styles/global/components/input";
2
+ @use "../../styles/utilities/_functions" as u;
3
+ @use "../../styles/utilities/_placeholders";
4
+
5
+ @layer craftsman-component {
6
+ .inputNumber {
7
+ &.input-wrapper[data-label-position=inside] .input-label {
8
+ left: 40px;
9
+ }
10
+ .input-field {
11
+ gap: #{u.width("gutter", 0.5)};
12
+ }
13
+ .input-field[data-has-end-adornment=true] {
14
+ & > .input {
15
+ padding-right: #{u.width("gutter", 0.75)};
16
+ }
17
+ }
18
+ .input-field[data-has-pre-adornment=true] {
19
+ & > .input {
20
+ padding-left: #{u.width("gutter", 0.75)};
21
+ }
22
+ }
23
+ .input-end-adornment, .input-pre-adornment {
24
+ position: unset;
25
+ transform: unset;
26
+ top: unset;
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ import { Button as e } from "../Button/Button.esm.js";
3
+ import { Input as t } from "../Input/Input2.esm.js";
4
+ import './InputNumber.css';/* empty css */
5
+ import n from "clsx";
6
+ import { jsx as r } from "react/jsx-runtime";
7
+ import { useRef as i } from "react";
8
+ import { IoAddCircleOutline as a, IoRemoveCircleOutline as o } from "react-icons/io5";
9
+ //#region src/components/InputNumber/InputNumber.tsx
10
+ var s = ({ type: s = "number", className: c, iconIncrement: l, iconDecrement: u, onDecrement: d, onIncrement: f, ...p }) => {
11
+ let m = i(null);
12
+ return /* @__PURE__ */ r(t, {
13
+ ref: m,
14
+ className: n("inputNumber", c),
15
+ preAdornment: /* @__PURE__ */ r(e, {
16
+ variant: "text",
17
+ onClick: (e) => {
18
+ let t = m.current;
19
+ t && (t.stepDown(), t.dispatchEvent(new Event("input", { bubbles: !0 }))), d?.(e);
20
+ },
21
+ children: l || /* @__PURE__ */ r(o, { size: "26" })
22
+ }),
23
+ endAdornment: /* @__PURE__ */ r(e, {
24
+ variant: "text",
25
+ onClick: (e) => {
26
+ let t = m.current;
27
+ t && (t.stepUp(), t.dispatchEvent(new Event("input", { bubbles: !0 }))), f?.(e);
28
+ },
29
+ children: u || /* @__PURE__ */ r(a, { size: "26" })
30
+ }),
31
+ ...p,
32
+ type: s
33
+ });
34
+ };
35
+ //#endregion
36
+ export { s as InputNumber };
@@ -0,0 +1,29 @@
1
+ # InputPassword — Agent Usage Notes
2
+
3
+ Import:
4
+
5
+ ```tsx
6
+ import { InputPassword } from "@stamcat/craftsman/InputPassword";
7
+ ```
8
+
9
+ Props:
10
+
11
+ - Extends `Input` props, with `type` constrained to password mode.
12
+ - Includes all label, error, required, and wrapper style props from `Input`.
13
+
14
+ Behavior notes:
15
+
16
+ - Built on top of `Input` and adds an internal password visibility state.
17
+ - Renders an in-field show/hide toggle button.
18
+ - Toggle is accessible: real button element, keyboard operable, and updates `aria-label` + `aria-pressed`.
19
+ - Use this component for password fields instead of `Input type="password"`.
20
+
21
+ Example:
22
+
23
+ ```tsx
24
+ <InputPassword
25
+ label="Password"
26
+ placeholder="Enter your password"
27
+ autoComplete="current-password"
28
+ />
29
+ ```
@@ -1,5 +1,5 @@
1
- import { TextInputType } from '../styles/utilities/types';
2
- import { InputProps } from './Input';
1
+ import { TextInputType } from '../../utilities/types';
2
+ import { InputProps } from '../Input/Input';
3
3
  export type InputPasswordProps = React.ComponentProps<"input"> & {} & Omit<InputProps, "type" | "endAdornment"> & {
4
4
  type?: Extract<TextInputType, "password">;
5
5
  };
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { Button as e } from "../Button/Button.esm.js";
3
+ import { Input as t } from "../Input/Input2.esm.js";
4
+ import n from "clsx";
5
+ import { jsx as r } from "react/jsx-runtime";
6
+ import { useState as i } from "react";
7
+ import { ImEye as a, ImEyeBlocked as o } from "react-icons/im";
8
+ //#region src/components/InputPassword/InputPassword.tsx
9
+ var s = ({ visible: t, onToggle: n }) => /* @__PURE__ */ r(e, {
10
+ type: "button",
11
+ variant: "text",
12
+ onClick: n,
13
+ "aria-label": t ? "Hide password" : "Show password",
14
+ "aria-pressed": t,
15
+ className: "input-view-toggle",
16
+ children: r(t ? a : o, { size: 16 })
17
+ }), c = ({ type: e = "password", className: a, ...o }) => {
18
+ let [c, l] = i(!1), u = c ? "text" : e;
19
+ return /* @__PURE__ */ r(t, {
20
+ className: n("inputPassword", a),
21
+ ...o,
22
+ type: u,
23
+ endAdornment: /* @__PURE__ */ r(s, {
24
+ visible: c,
25
+ onToggle: () => l((e) => !e)
26
+ })
27
+ });
28
+ };
29
+ //#endregion
30
+ export { c as InputPassword };
@@ -0,0 +1,35 @@
1
+ # InputPhone — Agent Usage Notes
2
+
3
+ Import:
4
+
5
+ ```tsx
6
+ import { InputPhone } from "@stamcat/craftsman/InputPhone";
7
+ ```
8
+
9
+ Props:
10
+
11
+ - Extends `PhoneInputProps` from `react-international-phone`.
12
+ - `label?: string | ReactNode`
13
+ - `labelPosition?: "top" | "left" | "bottom" | "right" | "inside" | "hidden"` (default: `"top"`)
14
+ - `error?: string | boolean | ReactNode`
15
+ - `required?: boolean`
16
+ - `defaultCountry?: string` (default: `"us"`)
17
+ - `preferredCountries?: string[]`
18
+ - `endAdornment?: ReactNode`
19
+
20
+ Behavior notes:
21
+
22
+ - Powered by `react-international-phone` for i18n-aware phone number formatting.
23
+ - Country selector dropdown opens below the field; ensure the container has at least 350px of vertical space.
24
+ - Use `preferredCountries` to surface commonly used countries at the top of the dropdown.
25
+
26
+ Example:
27
+
28
+ ```tsx
29
+ <InputPhone
30
+ label="Phone Number"
31
+ defaultCountry="us"
32
+ preferredCountries={["us", "gb", "ca"]}
33
+ required
34
+ />
35
+ ```
@@ -0,0 +1 @@
1
+ @layer craftsman-base;@layer craftsman-component{.inputPhone[data-label-position=inside] .input-label{top:15px;left:50px}.inputPhone .react-international-phone-country-selector{position:relative}.inputPhone .react-international-phone-flag-emoji{width:var(--react-international-phone-flag-width,24px);height:var(--react-international-phone-flag-height,24px);box-sizing:border-box}.inputPhone .react-international-phone-country-selector-button{height:var(--react-international-phone-height,36px);box-sizing:border-box;border:1px solid var(--react-international-phone-country-selector-border-color,var(--react-international-phone-border-color,gainsboro));appearance:button;background-color:var(--react-international-phone-country-selector-background-color,var(--react-international-phone-background-color,white));cursor:pointer;text-transform:none;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;margin:0;padding:0;display:flex}.inputPhone .react-international-phone-country-selector-button:hover{background-color:var(--react-international-phone-country-selector-background-color-hover,whitesmoke)}.inputPhone .react-international-phone-country-selector-button--hide-dropdown{cursor:auto}.inputPhone .react-international-phone-country-selector-button--hide-dropdown:hover{background-color:#0000}.inputPhone .react-international-phone-country-selector-button--disabled{background-color:var(--react-international-phone-disabled-country-selector-background-color,var(--react-international-phone-disabled-background-color,whitesmoke));cursor:auto}.inputPhone .react-international-phone-country-selector-button--disabled:hover{background-color:var(--react-international-phone-disabled-country-selector-background-color,var(--react-international-phone-disabled-background-color,whitesmoke))}.inputPhone .react-international-phone-country-selector-button__button-content{justify-content:center;align-items:center;display:flex}.inputPhone .react-international-phone-country-selector-button__flag-emoji{margin:0 4px}.inputPhone .react-international-phone-country-selector-button__flag-emoji--disabled{opacity:.75}.inputPhone .react-international-phone-country-selector-button__dropdown-arrow{border-top:var(--react-international-phone-country-selector-arrow-size,4px) solid var(--react-international-phone-country-selector-arrow-color,#777);border-right:var(--react-international-phone-country-selector-arrow-size,4px) solid transparent;border-left:var(--react-international-phone-country-selector-arrow-size,4px) solid transparent;margin-right:4px;transition:all .1s ease-out}.inputPhone .react-international-phone-country-selector-button__dropdown-arrow--active{transform:rotateX(180deg)}.inputPhone .react-international-phone-country-selector-button__dropdown-arrow--disabled{border-top-color:var(--react-international-phone-disabled-country-selector-arrow-color,#999)}.inputPhone .react-international-phone-country-selector-dropdown{z-index:1000;top:var(--react-international-phone-dropdown-top,44px);left:var(--react-international-phone-dropdown-left,0);background-color:var(--react-international-phone-dropdown-item-background-color,var(--react-international-phone-background-color,white));width:300px;max-height:200px;box-shadow:var(--react-international-phone-dropdown-shadow,2px 2px 16px #00000040);color:var(--react-international-phone-dropdown-item-text-color,var(--react-international-phone-text-color,#222));flex-direction:column;margin:0;padding:4px 0;list-style:none;display:flex;position:absolute;overflow-y:scroll}.inputPhone .react-international-phone-country-selector-dropdown__preferred-list-divider{height:1px;margin:var(--react-international-phone-dropdown-preferred-list-divider-margin,0);background:var(--react-international-phone-dropdown-preferred-list-divider-color,var(--react-international-phone-border-color,gainsboro));border:none}.inputPhone .react-international-phone-country-selector-dropdown__list-item{min-height:var(--react-international-phone-dropdown-item-height,28px);box-sizing:border-box;align-items:center;padding:2px 8px;display:flex}.inputPhone .react-international-phone-country-selector-dropdown__list-item:hover{background-color:var(--react-international-phone-selected-dropdown-item-background-color,var(--react-international-phone-selected-dropdown-item-background-color,whitesmoke));cursor:pointer}.inputPhone .react-international-phone-country-selector-dropdown__list-item--selected,.inputPhone .react-international-phone-country-selector-dropdown__list-item--focused{background-color:var(--react-international-phone-selected-dropdown-item-background-color,whitesmoke);color:var(--react-international-phone-selected-dropdown-item-text-color,var(--react-international-phone-text-color,#222))}.inputPhone .react-international-phone-country-selector-dropdown__list-item--selected .react-international-phone-country-selector-dropdown__list-item-dial-code,.inputPhone .react-international-phone-country-selector-dropdown__list-item--focused .react-international-phone-country-selector-dropdown__list-item-dial-code{color:var(--react-international-phone-selected-dropdown-item-dial-code-color,var(--react-international-phone-dropdown-item-dial-code-color,gray))}.inputPhone .react-international-phone-country-selector-dropdown__list-item--focused{background-color:var(--react-international-phone-selected-dropdown-item-background-color,var(--react-international-phone-selected-dropdown-item-background-color,whitesmoke))}.inputPhone .react-international-phone-country-selector-dropdown__list-item-flag-emoji{margin-right:8px}.inputPhone .react-international-phone-country-selector-dropdown__list-item-country-name{font-size:var(--react-international-phone-dropdown-item-font-size,14px);text-overflow:ellipsis;white-space:nowrap;margin-right:8px;overflow:hidden}.inputPhone .react-international-phone-country-selector-dropdown__list-item-dial-code{color:var(--react-international-phone-dropdown-item-dial-code-color,gray);font-size:var(--react-international-phone-dropdown-item-font-size,14px)}.inputPhone .react-international-phone-dial-code-preview{border:1px solid var(--react-international-phone-dial-code-preview-border-color,var(--react-international-phone-border-color,gainsboro));background-color:var(--react-international-phone-dial-code-preview-background-color,var(--react-international-phone-background-color,white));color:var(--react-international-phone-dial-code-preview-text-color,var(--react-international-phone-text-color,#222));font-size:var(--react-international-phone-dial-code-preview-font-size,var(--react-international-phone-font-size,13px));justify-content:center;align-items:center;margin-right:-1px;padding:0 8px;display:flex}.inputPhone .react-international-phone-dial-code-preview--disabled{background-color:var(--react-international-phone-dial-code-preview-disabled-background-color,var(--react-international-phone-disabled-background-color,whitesmoke));color:var(--react-international-phone-dial-code-preview-disabled-text-color,var(--react-international-phone-disabled-text-color,#666))}.inputPhone .react-international-phone-input-container{display:flex}.inputPhone .react-international-phone-input-container .react-international-phone-country-selector-button{border-radius:var(--react-international-phone-border-radius,4px);border-top-right-radius:0;border-bottom-right-radius:0;margin-right:-1px}.inputPhone .react-international-phone-input-container .react-international-phone-input{height:var(--react-international-phone-height,36px);box-sizing:border-box;border:1px solid var(--react-international-phone-border-color,gainsboro);border-radius:var(--react-international-phone-border-radius,4px);background-color:var(--react-international-phone-background-color,white);color:var(--react-international-phone-text-color,#222);font-family:inherit;font-size:var(--react-international-phone-font-size,13px);border-top-left-radius:0;border-bottom-left-radius:0;margin:0;padding:0 8px;overflow:visible}.inputPhone .react-international-phone-input-container .react-international-phone-input:focus{outline:none}.inputPhone .react-international-phone-input-container .react-international-phone-input--disabled{background-color:var(--react-international-phone-disabled-background-color,whitesmoke);color:var(--react-international-phone-disabled-text-color,#666)}}
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ import { LabeledInput } from '../Input/InputWrapper';
3
+ import { PhoneInputProps } from 'react-international-phone';
4
+ export type InputProps = PhoneInputProps & LabeledInput & {
5
+ id?: string;
6
+ };
7
+ export declare const InputPhone: React.FC<InputProps>;