@stamcat/craftsman 0.0.27 → 0.0.28

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 CHANGED
@@ -30,7 +30,9 @@ import { Select } from "@stamcat/craftsman/Select";
30
30
  import { Text } from "@stamcat/craftsman/Text";
31
31
  import { Textarea } from "@stamcat/craftsman/Textarea";
32
32
  import { TimePicker } from "@stamcat/craftsman/TimePicker";
33
+ import { DateTimePicker } from "@stamcat/craftsman/DateTimePicker";
33
34
  import { Toggle } from "@stamcat/craftsman/Toggle";
35
+ import { Tooltip } from "@stamcat/craftsman/Tooltip";
34
36
  import { Notice } from "@stamcat/craftsman/Notice";
35
37
  import { SortableList } from "@stamcat/craftsman/SortableList";
36
38
  ```
package/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # @stamcat/craftsman
2
2
 
3
- Craftsman design system components and styling utilities.
3
+ A lightweight, themeable React component library and design-system toolkit. Craftsman ships accessible, ready-to-style form controls, overlays, and layout primitives — plus a small set of theming and styling utilities — so you can build a consistent UI without pulling in a heavyweight framework.
4
+
5
+ - **Themeable by design** — override look and feel with a single `ThemeProvider` and CSS custom properties, no CSS-in-JS runtime required.
6
+ - **Tree-shakeable component entry points** — import only what you use (`@stamcat/craftsman/Button`, `@stamcat/craftsman/Input`, etc.).
7
+ - **React Server Component friendly** — works with Next.js App Router and other RSC setups.
8
+
9
+ 📖 Full component documentation and live examples: [stamcat.github.io/craftsman](https://stamcat.github.io/craftsman)
4
10
 
5
11
  ## Installation
6
12
 
@@ -8,12 +14,37 @@ Craftsman design system components and styling utilities.
8
14
  npm install @stamcat/craftsman
9
15
  ```
10
16
 
11
- ## RSC-safe setup
17
+ ## Getting started
18
+
19
+ 1. Import the package's global styles once at the root of your app.
20
+ 2. Wrap your app in `ThemeProvider`, optionally passing a theme object to customize CSS variables.
21
+ 3. Import components from their individual entry points and use them like any other React component.
22
+
23
+ ```tsx
24
+ import { ThemeProvider } from "@stamcat/craftsman/styles";
25
+ import { Button } from "@stamcat/craftsman/Button";
26
+ import { Input } from "@stamcat/craftsman/Input";
27
+ import "@stamcat/craftsman/styles/globalStyles";
28
+
29
+ const appTheme = {
30
+ root: {
31
+ "--w-gutter": "16px",
32
+ },
33
+ };
34
+
35
+ export default function App() {
36
+ return (
37
+ <ThemeProvider theme={appTheme}>
38
+ <Input label="Name" placeholder="Jane Doe" />
39
+ <Button>Submit</Button>
40
+ </ThemeProvider>
41
+ );
42
+ }
43
+ ```
12
44
 
13
- Use this pattern in React Server Component architectures (for example Next.js App Router):
45
+ ### RSC-safe setup
14
46
 
15
- 1. Import package global styles once at the application root.
16
- 2. Render `ThemeProvider` at the root with your theme object.
47
+ Use this pattern in React Server Component architectures (for example Next.js App Router). Render `ThemeProvider` at the root with your theme object, and import global styles once at the application root.
17
48
 
18
49
  ```tsx
19
50
  import { ThemeProvider } from "@stamcat/craftsman/styles";
@@ -36,15 +67,35 @@ export default function RootLayout({ children }: { children: React.ReactNode })
36
67
  }
37
68
  ```
38
69
 
39
- ## Component imports
70
+ ## Available components
40
71
 
41
- Use component entry points:
72
+ Each component has its own package entry point, e.g. `@stamcat/craftsman/Button`.
42
73
 
43
- ```tsx
44
- import { Button } from "@stamcat/craftsman/Button";
45
- import { Input } from "@stamcat/craftsman/Input";
46
- import { Modal } from "@stamcat/craftsman/Modal";
47
- ```
74
+ | Component | Entry point |
75
+ | --- | --- |
76
+ | Button | `@stamcat/craftsman/Button` |
77
+ | Carousel | `@stamcat/craftsman/Carousel` |
78
+ | Checkbox | `@stamcat/craftsman/Checkbox` |
79
+ | DatePicker | `@stamcat/craftsman/DatePicker` |
80
+ | DateRangePicker | `@stamcat/craftsman/DateRangePicker` |
81
+ | DateTimePicker | `@stamcat/craftsman/DateTimePicker` |
82
+ | Input | `@stamcat/craftsman/Input` |
83
+ | InputNumber | `@stamcat/craftsman/InputNumber` |
84
+ | InputPassword | `@stamcat/craftsman/InputPassword` |
85
+ | InputPhone | `@stamcat/craftsman/InputPhone` |
86
+ | Loader | `@stamcat/craftsman/Loader` |
87
+ | Modal | `@stamcat/craftsman/Modal` |
88
+ | Notice | `@stamcat/craftsman/Notice` |
89
+ | Pagination | `@stamcat/craftsman/Pagination` |
90
+ | Progress | `@stamcat/craftsman/Progress` |
91
+ | RadioButton | `@stamcat/craftsman/RadioButton` |
92
+ | Select | `@stamcat/craftsman/Select` |
93
+ | SortableList | `@stamcat/craftsman/SortableList` |
94
+ | Text | `@stamcat/craftsman/Text` |
95
+ | Textarea | `@stamcat/craftsman/Textarea` |
96
+ | TimePicker | `@stamcat/craftsman/TimePicker` |
97
+ | Toggle | `@stamcat/craftsman/Toggle` |
98
+ | Tooltip | `@stamcat/craftsman/Tooltip` |
48
99
 
49
100
  ## Styling notes
50
101
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stamcat/craftsman",
3
- "version": "0.0.27",
3
+ "version": "0.0.28",
4
4
  "type": "module",
5
5
  "description": "A powerful, lightweight framework for design systems",
6
6
  "repository": {
@@ -30,7 +30,6 @@
30
30
  "country-flag-icons": "1.6.20",
31
31
  "dompurify": "3.4.13",
32
32
  "embla-carousel-react": "8.6.0",
33
- "pure-react-carousel": "1.35.0",
34
33
  "react": "19.2.7",
35
34
  "react-date-picker": "12.0.2",
36
35
  "react-datetime-picker": "7.0.2",
@@ -1,68 +1,68 @@
1
1
  "use client";
2
2
  import { Button as e } from "../Button/Button.esm.js";
3
3
  import { Pagination as t } from "../Pagination/Pagination2.esm.js";
4
- import n from "../../../node_modules/embla-carousel-react/esm/embla-carousel-react.esm.esm.js";
5
4
  import './Carousel.css';/* empty css */
6
- import r from "clsx";
7
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
8
- import { useCallback as o, useSyncExternalStore as s } from "react";
9
- import { FaAngleLeft as c, FaAngleRight as l, FaCircle as u, FaRegCircle as d } from "react-icons/fa6";
5
+ import n from "clsx";
6
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
7
+ import { useCallback as a, useSyncExternalStore as o } from "react";
8
+ import { FaAngleLeft as s, FaAngleRight as c, FaCircle as l, FaRegCircle as u } from "react-icons/fa6";
9
+ import d from "embla-carousel-react";
10
10
  //#region src/components/Carousel/Carousel.tsx
11
11
  var f = (f) => {
12
- let { slides: p = [], className: m, style: h, buttons: g = !0, pagination: _ = "dots", ...v } = f, [y, b] = n(v), x = o((e) => b ? (b.on("select", e).on("reInit", e), () => {
12
+ let { slides: p = [], className: m, style: h, buttons: g = !0, pagination: _ = "dots", ...v } = f, [y, b] = d(v), x = a((e) => b ? (b.on("select", e).on("reInit", e), () => {
13
13
  b.off("select", e), b.off("reInit", e);
14
- }) : () => {}, [b]), S = s(x, () => !!b?.canScrollPrev(), () => !1), C = s(x, () => !!b?.canScrollNext(), () => !1), w = s(x, () => b?.selectedScrollSnap() ?? 0, () => 0), T = () => b?.scrollPrev(), E = () => b?.scrollNext(), D = (e) => {
14
+ }) : () => {}, [b]), S = o(x, () => !!b?.canScrollPrev(), () => !1), C = o(x, () => !!b?.canScrollNext(), () => !1), w = o(x, () => b?.selectedScrollSnap() ?? 0, () => 0), T = () => b?.scrollPrev(), E = () => b?.scrollNext(), D = (e) => {
15
15
  let t = parseInt(e.currentTarget.value, 10) || 0;
16
16
  b?.scrollTo(t);
17
17
  };
18
- return /* @__PURE__ */ a("div", {
19
- className: r("carousel", m),
18
+ return /* @__PURE__ */ i("div", {
19
+ className: n("carousel", m),
20
20
  style: h,
21
- children: [/* @__PURE__ */ i("div", {
21
+ children: [/* @__PURE__ */ r("div", {
22
22
  className: "carousel__viewport",
23
23
  ref: y,
24
- children: /* @__PURE__ */ i("div", {
24
+ children: /* @__PURE__ */ r("div", {
25
25
  className: "carousel__container",
26
- children: p.map((e, t) => /* @__PURE__ */ i("div", {
26
+ children: p.map((e, t) => /* @__PURE__ */ r("div", {
27
27
  className: "carousel__slide",
28
28
  children: e
29
29
  }, `slide-${t}`))
30
30
  })
31
- }), /* @__PURE__ */ a("div", {
31
+ }), /* @__PURE__ */ i("div", {
32
32
  className: "carousel__controls",
33
33
  children: [
34
- g && /* @__PURE__ */ a("div", {
34
+ g && /* @__PURE__ */ i("div", {
35
35
  className: "carousel__buttons",
36
- children: [/* @__PURE__ */ i(e, {
36
+ children: [/* @__PURE__ */ r(e, {
37
37
  variant: "text",
38
38
  onClick: T,
39
39
  disabled: !S,
40
40
  name: "prev",
41
- children: /* @__PURE__ */ i(c, {
41
+ children: /* @__PURE__ */ r(s, {
42
42
  size: 24,
43
43
  "aria-label": "prev"
44
44
  })
45
- }), /* @__PURE__ */ i(e, {
45
+ }), /* @__PURE__ */ r(e, {
46
46
  variant: "text",
47
47
  onClick: E,
48
48
  disabled: !C,
49
49
  name: "next",
50
- children: /* @__PURE__ */ i(l, {
50
+ children: /* @__PURE__ */ r(c, {
51
51
  size: 24,
52
52
  "aria-label": "next"
53
53
  })
54
54
  })]
55
55
  }),
56
- _ === "dots" && /* @__PURE__ */ i("div", {
56
+ _ === "dots" && /* @__PURE__ */ r("div", {
57
57
  className: "carousel__dots",
58
- children: p.map((t, n) => /* @__PURE__ */ i(e, {
58
+ children: p.map((t, n) => /* @__PURE__ */ r(e, {
59
59
  variant: "text",
60
60
  value: n,
61
61
  onClick: D,
62
- children: i(w === n ? u : d, { size: 16 })
62
+ children: r(w === n ? l : u, { size: 16 })
63
63
  }, `dot-${n}`))
64
64
  }),
65
- _ === "numbers" && /* @__PURE__ */ i(t, {
65
+ _ === "numbers" && /* @__PURE__ */ r(t, {
66
66
  total: p.length,
67
67
  current: w,
68
68
  onChange: D
@@ -1,24 +1,24 @@
1
1
  "use client";
2
- import e from "../../../node_modules/embla-carousel-react/esm/embla-carousel-react.esm.esm.js";
3
2
  import "./constants.esm.js";
4
- import { inactivateEmblaTransform as t, setContainerStyles as n, setSlideStyles as r, snapOnPointerUp as i } from "./utilities.esm.js";
5
- import a from "clsx";
6
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
- import { useCallback as c, useEffect as l, useLayoutEffect as u, useRef as d } from "react";
3
+ import { inactivateEmblaTransform as e, setContainerStyles as t, setSlideStyles as n, snapOnPointerUp as r } from "./utilities.esm.js";
4
+ import i from "clsx";
5
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
6
+ import { useCallback as s, useEffect as c, useLayoutEffect as l, useRef as u } from "react";
7
+ import d from "embla-carousel-react";
8
8
  //#region src/components/TimePicker/TimePickerWheel.tsx
9
9
  var f = (f) => {
10
- let { slideCount: p, perspective: m, label: h, loop: g = !1, offset: _ = 0, slides: v, selectedIndex: y, onSelect: b, disabled: x } = f, [S, C] = e({
10
+ let { slideCount: p, perspective: m, label: h, loop: g = !1, offset: _ = 0, slides: v, selectedIndex: y, onSelect: b, disabled: x } = f, [S, C] = d({
11
11
  loop: g,
12
12
  axis: "y",
13
13
  dragFree: !0,
14
14
  containScroll: !1
15
- }), w = d(null), T = d(b);
16
- u(() => {
15
+ }), w = u(null), T = u(b);
16
+ l(() => {
17
17
  T.current = b;
18
18
  });
19
- let E = p * 20, D = g ? 0 : 20, O = c((e) => {
20
- n(e, (p * 20 - D) * e.scrollProgress()), e.slideNodes().forEach((t, n) => {
21
- r(e, n, g, p, E);
19
+ let E = p * 20, D = g ? 0 : 20, O = s((e) => {
20
+ t(e, (p * 20 - D) * e.scrollProgress()), e.slideNodes().forEach((t, r) => {
21
+ n(e, r, g, p, E);
22
22
  });
23
23
  }, [
24
24
  g,
@@ -26,32 +26,32 @@ var f = (f) => {
26
26
  D,
27
27
  E
28
28
  ]);
29
- return l(() => {
29
+ return c(() => {
30
30
  if (!C) return () => {};
31
- let e = (e) => T.current?.(e.selectedScrollSnap());
32
- return C.on("pointerUp", i), C.on("scroll", O), C.on("reInit", t), C.on("reInit", O), C.on("select", e), t(C), O(C), () => {
33
- C.off("pointerUp", i), C.off("scroll", O), C.off("reInit", t), C.off("reInit", O), C.off("select", e);
31
+ let t = (e) => T.current?.(e.selectedScrollSnap());
32
+ return C.on("pointerUp", r), C.on("scroll", O), C.on("reInit", e), C.on("reInit", O), C.on("select", t), e(C), O(C), () => {
33
+ C.off("pointerUp", r), C.off("scroll", O), C.off("reInit", e), C.off("reInit", O), C.off("select", t);
34
34
  };
35
- }, [C, O]), l(() => {
35
+ }, [C, O]), c(() => {
36
36
  !C || y === void 0 || C.selectedScrollSnap() !== y && C.scrollTo(y);
37
- }, [C, y]), /* @__PURE__ */ s("div", {
38
- className: a("ios-picker", { "ios-picker--disabled": x }),
37
+ }, [C, y]), /* @__PURE__ */ o("div", {
38
+ className: i("ios-picker", { "ios-picker--disabled": x }),
39
39
  "aria-disabled": x,
40
- children: [/* @__PURE__ */ o("div", {
40
+ children: [/* @__PURE__ */ a("div", {
41
41
  className: "ios-picker__scene",
42
42
  ref: w,
43
- children: /* @__PURE__ */ o("div", {
43
+ children: /* @__PURE__ */ a("div", {
44
44
  className: `ios-picker__viewport ios-picker__viewport--perspective-${m}`,
45
45
  ref: S,
46
- children: /* @__PURE__ */ o("div", {
46
+ children: /* @__PURE__ */ a("div", {
47
47
  className: "ios-picker__container",
48
- children: Array.from({ length: p }, (e, t) => /* @__PURE__ */ o("div", {
48
+ children: Array.from({ length: p }, (e, t) => /* @__PURE__ */ a("div", {
49
49
  className: "ios-picker__slide",
50
50
  children: v ? v[t] : t + _
51
51
  }, t))
52
52
  })
53
53
  })
54
- }), /* @__PURE__ */ o("div", {
54
+ }), /* @__PURE__ */ a("div", {
55
55
  className: "ios-picker__label",
56
56
  children: h
57
57
  })]