@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.
- package/AGENTS.md +5 -4
- package/Components.esm.js +78 -76
- package/package.json +7 -1
- package/skills/craftsman-component-usage/SKILL.md +156 -0
- package/skills/craftsman-device-detection/SKILL.md +79 -0
- package/skills/craftsman-style-utilities/SKILL.md +228 -0
- package/skills/craftsman-utility-functions/SKILL.md +71 -0
- package/src/components/Accordion/AGENTS.md +45 -0
- package/src/components/Accordion/Accordion.css +1 -0
- package/src/components/Accordion/Accordion.d.ts +14 -0
- package/src/components/Accordion/Accordion.scss +64 -0
- package/src/components/Accordion/Accordion2.esm.js +70 -0
- package/src/components/Carousel/Carousel2.esm.js +21 -21
- package/src/components/DatePicker/DatePicker.css +1 -1
- package/src/components/DatePicker/DatePicker2.esm.js +11 -11
- package/src/components/DateRangePicker/DateRangePicker.css +1 -1
- package/src/components/DateRangePicker/DateRangePicker2.esm.js +10 -10
- package/src/components/DateTimePicker/DateTimePicker.css +1 -1
- package/src/components/DateTimePicker/DateTimePicker2.esm.js +14 -14
- package/src/components/Input/Input.css +1 -1
- package/src/components/Input/Input.scss +7 -0
- package/src/components/Input/Input2.esm.js +10 -10
- package/src/components/InputNumber/InputNumber2.esm.js +10 -10
- package/src/components/InputPassword/InputPassword.esm.js +9 -9
- package/src/components/InputPhone/InputPhone2.esm.js +7 -7
- package/src/components/Modal/Modal2.esm.js +15 -15
- package/src/components/Pagination/Pagination2.esm.js +1 -1
- package/src/components/Select/Select.esm.js +18 -17
- package/src/components/SortableList/ListItem.esm.js +8 -8
- package/src/components/SortableList/SortableList2.esm.js +8 -8
- package/src/components/Text/AGENTS.md +4 -2
- package/src/components/Textarea/Textarea.esm.js +5 -5
- package/src/components/TimePicker/TimePicker.css +1 -1
- package/src/components/TimePicker/TimePicker2.esm.js +15 -15
- package/src/components/TimePicker/TimePickerDisplay.esm.js +1 -1
- package/src/components/TimePicker/TimePickerWheel.esm.js +15 -15
- package/src/components/Tooltip/Tooltip2.esm.js +12 -12
- package/src/components/index.d.ts +1 -0
- package/src/styles/global/components/_input.scss +8 -9
- package/src/styles/global/components/_select.scss +11 -16
- 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](
|
|
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](
|
|
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
|
|
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 {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
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
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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,
|
|
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
|
|
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
|
+
```
|