@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,42 @@
1
+ # Notice — Agent Usage Notes
2
+
3
+ Import:
4
+
5
+ ```tsx
6
+ import { Notice } from "@stamcat/craftsman/Notice";
7
+ ```
8
+
9
+ Props:
10
+
11
+ - Inherits all native `<div>` props.
12
+ - `type?: "help" | "info" | "success" | "error" | "none"` (default: `"info"`; `"none"` hides the leading status icon container)
13
+ - `icon?: React.ReactNode` (overrides the default status icon for the given `type`)
14
+ - `title?: string | React.ReactNode`
15
+ - `message?: string | React.ReactNode`
16
+ - `children?: React.ReactNode` (rendered alongside `title`/`message`)
17
+ - `buttons?: React.ReactNode` (rendered in a footer action row)
18
+ - `dismissible?: boolean` (shows a close ("x") button)
19
+ - `visible?: boolean` (default: `true`; renders nothing when `false`)
20
+ - `onDismiss?: (id?: string) => void`
21
+ - `id?: string` (passed back to `onDismiss`)
22
+
23
+ Behavior notes:
24
+
25
+ - Notice is an inline, persistent alert banner — not a popup toast. For transient popup notifications use the existing `react-toastify` integration (see the "Molecules/Toast" story), not this component.
26
+ - Notice is not self-dismissing — the dismiss button only calls `onDismiss`; the parent owns visibility and must flip `visible` to `false` (or unmount) in response.
27
+ - `title` is wrapped in `<Text as="h5">` and `message` in `<Text as="span">` when passed as a string; `React.ReactNode` values are rendered as-is.
28
+ - The leading icon inherits its color via CSS (`currentColor`) from the `.notice.<type>` class — don't pass an explicit `fill`/`color` prop to override it, use `icon` to swap the element instead.
29
+
30
+ Example:
31
+
32
+ ```tsx
33
+ <Notice
34
+ type="error"
35
+ title="Something went wrong"
36
+ message="Please check the highlighted fields and try again."
37
+ dismissible
38
+ visible={visible}
39
+ onDismiss={() => setVisible(false)}
40
+ buttons={<Button variant="text" onClick={retry}>Retry</Button>}
41
+ />
42
+ ```
@@ -0,0 +1 @@
1
+ @layer craftsman-component{.notice{gap:calc(var(--w-gutter) * .5);padding:var(--w-gutter);border:1px solid var(--gray400);background-color:var(--white);border-left-width:3px;border-radius:4px;flex-direction:column;transition:opacity .5s ease-in-out;display:flex}.notice.info{border-color:var(--blue500);background-color:var(--blue50);color:var(--blue600)}.notice.success{border-color:var(--green500);background-color:var(--green50);border-color:var(--green500)}.notice.error{border-color:var(--red500);background-color:var(--red50);color:var(--red600)}.notice.help{border-color:var(--gray500);background-color:var(--gray50)}.notice button.text{color:inherit}.notice-contents{align-items:flex-start;gap:calc(var(--w-gutter) * .5);flex-flow:row;width:100%;display:flex}.notice-icon{flex:none;font-size:24px;display:flex}.notice-text{margin-top:calc(var(--w-gutter) * .25);flex-grow:1}.notice-text span{display:block}.notice-dismiss{flex:none;padding:0}.notice-buttons{justify-content:flex-end;gap:calc(var(--w-gutter) * .5);width:100%;display:flex}}
@@ -0,0 +1,13 @@
1
+ import { NoticeType } from '../../utilities/types';
2
+ export type NoticeProps = React.ComponentPropsWithoutRef<"div"> & {
3
+ type?: NoticeType;
4
+ icon?: React.ReactNode;
5
+ title?: string | React.ReactNode;
6
+ message?: string | React.ReactNode;
7
+ buttons?: React.ReactNode;
8
+ visible?: boolean;
9
+ dismissible?: boolean;
10
+ onDismiss?: (id?: string) => void;
11
+ id?: string;
12
+ };
13
+ export declare const Notice: React.FC<NoticeProps>;
@@ -0,0 +1,76 @@
1
+ @use "../../styles/utilities/_functions" as u;
2
+
3
+ @layer craftsman-component {
4
+ .notice {
5
+ transition: opacity 500ms ease-in-out;
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: #{u.width("gutter", 0.5)};
9
+ padding: #{u.width("gutter")};
10
+ border: 1px solid var(--gray400);
11
+ border-left-width: 3px;
12
+ background-color: var(--white);
13
+ border-radius: 4px;
14
+
15
+ &.info {
16
+ border-color: var(--blue500);
17
+ background-color: var(--blue50);
18
+ color: var(--blue600);
19
+ }
20
+
21
+ &.success {
22
+ border-color: var(--green500);
23
+ background-color: var(--green50);
24
+ border-color: var(--green500);
25
+ }
26
+
27
+ &.error {
28
+ border-color: var(--red500);
29
+ background-color: var(--red50);
30
+ color: var(--red600);
31
+ }
32
+
33
+ &.help {
34
+ border-color: var(--gray500);
35
+ background-color: var(--gray50);
36
+ }
37
+ button.text {
38
+ color: inherit;
39
+ }
40
+ }
41
+
42
+ .notice-contents {
43
+ display: flex;
44
+ flex-flow: row nowrap;
45
+ align-items: flex-start;
46
+ gap: #{u.width("gutter", 0.5)};
47
+ width: 100%;
48
+ }
49
+
50
+ .notice-icon {
51
+ display: flex;
52
+ flex: 0 0 auto;
53
+ font-size: 24px;
54
+ }
55
+
56
+ .notice-text {
57
+ flex-grow: 1;
58
+ margin-top: #{u.width("gutter", 0.25)};
59
+ span {
60
+ display: block;
61
+ }
62
+ }
63
+
64
+ .notice-dismiss {
65
+ flex: 0 0 auto;
66
+ padding: 0;
67
+ }
68
+
69
+ .notice-buttons {
70
+ width: 100%;
71
+ display: flex;
72
+ justify-content: flex-end;
73
+ gap: #{u.width("gutter", 0.5)};
74
+
75
+ }
76
+ }
@@ -0,0 +1,56 @@
1
+ "use client";
2
+ import { Button as e } from "../Button/Button.esm.js";
3
+ import { Text as t } from "../Text/Text2.esm.js";
4
+ import './Notice.css';/* empty css */
5
+ import n from "clsx";
6
+ import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
7
+ import { IoAlertCircleOutline as o, IoCheckmarkCircleOutline as s, IoCloseOutline as c, IoHelpCircleOutline as l, IoInformationCircleOutline as u } from "react-icons/io5";
8
+ //#region src/components/Notice/Notice.tsx
9
+ var d = {
10
+ info: /* @__PURE__ */ i(u, {}),
11
+ success: /* @__PURE__ */ i(s, {}),
12
+ error: /* @__PURE__ */ i(o, {}),
13
+ help: /* @__PURE__ */ i(l, {}),
14
+ none: /* @__PURE__ */ i(r, {})
15
+ }, f = (e, n) => typeof e == "string" ? /* @__PURE__ */ i(t, {
16
+ as: n,
17
+ children: e
18
+ }) : e, p = ({ type: t = "info", title: r, message: o, buttons: s, id: l, className: u, style: p, icon: m, children: h, dismissible: g, onDismiss: _, ...v }) => {
19
+ let y = () => {
20
+ _?.(l);
21
+ };
22
+ return /* @__PURE__ */ a("div", {
23
+ id: l,
24
+ className: n("notice", t, u),
25
+ style: p,
26
+ ...v,
27
+ children: [/* @__PURE__ */ a("div", {
28
+ className: "notice-contents",
29
+ children: [
30
+ t !== "none" && /* @__PURE__ */ i("div", {
31
+ className: "notice-icon",
32
+ children: m || d[t]
33
+ }),
34
+ /* @__PURE__ */ a("div", {
35
+ className: "notice-text",
36
+ children: [
37
+ r && f(r, "h5"),
38
+ o && f(o, "span"),
39
+ h
40
+ ]
41
+ }),
42
+ g && /* @__PURE__ */ i(e, {
43
+ variant: "text",
44
+ className: "notice-dismiss",
45
+ onClick: y,
46
+ children: /* @__PURE__ */ i(c, { size: 16 })
47
+ })
48
+ ]
49
+ }), s && /* @__PURE__ */ i("footer", {
50
+ className: "notice-buttons",
51
+ children: s
52
+ })]
53
+ });
54
+ };
55
+ //#endregion
56
+ export { p as Notice };
@@ -0,0 +1,38 @@
1
+ # Pagination — Agent Usage Notes
2
+
3
+ Import:
4
+
5
+ ```tsx
6
+ import { Pagination } from "@stamcat/craftsman/Pagination";
7
+ ```
8
+
9
+ Props:
10
+
11
+ - `total: number`
12
+ - `current: number`
13
+ - `showPages?: number` (default: `5`)
14
+ - `onChange: (e: React.MouseEvent<HTMLButtonElement>) => void`
15
+ - `className?: string`
16
+ - `style?: React.CSSProperties`
17
+
18
+ Behavior notes:
19
+
20
+ - Pagination is zero-based internally. Pass `current={0}` for the first page.
21
+ - `total` is the total number of pages, not the last page index.
22
+ - The component renders first/last buttons and jump-by-window buttons when needed.
23
+ - `showPages` controls both the visible window size and the jump step for `‹‹` / `››`.
24
+ - `onChange` receives the clicked button event. Read the next page from `event.currentTarget.value`.
25
+ - The active page button is disabled and marked with `aria-current="page"`.
26
+
27
+ Example:
28
+
29
+ ```tsx
30
+ const [current, setCurrent] = useState(0);
31
+
32
+ <Pagination
33
+ total={50}
34
+ current={current}
35
+ showPages={5}
36
+ onChange={(event) => setCurrent(parseInt(event.currentTarget.value, 10) || 0)}
37
+ />
38
+ ```
@@ -0,0 +1 @@
1
+ @layer craftsman-component{.pagination{align-items:center;gap:calc(var(--w-gutter) * .25);display:inline-flex}.pagination .active{color:var(--gray700);border:1px solid;border-radius:50%;justify-content:center;align-items:center;width:20px;height:20px;display:inline-flex}}
@@ -0,0 +1,10 @@
1
+ import { default as React } from 'react';
2
+ export type PaginationProps = {
3
+ total: number;
4
+ current: number;
5
+ showPages?: number;
6
+ onChange: (e: React.MouseEvent<HTMLButtonElement>) => void;
7
+ className?: string;
8
+ style?: React.CSSProperties;
9
+ };
10
+ export declare const Pagination: React.FC<PaginationProps>;
@@ -0,0 +1,22 @@
1
+
2
+ @use "../../styles/utilities/_functions" as u;
3
+
4
+ @layer craftsman-component {
5
+ .pagination {
6
+ display: inline-flex;
7
+ align-items: center;
8
+ gap: #{u.width("gutter", 0.25)};
9
+
10
+ .active {
11
+ color: #{u.color("gray700")};
12
+ border: 1px solid;
13
+ border-radius: 50%;
14
+ width: 20px;
15
+ height: 20px;
16
+ display: inline-flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,64 @@
1
+ "use client";
2
+ import './Pagination.css';/* empty css */
3
+ import e from "clsx";
4
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
5
+ import "react";
6
+ //#region src/components/Pagination/Pagination.tsx
7
+ var r = ({ total: r, current: i, onChange: a, className: o, style: s, showPages: c = 5 }) => {
8
+ function l(e, t) {
9
+ let n = Math.floor(c / 2), r = Math.max(0, e - n), i = Math.min(t - 1, r + c - 1);
10
+ r = Math.max(0, i - c + 1);
11
+ let a = [];
12
+ for (let e = r; e <= i; e++) a.push(e);
13
+ return a;
14
+ }
15
+ let u = l(i, r), d = Math.floor(i / c), f = d > 0, p = (d + 1) * c < r, m = (d - 1) * c, h = (d + 1) * c;
16
+ return /* @__PURE__ */ n("nav", {
17
+ className: e("pagination", o),
18
+ style: s,
19
+ "aria-label": "Pagination",
20
+ children: [
21
+ /* @__PURE__ */ t("button", {
22
+ className: "text",
23
+ value: 0,
24
+ onClick: a,
25
+ disabled: i === 0,
26
+ "aria-label": "First page",
27
+ children: "«"
28
+ }),
29
+ f && /* @__PURE__ */ t("button", {
30
+ className: "text",
31
+ value: m,
32
+ onClick: a,
33
+ "aria-label": `Back ${c} pages`,
34
+ children: "‹‹"
35
+ }),
36
+ u.map((n) => /* @__PURE__ */ t("button", {
37
+ value: n,
38
+ onClick: a,
39
+ disabled: n === i,
40
+ "aria-label": `Page ${n + 1}`,
41
+ "aria-current": n === i ? "page" : void 0,
42
+ className: e("text", n === i ? "active" : void 0),
43
+ children: n + 1
44
+ }, n)),
45
+ p && /* @__PURE__ */ t("button", {
46
+ className: "text",
47
+ value: h,
48
+ onClick: a,
49
+ "aria-label": `Forward ${c} pages`,
50
+ children: "››"
51
+ }),
52
+ /* @__PURE__ */ t("button", {
53
+ className: "text",
54
+ value: r - 1,
55
+ onClick: a,
56
+ disabled: i === r - 1,
57
+ "aria-label": "Last page",
58
+ children: "»"
59
+ })
60
+ ]
61
+ });
62
+ };
63
+ //#endregion
64
+ export { r as Pagination };
@@ -0,0 +1,44 @@
1
+ # RadioButton — Agent Usage Notes
2
+
3
+ Import:
4
+
5
+ ```tsx
6
+ import { RadioButton } from "@stamcat/craftsman/RadioButton";
7
+ ```
8
+
9
+ Props:
10
+
11
+ - Extends `Input` props.
12
+ - `type?: "radio"` (default: `"radio"`)
13
+ - `labelPosition?: "left" | "right"` (default: `"right"`)
14
+ - `size?: number` (default visual scale is `1`, clamped to `[0.1, 10]`)
15
+
16
+ Behavior notes:
17
+
18
+ - `RadioButton` is a thin wrapper around `Input` with radio-specific guardrails.
19
+ - Group behavior is native HTML radio behavior: use a shared `name` across options.
20
+ - Controlled and uncontrolled patterns are both supported (`checked` + `onChange`, or `defaultChecked`).
21
+ - When `size` is provided, RadioButton sets a single `--radio-size` CSS variable inline; the radio circle and dot scale via SCSS `calc()` from that variable (same pattern as `Button`'s `--btn-size` and `Toggle`'s `--toggle-width`).
22
+
23
+ Example:
24
+
25
+ ```tsx
26
+ <>
27
+ <RadioButton
28
+ id="captain-kirk"
29
+ name="favorite-captain"
30
+ value="Kirk"
31
+ label="James T. Kirk"
32
+ checked={selected === "Kirk"}
33
+ onChange={(event) => setSelected(event.currentTarget.value)}
34
+ />
35
+ <RadioButton
36
+ id="captain-picard"
37
+ name="favorite-captain"
38
+ value="Picard"
39
+ label="Jean-Luc Picard"
40
+ checked={selected === "Picard"}
41
+ onChange={(event) => setSelected(event.currentTarget.value)}
42
+ />
43
+ </>
44
+ ```
@@ -0,0 +1,9 @@
1
+ import { RadioLabelPosition } from '../../styles';
2
+ import { InputProps } from '../Input/Input';
3
+ type RadioButtonProps = InputProps & {
4
+ type?: "radio";
5
+ labelPosition?: RadioLabelPosition;
6
+ size?: number;
7
+ };
8
+ export declare const RadioButton: React.FC<RadioButtonProps>;
9
+ export {};
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { Input as e } from "../Input/Input2.esm.js";
3
+ import { jsx as t } from "react/jsx-runtime";
4
+ //#region src/components/RadioButton/RadioButton.tsx
5
+ var n = ({ type: n = "radio", labelPosition: r = "right", size: i, style: a, ...o }) => {
6
+ let s = typeof i == "number" ? Math.min(10, Math.max(.1, i)) : void 0;
7
+ return /* @__PURE__ */ t(e, {
8
+ type: n,
9
+ labelPosition: r,
10
+ style: {
11
+ ...s ? { "--radio-size": s } : void 0,
12
+ ...a
13
+ },
14
+ ...o
15
+ });
16
+ };
17
+ //#endregion
18
+ export { n as RadioButton };
@@ -0,0 +1,36 @@
1
+ # Select — Agent Usage Notes
2
+
3
+ Import:
4
+
5
+ ```tsx
6
+ import { Select } from "@stamcat/craftsman/Select";
7
+ ```
8
+
9
+ Props:
10
+
11
+ - Inherits all native `<select>` props.
12
+ - `label?: string | ReactNode`
13
+ - `labelPosition?: "top" | "left" | "bottom" | "right" | "inside" | "hidden"` (default: `"top"`)
14
+ - `error?: string | boolean | ReactNode`
15
+ - `required?: boolean`
16
+ - `options?: Array<{ label: string; value: string }>`
17
+
18
+ Behavior notes:
19
+
20
+ - Built on the native `<select>` element via `InputWrapper`.
21
+ - Pass options as a plain array — do not render `<option>` children manually.
22
+ - `id` is auto-generated via `useId` if not provided.
23
+
24
+ Example:
25
+
26
+ ```tsx
27
+ <Select
28
+ label="Favorite Fruit"
29
+ required
30
+ options={[
31
+ { value: "", label: "Select one..." },
32
+ { value: "apple", label: "Apple" },
33
+ { value: "banana", label: "Banana" },
34
+ ]}
35
+ />
36
+ ```
@@ -0,0 +1,14 @@
1
+ import { LabeledInput } from '../Input/InputWrapper';
2
+ export type SelectOption = {
3
+ value: string;
4
+ selected?: boolean;
5
+ disabled?: boolean;
6
+ label: string;
7
+ };
8
+ export type SelectProps = React.ComponentProps<"select"> & LabeledInput & {
9
+ options?: {
10
+ label: string;
11
+ value: string;
12
+ }[];
13
+ };
14
+ export declare const Select: React.FC<SelectProps>;
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { InputWrapper as e } from "../Input/InputWrapper.esm.js";
3
+ import { jsx as t } from "react/jsx-runtime";
4
+ import { useId as n } from "react";
5
+ //#region src/components/Select/Select.tsx
6
+ var r = ({ label: r, id: i, labelPosition: a = "top", required: o = !1, error: s, options: c = [], className: l, style: u, ...d }) => {
7
+ let f = n(), p = i || f;
8
+ return /* @__PURE__ */ t(e, {
9
+ label: r,
10
+ labelPosition: a,
11
+ error: s,
12
+ required: o,
13
+ className: l,
14
+ style: u,
15
+ children: /* @__PURE__ */ t("select", {
16
+ id: p,
17
+ ...d,
18
+ children: c.map((e, n) => /* @__PURE__ */ t("option", {
19
+ value: e.value,
20
+ children: e.label
21
+ }, `${p}-opt-${n}`))
22
+ })
23
+ });
24
+ };
25
+ //#endregion
26
+ export { r as Select };
@@ -0,0 +1,45 @@
1
+ # SortableList — Agent Usage Notes
2
+
3
+ Import:
4
+
5
+ ```tsx
6
+ import { SortableList } from "@stamcat/craftsman/SortableList";
7
+ ```
8
+
9
+ Props:
10
+
11
+ - `items: T[]`
12
+ - `getKey: (item: T, index: number) => string`
13
+ - `renderItem: (args: SortableListRenderArgs<T>) => React.ReactNode`
14
+ - `onReorder: (items: T[]) => void`
15
+ - `disabled?: boolean`
16
+ - `className?: string`
17
+ - `style?: React.CSSProperties`
18
+
19
+ Behavior notes:
20
+
21
+ - Built on `@atlaskit/pragmatic-drag-and-drop`. The list only owns drag/drop wiring and reordering — all item markup comes from `renderItem`.
22
+ - `renderItem` receives `{ item, index, isDragging, dropEdge, dragHandleRef }`.
23
+ - By default the whole rendered item is the drag source.
24
+ - To restrict dragging to a handle, attach `dragHandleRef` to the handle element's `ref`.
25
+ - `dropEdge` is `"top" | "bottom" | null` while another item is dragged over this one — use it to render a drop indicator, or rely on the built-in `.drop-top` / `.drop-bottom` styles.
26
+ - `onReorder` is called with the full reordered array on drop; the component does not mutate `items` itself — update your own state in the callback.
27
+ - Set `disabled` to suspend all drag/drop wiring (for example while a related request is in flight).
28
+
29
+ Example:
30
+
31
+ ```tsx
32
+ const [items, setItems] = useState(["Alpha", "Beta", "Gamma"]);
33
+
34
+ <SortableList
35
+ items={items}
36
+ getKey={(item) => item}
37
+ onReorder={setItems}
38
+ renderItem={({ item, isDragging, dropEdge, dragHandleRef }) => (
39
+ <div className={isDragging ? "dragging" : undefined} data-drop-edge={dropEdge ?? undefined}>
40
+ <span ref={dragHandleRef}>⠿</span>
41
+ {item}
42
+ </div>
43
+ )}
44
+ />
45
+ ```
@@ -0,0 +1,10 @@
1
+ import { SortableListRenderArgs } from './SortableList';
2
+ export type DropEdge = "top" | "bottom";
3
+ export declare function SortableListItem<T>({ item, index, getKey, renderItem, disabled, listId, }: {
4
+ item: T;
5
+ index: number;
6
+ getKey: (item: T, index: number) => string;
7
+ renderItem: (args: SortableListRenderArgs<T>) => React.ReactNode;
8
+ disabled?: boolean;
9
+ listId: string;
10
+ }): import("react").JSX.Element;
@@ -0,0 +1,67 @@
1
+ "use client";
2
+ import { combine as e } from "../../../node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/public-utils/combine.esm.js";
3
+ import { draggable as t, dropTargetForElements as n } from "../../../node_modules/@atlaskit/pragmatic-drag-and-drop/dist/esm/adapter/element-adapter.esm.js";
4
+ import { isItemData as r } from "./utilities.esm.js";
5
+ import i from "clsx";
6
+ import { jsx as a } from "react/jsx-runtime";
7
+ import { useEffect as o, useLayoutEffect as s, useRef as c, useState as l } from "react";
8
+ //#region src/components/SortableList/ListItem.tsx
9
+ function u({ item: u, index: d, getKey: f, renderItem: p, disabled: m, listId: h }) {
10
+ let [g, _] = l(null), [v, y] = l(null), [b, x] = l(!1), [S, C] = l(null), w = c(null), T = c(null), E = f(u, d);
11
+ return s(() => {
12
+ w.current = g;
13
+ let e = w.current;
14
+ if (!e) return;
15
+ let t = T.current, n = e.getBoundingClientRect();
16
+ T.current = n;
17
+ let r = t ? t.top - n.top : 0;
18
+ !r || window.matchMedia("(prefers-reduced-motion: reduce)").matches || (e.style.transition = "none", e.style.transform = `translateY(${r}px)`, requestAnimationFrame(() => {
19
+ e.style.transition = "", e.style.transform = "";
20
+ }));
21
+ }, [g, d]), o(() => {
22
+ if (!g || m) return;
23
+ let i = {
24
+ key: E,
25
+ index: d,
26
+ listId: h,
27
+ item: u
28
+ };
29
+ return e(t({
30
+ element: g,
31
+ dragHandle: v ?? void 0,
32
+ getInitialData: () => i,
33
+ onDragStart: () => x(!0),
34
+ onDrop: () => x(!1)
35
+ }), n({
36
+ element: g,
37
+ getData: () => i,
38
+ canDrop: ({ source: e }) => r(e.data) && e.data.key !== E,
39
+ onDrag: ({ location: e }) => {
40
+ let t = g.getBoundingClientRect(), n = e.current.input.clientY > t.top + t.height / 2;
41
+ C(n ? "bottom" : "top");
42
+ },
43
+ onDragLeave: () => C(null),
44
+ onDrop: () => C(null)
45
+ }));
46
+ }, [
47
+ g,
48
+ v,
49
+ E,
50
+ d,
51
+ m,
52
+ h,
53
+ u
54
+ ]), /* @__PURE__ */ a("li", {
55
+ ref: _,
56
+ className: i("sortable-list-item", b && "dragging", S && `drop-${S}`),
57
+ children: p({
58
+ item: u,
59
+ index: d,
60
+ isDragging: b,
61
+ dropEdge: S,
62
+ dragHandleRef: y
63
+ })
64
+ }, E);
65
+ }
66
+ //#endregion
67
+ export { u as SortableListItem };
@@ -0,0 +1 @@
1
+ @layer craftsman-component{.sortable-list{gap:calc(var(--w-gutter) * .25);flex-direction:column;margin:0;padding:0;list-style:none;display:flex}.sortable-list-item{cursor:grab;transition:transform .2s,opacity .15s;position:relative}.sortable-list-item.dragging{opacity:.4}.sortable-list-item.drop-top:before,.sortable-list-item.drop-bottom:after{content:"";background-color:var(--blue500);border-radius:1px;height:2px;position:absolute;left:0;right:0}.sortable-list-item.drop-top:before{top:-1px}.sortable-list-item.drop-bottom:after{bottom:-1px}}
@@ -0,0 +1,23 @@
1
+ import { default as React } from 'react';
2
+ import { DropEdge } from './ListItem';
3
+ export type SortableListItemState = {
4
+ isDragging: boolean;
5
+ dropEdge: DropEdge | null;
6
+ };
7
+ export type SortableListRenderArgs<T> = SortableListItemState & {
8
+ dragHandleRef: (element: HTMLElement | null) => void;
9
+ item: T;
10
+ index: number;
11
+ };
12
+ export type SortableListProps<T> = {
13
+ items: T[];
14
+ getKey: (item: T, index: number) => string;
15
+ renderItem: (args: SortableListRenderArgs<T>) => React.ReactNode;
16
+ onReorder: (items: T[]) => void;
17
+ disabled?: boolean;
18
+ className?: string;
19
+ style?: React.CSSProperties;
20
+ listId?: string;
21
+ onReceive?: (item: T, atIndex: number) => void;
22
+ };
23
+ export declare const SortableList: <T>({ items, getKey, renderItem, onReorder, disabled, className, style, listId, onReceive }: SortableListProps<T>) => React.JSX.Element;