@stamcat/craftsman 0.0.31-beta.3 → 0.0.31

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/AGENTS.md +5 -4
  2. package/Components.esm.js +78 -76
  3. package/package.json +7 -1
  4. package/skills/craftsman-component-usage/SKILL.md +156 -0
  5. package/skills/craftsman-device-detection/SKILL.md +79 -0
  6. package/skills/craftsman-style-utilities/SKILL.md +228 -0
  7. package/skills/craftsman-utility-functions/SKILL.md +71 -0
  8. package/src/components/Accordion/AGENTS.md +45 -0
  9. package/src/components/Accordion/Accordion.css +1 -0
  10. package/src/components/Accordion/Accordion.d.ts +14 -0
  11. package/src/components/Accordion/Accordion.scss +64 -0
  12. package/src/components/Accordion/Accordion2.esm.js +70 -0
  13. package/src/components/Carousel/Carousel2.esm.js +21 -21
  14. package/src/components/DatePicker/DatePicker.css +1 -1
  15. package/src/components/DatePicker/DatePicker2.esm.js +11 -11
  16. package/src/components/DateRangePicker/DateRangePicker.css +1 -1
  17. package/src/components/DateRangePicker/DateRangePicker2.esm.js +10 -10
  18. package/src/components/DateTimePicker/DateTimePicker.css +1 -1
  19. package/src/components/DateTimePicker/DateTimePicker2.esm.js +14 -14
  20. package/src/components/Input/Input.css +1 -1
  21. package/src/components/Input/Input.scss +7 -0
  22. package/src/components/Input/Input2.esm.js +10 -10
  23. package/src/components/InputNumber/InputNumber2.esm.js +10 -10
  24. package/src/components/InputPassword/InputPassword.esm.js +9 -9
  25. package/src/components/InputPhone/InputPhone2.esm.js +7 -7
  26. package/src/components/Modal/Modal2.esm.js +15 -15
  27. package/src/components/Pagination/Pagination2.esm.js +1 -1
  28. package/src/components/Select/Select.esm.js +18 -17
  29. package/src/components/SortableList/ListItem.esm.js +8 -8
  30. package/src/components/SortableList/SortableList2.esm.js +8 -8
  31. package/src/components/Text/AGENTS.md +4 -2
  32. package/src/components/Textarea/Textarea.esm.js +5 -5
  33. package/src/components/TimePicker/TimePicker.css +1 -1
  34. package/src/components/TimePicker/TimePicker2.esm.js +15 -15
  35. package/src/components/TimePicker/TimePickerDisplay.esm.js +1 -1
  36. package/src/components/TimePicker/TimePickerWheel.esm.js +15 -15
  37. package/src/components/Tooltip/Tooltip2.esm.js +12 -12
  38. package/src/components/index.d.ts +1 -0
  39. package/src/styles/global/components/_input.scss +8 -9
  40. package/src/styles/global/components/_select.scss +11 -16
  41. package/src/utilities/types.d.ts +14 -14
package/AGENTS.md CHANGED
@@ -4,15 +4,16 @@ This document explains how code-generation agents should use this library safely
4
4
 
5
5
  Full guidance has been split out for progressive loading:
6
6
 
7
- - **Global guidelines** (exports, hard rules, code block rendering, style utilities, theme authoring, `isEmpty`, code gen patterns, fallback strategy): see the [craftsman-component-usage skill](.github/skills/craftsman-component-usage/SKILL.md).
7
+ - **Global guidelines** (exports, hard rules, code block rendering, style utilities, theme authoring, `isEmpty`, code gen patterns, fallback strategy): see the [craftsman-component-usage skill](skills/craftsman-component-usage/SKILL.md).
8
8
  - **Component-specific guidelines** (props, behavior notes, examples): each component has its own `AGENTS.md` co-located with its source, for example [src/components/Button/AGENTS.md](src/components/Button/AGENTS.md).
9
- - **Device/browser detection** (prefer `react-device-detect` over custom user-agent/viewport checks): see the [craftsman-device-detection skill](.github/skills/craftsman-device-detection/SKILL.md).
9
+ - **Device/browser detection** (prefer `react-device-detect` over custom user-agent/viewport checks): see the [craftsman-device-detection skill](skills/craftsman-device-detection/SKILL.md).
10
10
 
11
11
  ## Quick Reference
12
12
 
13
13
  Use these imports:
14
14
 
15
15
  ```tsx
16
+ import { Accordion } from "@stamcat/craftsman/Accordion";
16
17
  import { Button } from "@stamcat/craftsman/Button";
17
18
  import { Carousel } from "@stamcat/craftsman/Carousel";
18
19
  import { Checkbox } from "@stamcat/craftsman/Checkbox";
@@ -41,9 +42,9 @@ Do not assume a root export like `@stamcat/craftsman` unless that export is expl
41
42
 
42
43
  ## Hard Rules for Agents
43
44
 
44
- 1. Never deep-import from package internals (for example `@stamcat/craftsman/src/...`).
45
+ 1. Never deep-import from package internals (for example `@stamcat/craftsman/src/...`). This applies to Sass too — `@use "@stamcat/craftsman/src/styles/utilities/functions"` will fail to resolve; use the published subpath `@stamcat/craftsman/styles/utilities/functions` instead.
45
46
  2. Only use documented component entry points.
46
- 3. Do not import storybook files or internal style utilities from consuming applications.
47
+ 3. Do not import storybook files from consuming applications. Style utilities are fine to import, but only via their published subpaths (`@stamcat/craftsman/styles/utilities/functions`, `/mixins`, `/placeholders`) — never via a `/src/...` path.
47
48
  4. Prefer standard React props first; use custom props only when required.
48
49
 
49
50
 
package/Components.esm.js CHANGED
@@ -1,81 +1,83 @@
1
1
  import { __exportAll as e } from "./_virtual/_rolldown/runtime.esm.js";
2
- import { Button as t } from "./src/components/Button/Button.esm.js";
3
- import { Input as n } from "./src/components/Input/Input2.esm.js";
4
- import { InputPassword as r } from "./src/components/InputPassword/InputPassword.esm.js";
5
- import { Loader as i } from "./src/components/Loader/Loader.esm.js";
6
- import { RadioButton as a } from "./src/components/RadioButton/RadioButton.esm.js";
7
- import { Checkbox as o } from "./src/components/Checkbox/Checkbox.esm.js";
8
- import { Textarea as s } from "./src/components/Textarea/Textarea.esm.js";
9
- import { Text as c } from "./src/components/Text/Text2.esm.js";
10
- import { Modal as l } from "./src/components/Modal/Modal2.esm.js";
11
- import { Select as u } from "./src/components/Select/Select.esm.js";
12
- import { DatePicker as d } from "./src/components/DatePicker/DatePicker2.esm.js";
13
- import { DateRangePicker as f } from "./src/components/DateRangePicker/DateRangePicker2.esm.js";
14
- import { InputPhone as p } from "./src/components/InputPhone/InputPhone2.esm.js";
15
- import { InputNumber as m } from "./src/components/InputNumber/InputNumber2.esm.js";
16
- import { Toggle as h } from "./src/components/Toggle/Toggle2.esm.js";
17
- import { Pagination as g } from "./src/components/Pagination/Pagination2.esm.js";
18
- import { Carousel as _ } from "./src/components/Carousel/Carousel2.esm.js";
19
- import { TimePicker as v } from "./src/components/TimePicker/TimePicker2.esm.js";
20
- import { DateTimePicker as y } from "./src/components/DateTimePicker/DateTimePicker2.esm.js";
21
- import { Tooltip as b } from "./src/components/Tooltip/Tooltip2.esm.js";
22
- import { Notice as x } from "./src/components/Notice/Notice2.esm.js";
23
- import { SortableList as S } from "./src/components/SortableList/SortableList2.esm.js";
24
- import { IconAmazonPay as C } from "./src/components/Icons/IconAmazonPay.esm.js";
25
- import { IconAmex as w } from "./src/components/Icons/IconAmex.esm.js";
26
- import { IconApplePay as T } from "./src/components/Icons/IconApplePay.esm.js";
27
- import { IconDiscover as E } from "./src/components/Icons/IconDiscover.esm.js";
28
- import { IconGooglePay as D } from "./src/components/Icons/IconGooglePay.esm.js";
29
- import { IconMaestro as O } from "./src/components/Icons/IconMaestro.esm.js";
30
- import { IconMastercard as k } from "./src/components/Icons/IconMastercard.esm.js";
31
- import { IconPayPal as A } from "./src/components/Icons/IconPayPal.esm.js";
32
- import { IconSepa as j } from "./src/components/Icons/IconSepa.esm.js";
33
- import { IconShopPay as M } from "./src/components/Icons/IconShopPay.esm.js";
34
- import { IconSquare as N } from "./src/components/Icons/IconSquare.esm.js";
35
- import { IconStripe as P } from "./src/components/Icons/IconStripe.esm.js";
36
- import { IconUnionPay as F } from "./src/components/Icons/IconUnionPay.esm.js";
37
- import { IconVenmo as I } from "./src/components/Icons/IconVenmo.esm.js";
38
- import { IconVisa as L } from "./src/components/Icons/IconVisa.esm.js";
2
+ import { Accordion as t } from "./src/components/Accordion/Accordion2.esm.js";
3
+ import { Button as n } from "./src/components/Button/Button.esm.js";
4
+ import { Input as r } from "./src/components/Input/Input2.esm.js";
5
+ import { InputPassword as i } from "./src/components/InputPassword/InputPassword.esm.js";
6
+ import { Loader as a } from "./src/components/Loader/Loader.esm.js";
7
+ import { RadioButton as o } from "./src/components/RadioButton/RadioButton.esm.js";
8
+ import { Checkbox as s } from "./src/components/Checkbox/Checkbox.esm.js";
9
+ import { Textarea as c } from "./src/components/Textarea/Textarea.esm.js";
10
+ import { Text as l } from "./src/components/Text/Text2.esm.js";
11
+ import { Modal as u } from "./src/components/Modal/Modal2.esm.js";
12
+ import { Select as d } from "./src/components/Select/Select.esm.js";
13
+ import { DatePicker as f } from "./src/components/DatePicker/DatePicker2.esm.js";
14
+ import { DateRangePicker as p } from "./src/components/DateRangePicker/DateRangePicker2.esm.js";
15
+ import { InputPhone as m } from "./src/components/InputPhone/InputPhone2.esm.js";
16
+ import { InputNumber as h } from "./src/components/InputNumber/InputNumber2.esm.js";
17
+ import { Toggle as g } from "./src/components/Toggle/Toggle2.esm.js";
18
+ import { Pagination as _ } from "./src/components/Pagination/Pagination2.esm.js";
19
+ import { Carousel as v } from "./src/components/Carousel/Carousel2.esm.js";
20
+ import { TimePicker as y } from "./src/components/TimePicker/TimePicker2.esm.js";
21
+ import { DateTimePicker as b } from "./src/components/DateTimePicker/DateTimePicker2.esm.js";
22
+ import { Tooltip as x } from "./src/components/Tooltip/Tooltip2.esm.js";
23
+ import { Notice as S } from "./src/components/Notice/Notice2.esm.js";
24
+ import { SortableList as C } from "./src/components/SortableList/SortableList2.esm.js";
25
+ import { IconAmazonPay as w } from "./src/components/Icons/IconAmazonPay.esm.js";
26
+ import { IconAmex as T } from "./src/components/Icons/IconAmex.esm.js";
27
+ import { IconApplePay as E } from "./src/components/Icons/IconApplePay.esm.js";
28
+ import { IconDiscover as D } from "./src/components/Icons/IconDiscover.esm.js";
29
+ import { IconGooglePay as O } from "./src/components/Icons/IconGooglePay.esm.js";
30
+ import { IconMaestro as k } from "./src/components/Icons/IconMaestro.esm.js";
31
+ import { IconMastercard as A } from "./src/components/Icons/IconMastercard.esm.js";
32
+ import { IconPayPal as j } from "./src/components/Icons/IconPayPal.esm.js";
33
+ import { IconSepa as M } from "./src/components/Icons/IconSepa.esm.js";
34
+ import { IconShopPay as N } from "./src/components/Icons/IconShopPay.esm.js";
35
+ import { IconSquare as P } from "./src/components/Icons/IconSquare.esm.js";
36
+ import { IconStripe as F } from "./src/components/Icons/IconStripe.esm.js";
37
+ import { IconUnionPay as I } from "./src/components/Icons/IconUnionPay.esm.js";
38
+ import { IconVenmo as L } from "./src/components/Icons/IconVenmo.esm.js";
39
+ import { IconVisa as R } from "./src/components/Icons/IconVisa.esm.js";
39
40
  import "./src/components/Icons/index.esm.js";
40
41
  //#region src/components/index.ts
41
- var R = /* @__PURE__ */ e({
42
- Button: () => t,
43
- Carousel: () => _,
44
- Checkbox: () => o,
45
- DatePicker: () => d,
46
- DateRangePicker: () => f,
47
- DateTimePicker: () => y,
48
- IconAmazonPay: () => C,
49
- IconAmex: () => w,
50
- IconApplePay: () => T,
51
- IconDiscover: () => E,
52
- IconGooglePay: () => D,
53
- IconMaestro: () => O,
54
- IconMastercard: () => k,
55
- IconPayPal: () => A,
56
- IconSepa: () => j,
57
- IconShopPay: () => M,
58
- IconSquare: () => N,
59
- IconStripe: () => P,
60
- IconUnionPay: () => F,
61
- IconVenmo: () => I,
62
- IconVisa: () => L,
63
- Input: () => n,
64
- InputNumber: () => m,
65
- InputPassword: () => r,
66
- InputPhone: () => p,
67
- Loader: () => i,
68
- Modal: () => l,
69
- Notice: () => x,
70
- Pagination: () => g,
71
- RadioButton: () => a,
72
- Select: () => u,
73
- SortableList: () => S,
74
- Text: () => c,
75
- Textarea: () => s,
76
- TimePicker: () => v,
77
- Toggle: () => h,
78
- Tooltip: () => b
42
+ var z = /* @__PURE__ */ e({
43
+ Accordion: () => t,
44
+ Button: () => n,
45
+ Carousel: () => v,
46
+ Checkbox: () => s,
47
+ DatePicker: () => f,
48
+ DateRangePicker: () => p,
49
+ DateTimePicker: () => b,
50
+ IconAmazonPay: () => w,
51
+ IconAmex: () => T,
52
+ IconApplePay: () => E,
53
+ IconDiscover: () => D,
54
+ IconGooglePay: () => O,
55
+ IconMaestro: () => k,
56
+ IconMastercard: () => A,
57
+ IconPayPal: () => j,
58
+ IconSepa: () => M,
59
+ IconShopPay: () => N,
60
+ IconSquare: () => P,
61
+ IconStripe: () => F,
62
+ IconUnionPay: () => I,
63
+ IconVenmo: () => L,
64
+ IconVisa: () => R,
65
+ Input: () => r,
66
+ InputNumber: () => h,
67
+ InputPassword: () => i,
68
+ InputPhone: () => m,
69
+ Loader: () => a,
70
+ Modal: () => u,
71
+ Notice: () => S,
72
+ Pagination: () => _,
73
+ RadioButton: () => o,
74
+ Select: () => d,
75
+ SortableList: () => C,
76
+ Text: () => l,
77
+ Textarea: () => c,
78
+ TimePicker: () => y,
79
+ Toggle: () => g,
80
+ Tooltip: () => x
79
81
  });
80
82
  //#endregion
81
- export { t as Button, _ as Carousel, o as Checkbox, d as DatePicker, f as DateRangePicker, y as DateTimePicker, C as IconAmazonPay, w as IconAmex, T as IconApplePay, E as IconDiscover, D as IconGooglePay, O as IconMaestro, k as IconMastercard, A as IconPayPal, j as IconSepa, M as IconShopPay, N as IconSquare, P as IconStripe, F as IconUnionPay, I as IconVenmo, L as IconVisa, n as Input, m as InputNumber, r as InputPassword, p as InputPhone, i as Loader, l as Modal, x as Notice, g as Pagination, a as RadioButton, u as Select, S as SortableList, c as Text, s as Textarea, v as TimePicker, h as Toggle, b as Tooltip, R as components_exports };
83
+ export { t as Accordion, n as Button, v as Carousel, s as Checkbox, f as DatePicker, p as DateRangePicker, b as DateTimePicker, w as IconAmazonPay, T as IconAmex, E as IconApplePay, D as IconDiscover, O as IconGooglePay, k as IconMaestro, A as IconMastercard, j as IconPayPal, M as IconSepa, N as IconShopPay, P as IconSquare, F as IconStripe, I as IconUnionPay, L as IconVenmo, R as IconVisa, r as Input, h as InputNumber, i as InputPassword, m as InputPhone, a as Loader, u as Modal, S as Notice, _ as Pagination, o as RadioButton, d as Select, C as SortableList, l as Text, c as Textarea, y as TimePicker, g as Toggle, x as Tooltip, z as components_exports };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stamcat/craftsman",
3
- "version": "0.0.31-beta.3",
3
+ "version": "0.0.31",
4
4
  "type": "module",
5
5
  "description": "A powerful, lightweight framework for design systems",
6
6
  "repository": {
@@ -16,6 +16,8 @@
16
16
  "bugs": {
17
17
  "url": "https://github.com/Stamcat/craftsman/issues"
18
18
  },
19
+ "x-agent-instructions": "./AGENTS.md",
20
+ "x-agent-components": "./src/components/*/AGENTS.md",
19
21
  "types": "./src/components/index.d.ts",
20
22
  "main": "./Components.esm.js",
21
23
  "homepage": "https://github.com/Stamcat/craftsman#readme",
@@ -79,6 +81,10 @@
79
81
  "./styles/utilities/placeholders": {
80
82
  "default": "./src/styles/utilities/_placeholders.scss"
81
83
  },
84
+ "./Accordion": {
85
+ "types": "./src/components/Accordion/Accordion.d.ts",
86
+ "default": "./src/components/Accordion/Accordion.esm.js"
87
+ },
82
88
  "./Button": {
83
89
  "types": "./src/components/Button/Button.d.ts",
84
90
  "default": "./src/components/Button/Button.esm.js"
@@ -0,0 +1,156 @@
1
+ ---
2
+ name: craftsman-component-usage
3
+ description: 'Global AI agent guidelines for using the @stamcat/craftsman component library — package exports, hard import rules, code block rendering, Toast usage, and code generation patterns. Use when generating or reviewing code that imports from @stamcat/craftsman or needing per-component prop contracts (Button, Input, Modal, DatePicker, TimePicker, Carousel, Pagination, etc). See the craftsman-style-utilities, craftsman-utility-functions, and craftsman-device-detection skills for styling, utility function, and device detection guidance.'
4
+ ---
5
+
6
+ # Craftsman Component Library Usage
7
+
8
+ Global rules for AI agents generating code against `@stamcat/craftsman`. For a specific component's props, behavior notes, and examples, open that component's `AGENTS.md` co-located with its source — see the index below. For styling utilities and theme authoring, see the [craftsman-style-utilities skill](../craftsman-style-utilities/SKILL.md). For the `isEmpty` utility and style utility parity notes, see the [craftsman-utility-functions skill](../craftsman-utility-functions/SKILL.md). For device/browser/OS detection, see the [craftsman-device-detection skill](../craftsman-device-detection/SKILL.md).
9
+
10
+ ## What This Package Currently Exports
11
+
12
+ The package is built with component-level entry points only.
13
+
14
+ ```tsx
15
+ import { Accordion } from "@stamcat/craftsman/Accordion";
16
+ import { Button } from "@stamcat/craftsman/Button";
17
+ import { Carousel } from "@stamcat/craftsman/Carousel";
18
+ import { Checkbox } from "@stamcat/craftsman/Checkbox";
19
+ import { DatePicker } from "@stamcat/craftsman/DatePicker";
20
+ import { DateRangePicker } from "@stamcat/craftsman/DateRangePicker";
21
+ import { Input } from "@stamcat/craftsman/Input";
22
+ import { InputNumber } from "@stamcat/craftsman/InputNumber";
23
+ import { InputPassword } from "@stamcat/craftsman/InputPassword";
24
+ import { InputPhone } from "@stamcat/craftsman/InputPhone";
25
+ import { Loader } from "@stamcat/craftsman/Loader";
26
+ import { Modal } from "@stamcat/craftsman/Modal";
27
+ import { Pagination } from "@stamcat/craftsman/Pagination";
28
+ import { RadioButton } from "@stamcat/craftsman/RadioButton";
29
+ import { Select } from "@stamcat/craftsman/Select";
30
+ import { Text } from "@stamcat/craftsman/Text";
31
+ import { Textarea } from "@stamcat/craftsman/Textarea";
32
+ import { TimePicker } from "@stamcat/craftsman/TimePicker";
33
+ import { DateTimePicker } from "@stamcat/craftsman/DateTimePicker";
34
+ import { Toggle } from "@stamcat/craftsman/Toggle";
35
+ import { Tooltip } from "@stamcat/craftsman/Tooltip";
36
+ import { Notice } from "@stamcat/craftsman/Notice";
37
+ import { SortableList } from "@stamcat/craftsman/SortableList";
38
+ ```
39
+
40
+ Do not assume a root export like `@stamcat/craftsman` unless that export is explicitly added to package `exports`.
41
+
42
+ ## Hard Rules for Agents
43
+
44
+ 1. Never deep-import from package internals (for example `@stamcat/craftsman/src/...`). This applies to Sass too — `@use "@stamcat/craftsman/src/styles/utilities/functions"` will fail to resolve; use the published subpath `@stamcat/craftsman/styles/utilities/functions` instead.
45
+ 2. Only use documented component entry points.
46
+ 3. Do not import storybook files from consuming applications. Style utilities are fine to import, but only via their published subpaths (`@stamcat/craftsman/styles/utilities/functions`, `/mixins`, `/placeholders`) — never via a `/src/...` path.
47
+ 4. Prefer standard React props first; use custom props only when required.
48
+
49
+ ## Component Index
50
+
51
+ Each entry links to the `AGENTS.md` co-located with that component's source for props, behavior notes, and examples.
52
+
53
+ | Component | Docs |
54
+ |---|---|
55
+ | Accordion | [../../src/components/Accordion/AGENTS.md](../../src/components/Accordion/AGENTS.md) |
56
+ | Button | [../../src/components/Button/AGENTS.md](../../src/components/Button/AGENTS.md) |
57
+ | Input | [../../src/components/Input/AGENTS.md](../../src/components/Input/AGENTS.md) |
58
+ | InputPassword | [../../src/components/InputPassword/AGENTS.md](../../src/components/InputPassword/AGENTS.md) |
59
+ | Checkbox | [../../src/components/Checkbox/AGENTS.md](../../src/components/Checkbox/AGENTS.md) |
60
+ | RadioButton | [../../src/components/RadioButton/AGENTS.md](../../src/components/RadioButton/AGENTS.md) |
61
+ | Modal | [../../src/components/Modal/AGENTS.md](../../src/components/Modal/AGENTS.md) |
62
+ | Pagination | [../../src/components/Pagination/AGENTS.md](../../src/components/Pagination/AGENTS.md) |
63
+ | Carousel | [../../src/components/Carousel/AGENTS.md](../../src/components/Carousel/AGENTS.md) |
64
+ | Loader | [../../src/components/Loader/AGENTS.md](../../src/components/Loader/AGENTS.md) |
65
+ | Textarea | [../../src/components/Textarea/AGENTS.md](../../src/components/Textarea/AGENTS.md) |
66
+ | Select | [../../src/components/Select/AGENTS.md](../../src/components/Select/AGENTS.md) |
67
+ | InputPhone | [../../src/components/InputPhone/AGENTS.md](../../src/components/InputPhone/AGENTS.md) |
68
+ | DatePicker | [../../src/components/DatePicker/AGENTS.md](../../src/components/DatePicker/AGENTS.md) |
69
+ | DateRangePicker | [../../src/components/DateRangePicker/AGENTS.md](../../src/components/DateRangePicker/AGENTS.md) |
70
+ | InputNumber | [../../src/components/InputNumber/AGENTS.md](../../src/components/InputNumber/AGENTS.md) |
71
+ | TimePicker | [../../src/components/TimePicker/AGENTS.md](../../src/components/TimePicker/AGENTS.md) |
72
+ | Text | [../../src/components/Text/AGENTS.md](../../src/components/Text/AGENTS.md) |
73
+ | DateTimePicker | [../../src/components/DateTimePicker/AGENTS.md](../../src/components/DateTimePicker/AGENTS.md) |
74
+ | Tooltip | [../../src/components/Tooltip/AGENTS.md](../../src/components/Tooltip/AGENTS.md) |
75
+ | Toggle | [../../src/components/Toggle/AGENTS.md](../../src/components/Toggle/AGENTS.md) |
76
+ | Notice | [../../src/components/Notice/AGENTS.md](../../src/components/Notice/AGENTS.md) |
77
+ | SortableList | [../../src/components/SortableList/AGENTS.md](../../src/components/SortableList/AGENTS.md) |
78
+
79
+ Not yet part of the documented public export surface: `Progress` (source exists but is incomplete — see Known Limitations).
80
+
81
+ ## Code Block Rendering
82
+
83
+ Craftsman's global styles automatically style `<code>` and `<code><pre>` elements. **Never create custom inline styles or wrapper divs to simulate a code block.** Use the native elements directly:
84
+
85
+ ```tsx
86
+ // Inline code — renders with pill/badge style
87
+ <code>someValue</code>
88
+
89
+ // Block code — renders with dark background, padding, and border-radius
90
+ <code><pre>{`your
91
+ multiline
92
+ code here`}</pre></code>
93
+ ```
94
+
95
+ The two modes are driven by `_code.scss`:
96
+ - `<code>` alone → light gray background, inline display
97
+ - `<code>` containing `<pre>` → dark background (`--gray800`), block display, padded and rounded
98
+
99
+ Do not create `preStyle`, `codeBlockStyle`, or equivalent inline style objects for this purpose. The global styles handle it.
100
+
101
+ ## Toast (react-toastify)
102
+
103
+ Craftsman re-exports `toast` and `ToastContainer` from `react-toastify`. No custom wrapper is needed, and there is no dedicated component folder for it.
104
+
105
+ Import:
106
+
107
+ ```tsx
108
+ import { toast, ToastContainer } from "react-toastify";
109
+ import "react-toastify/dist/ReactToastify.css";
110
+ ```
111
+
112
+ Usage:
113
+
114
+ - Render one `<ToastContainer>` near the root of your app.
115
+ - Call `toast(...)` anywhere in response to user actions.
116
+ - `ToastContainer` props: `position`, `autoClose`, `theme` (`"light" | "dark" | "colored"`), `closeOnClick`, `pauseOnHover`, `draggable`, `newestOnTop`.
117
+
118
+ Example:
119
+
120
+ ```tsx
121
+ // Root layout
122
+ <ToastContainer position="bottom-right" autoClose={3000} theme="light" />
123
+
124
+ // Anywhere in the app
125
+ toast("Saved successfully!");
126
+ toast.error("Something went wrong.");
127
+ toast.success("Profile updated.");
128
+ toast.warning("Unsaved changes.");
129
+ toast.info("New version available.");
130
+ ```
131
+
132
+ ## Code Generation Patterns to Prefer
133
+
134
+ 1. Generate fully typed React usage examples.
135
+ 2. Keep accessibility props in place (`aria-label`, `disabled`, semantic `type`).
136
+ 3. Use `variant="primary"` for main actions and `variant="text"` for low-emphasis actions.
137
+ 4. For loading states, pair `Loader` with accessible status text where needed.
138
+ 5. **Functional component declaration order** — always organize the body in this sequence:
139
+ 1. Hook calls (`useSomething`)
140
+ 2. State (`useState`)
141
+ 3. Derived state / variables (values computed from state or props)
142
+ 4. Action handlers (`const handle*`, `const dispatch*`, `useEffect`)
143
+
144
+ ## Known Limitations (Current Package State)
145
+
146
+ 1. The README now covers installation, theming, and getting-started usage; treat this skill and the per-component `AGENTS.md` files as the source of truth for deeper agent usage.
147
+ 2. Theme utilities exist in source but are not guaranteed public package exports.
148
+ 3. `Progress` exists in source but is incomplete and intentionally omitted from documentation for now.
149
+
150
+ ## Safe Fallback Strategy for Agents
151
+
152
+ If uncertain about available exports:
153
+
154
+ 1. Use only `Button`, `Checkbox`, `DatePicker`, `Input`, `InputPassword`, `InputPhone`, `Loader`, `Modal`, `RadioButton`, `Select`, `Text`, and `Textarea` from their component entry points.
155
+ 2. Do not invent package APIs.
156
+ 3. Prefer native HTML elements for anything not explicitly exported.
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: craftsman-device-detection
3
+ description: 'Device/browser detection conventions for @stamcat/craftsman — use react-device-detect instead of hand-rolled user-agent sniffing or window.innerWidth checks. Use when writing responsive logic, conditional rendering by device/browser/OS, or reviewing code that branches on viewport size or navigator.userAgent.'
4
+ ---
5
+
6
+ # Craftsman Device Detection
7
+
8
+ `react-device-detect` is already a dependency of `@stamcat/craftsman` (it powers the mobile wheel-picker fallback in `TimePicker`). **Prefer it over custom implementations** for any device, browser, or OS branching logic. Consuming apps should install it directly rather than writing their own detection.
9
+
10
+ ## Hard Rule
11
+
12
+ Never write custom detection logic such as:
13
+
14
+ ```ts
15
+ // DO NOT — fragile, reinvents an already-solved problem
16
+ const isMobile = /Mobi|Android/i.test(navigator.userAgent);
17
+ const isMobile = window.innerWidth < 768;
18
+ ```
19
+
20
+ Use the library instead:
21
+
22
+ ```tsx
23
+ import { isMobile } from "react-device-detect";
24
+
25
+ if (isMobile) {
26
+ // mobile-specific behavior
27
+ }
28
+ ```
29
+
30
+ CSS media queries are still the right tool for pure layout/visual breakpoints (see the [craftsman-style-utilities skill](../craftsman-style-utilities/SKILL.md) for `breakpoint()`). Reach for `react-device-detect` when the decision depends on the actual device/browser/OS rather than viewport width alone, or when the branch happens in JS/TS rather than CSS.
31
+
32
+ ## Common Named Exports
33
+
34
+ ```tsx
35
+ import {
36
+ isMobile,
37
+ isTablet,
38
+ isDesktop,
39
+ isBrowser,
40
+ isSmartTV,
41
+ isAndroid,
42
+ isIOS,
43
+ isMobileOnly,
44
+ browserName,
45
+ osName,
46
+ deviceType,
47
+ BrowserView,
48
+ MobileView,
49
+ TabletView,
50
+ } from "react-device-detect";
51
+ ```
52
+
53
+ - `isMobile` / `isTablet` / `isDesktop` / `isBrowser` — boolean flags for conditional logic.
54
+ - `isMobileOnly` — `true` for phones, `false` for tablets (use this, not `isMobile`, when tablets must be excluded).
55
+ - `browserName`, `osName`, `deviceType` — string values for logging/analytics, not for branching (prefer the boolean flags for that).
56
+ - `BrowserView` / `MobileView` / `TabletView` — declarative wrapper components that render `children` only on the matching device, as an alternative to `if (isMobile)` branches in JSX.
57
+
58
+ ## Example: Conditional Rendering
59
+
60
+ ```tsx
61
+ import { MobileView, BrowserView } from "react-device-detect";
62
+
63
+ <MobileView>
64
+ <CompactNav />
65
+ </MobileView>
66
+ <BrowserView>
67
+ <FullNav />
68
+ </BrowserView>
69
+ ```
70
+
71
+ ## Orientation
72
+
73
+ For portrait/landscape detection, use the `useMobileOrientation` hook rather than comparing `window.innerWidth`/`innerHeight`:
74
+
75
+ ```tsx
76
+ import { useMobileOrientation } from "react-device-detect";
77
+
78
+ const { isPortrait, isLandscape } = useMobileOrientation();
79
+ ```