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

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 (62) hide show
  1. package/AGENTS.md +54 -2
  2. package/Components.esm.js +11 -9
  3. package/README.md +5 -0
  4. package/Styles.esm.js +5 -5
  5. package/package.json +5 -4
  6. package/src/components/Button.d.ts +1 -1
  7. package/src/components/Button.esm.js +14 -16
  8. package/src/components/{Checkbox.esm.js → Input/Checkbox.esm.js} +1 -1
  9. package/src/components/Input/Input.d.ts +6 -0
  10. package/src/components/Input/Input.esm.js +33 -0
  11. package/src/components/Input/Input.module.css +1 -0
  12. package/src/components/Input/Input.module.esm.js +13 -0
  13. package/src/components/Input/Input.module.scss +165 -0
  14. package/src/components/{InputPassword.d.ts → Input/InputPassword.d.ts} +1 -1
  15. package/src/components/Input/InputPassword.esm.js +29 -0
  16. package/src/components/Input/InputWrapper.d.ts +11 -0
  17. package/src/components/Input/InputWrapper.esm.js +28 -0
  18. package/src/components/{RadioButton.esm.js → Input/RadioButton.esm.js} +1 -1
  19. package/src/components/Input/Textarea.d.ts +3 -0
  20. package/src/components/Input/Textarea.esm.js +25 -0
  21. package/src/components/Modal.esm.js +18 -26
  22. package/src/components/Modal.module.css +1 -1
  23. package/src/components/Modal.module.esm.js +6 -3
  24. package/src/components/Modal.module.scss +28 -14
  25. package/src/components/index.d.ts +5 -4
  26. package/src/styles/components/ThemeProvider.esm.js +1 -1
  27. package/src/styles/global/components/_button.scss +52 -51
  28. package/src/styles/global/components/_checkbox.scss +63 -59
  29. package/src/styles/global/components/_code.scss +19 -15
  30. package/src/styles/global/components/_input.scss +35 -37
  31. package/src/styles/global/components/_radioButton.scss +29 -26
  32. package/src/styles/global/components/_typography.scss +61 -6
  33. package/src/styles/global/components/loaders.module.css +1 -1
  34. package/src/styles/global/components/loaders.module.esm.js +1 -1
  35. package/src/styles/global/components/loaders.module.scss +2 -1
  36. package/src/styles/global/globalStyles.module.scss +1 -129
  37. package/src/styles/global/globalStyles.scss +83 -1
  38. package/src/styles/index.d.ts +1 -1
  39. package/src/styles/theme/components.esm.js +11 -5
  40. package/src/styles/theme/theme.esm.js +29 -43
  41. package/src/styles/theme/types.d.ts +1 -1
  42. package/src/styles/utilities/_functions.scss +116 -0
  43. package/src/styles/utilities/_mixins.scss +0 -0
  44. package/src/styles/utilities/color.d.ts +1 -1
  45. package/src/styles/utilities/constants.d.ts +1 -1
  46. package/src/styles/utilities/layout.d.ts +1 -1
  47. package/src/styles/utilities/layout.esm.js +1 -1
  48. package/src/{styles/utilities → utilities}/types.d.ts +7 -1
  49. package/src/{styles/utilities → utilities}/types.esm.js +6 -2
  50. package/src/components/Button.module.css +0 -1
  51. package/src/components/Button.module.esm.js +0 -9
  52. package/src/components/Button.module.scss +0 -5
  53. package/src/components/Input.d.ts +0 -11
  54. package/src/components/Input.esm.js +0 -41
  55. package/src/components/Input.module.css +0 -1
  56. package/src/components/Input.module.esm.js +0 -11
  57. package/src/components/Input.module.scss +0 -141
  58. package/src/components/InputPassword.esm.js +0 -33
  59. package/src/styles/global/components/_mixins.scss +0 -2
  60. package/src/styles/global/components/button.d.ts +0 -7
  61. /package/src/components/{Checkbox.d.ts → Input/Checkbox.d.ts} +0 -0
  62. /package/src/components/{RadioButton.d.ts → Input/RadioButton.d.ts} +0 -0
package/AGENTS.md CHANGED
@@ -48,8 +48,8 @@ Behavior notes:
48
48
 
49
49
  - `type` defaults to `"button"`.
50
50
  - For `variant !== "default"`, variant is appended to `className` (for example `"primary"`).
51
- - Theme class merge: if `theme.components.button` is a string, it is appended to the class list.
52
- - `className` is preserved and merged after variant/theme classes.
51
+ - `className` is preserved and merged after component classes.
52
+ - Theme component overrides are selector-based CSS emitted by `ThemeProvider`; `theme.components.*` accepts JS style objects or raw CSS/Sass strings for the target selector.
53
53
  - If `children` is empty (per `isEmpty`), the component renders nothing.
54
54
  - `size` is clamped to `[0.1, 10]` before styling is applied.
55
55
  - When `size` is provided, Button scales:
@@ -316,6 +316,27 @@ Example:
316
316
  - If your app does not include this package's global CSS variable setup, visual output may differ.
317
317
  - Agents should avoid hard-coding assumptions about token names beyond what the consumer app already defines.
318
318
 
319
+ ## Theme Authoring
320
+
321
+ - `theme.root` supports JS style objects and raw CSS/Sass strings.
322
+ - `theme.components.*` supports JS style objects and raw CSS/Sass strings.
323
+ - String component styles are applied to the mapped target selector (for example `button`, `input[type='checkbox']`).
324
+ - For multi-file Sass workflows with syntax highlighting and mixins, import compiled CSS text via `*.scss?inline`.
325
+
326
+ Example:
327
+
328
+ ```tsx
329
+ import greenRoot from "./green.root.scss?inline";
330
+ import greenButton from "./green.button.scss?inline";
331
+
332
+ export const theme = {
333
+ root: greenRoot,
334
+ components: {
335
+ button: greenButton,
336
+ },
337
+ };
338
+ ```
339
+
319
340
  ## Utility Functions
320
341
 
321
342
  ### `isEmpty`
@@ -350,6 +371,37 @@ if (Object.keys(obj).length === 0) { ... }
350
371
  if (arr.length === 0) { ... }
351
372
  ```
352
373
 
374
+ ### Style utilities parity (`color`, `width`, `breakpoint`)
375
+
376
+ These utility patterns exist in both TypeScript and Sass.
377
+
378
+ TypeScript usage:
379
+
380
+ ```ts
381
+ import { color, width, breakpoint } from "@stamcat/craftsman/styles";
382
+
383
+ const accent = color("blue500");
384
+ const alphaAccent = color("blue500", "rgba", 0.32);
385
+ const twoColumns = width("column", 2);
386
+ const mobileRule = breakpoint("mobileMax", "h4{font-size:14px;}");
387
+ ```
388
+
389
+ Sass usage (framework source):
390
+
391
+ ```scss
392
+ @use "./src/styles/utilities" as u;
393
+
394
+ .example {
395
+ color: #{u.color(blue500)};
396
+ background: #{u.color(blue500, rgba, 0.32)};
397
+ max-width: #{u.width(column, 2)};
398
+ }
399
+
400
+ @include u.breakpoint(mobileMax) {
401
+ .example { font-size: #{u.width(text)}; }
402
+ }
403
+ ```
404
+
353
405
  ## Code Generation Patterns to Prefer
354
406
 
355
407
  1. Generate fully typed React usage examples.
package/Components.esm.js CHANGED
@@ -1,20 +1,22 @@
1
1
  import { __exportAll as e } from "./_virtual/_rolldown/runtime.esm.js";
2
2
  import { Button as t } from "./src/components/Button.esm.js";
3
- import { Input as n } from "./src/components/Input.esm.js";
4
- import { InputPassword as r } from "./src/components/InputPassword.esm.js";
3
+ import { Input as n } from "./src/components/Input/Input.esm.js";
4
+ import { InputPassword as r } from "./src/components/Input/InputPassword.esm.js";
5
5
  import { Loader as i } from "./src/components/Loader.esm.js";
6
- import { RadioButton as a } from "./src/components/RadioButton.esm.js";
7
- import { Checkbox as o } from "./src/components/Checkbox.esm.js";
8
- import { Modal as s } from "./src/components/Modal.esm.js";
6
+ import { RadioButton as a } from "./src/components/Input/RadioButton.esm.js";
7
+ import { Checkbox as o } from "./src/components/Input/Checkbox.esm.js";
8
+ import { Textarea as s } from "./src/components/Input/Textarea.esm.js";
9
+ import { Modal as c } from "./src/components/Modal.esm.js";
9
10
  //#region src/components/index.ts
10
- var c = /* @__PURE__ */ e({
11
+ var l = /* @__PURE__ */ e({
11
12
  Button: () => t,
12
13
  Checkbox: () => o,
13
14
  Input: () => n,
14
15
  InputPassword: () => r,
15
16
  Loader: () => i,
16
- Modal: () => s,
17
- RadioButton: () => a
17
+ Modal: () => c,
18
+ RadioButton: () => a,
19
+ Textarea: () => s
18
20
  });
19
21
  //#endregion
20
- export { t as Button, o as Checkbox, n as Input, r as InputPassword, i as Loader, s as Modal, a as RadioButton, c as components_exports };
22
+ export { t as Button, o as Checkbox, n as Input, r as InputPassword, i as Loader, c as Modal, a as RadioButton, s as Textarea, l as components_exports };
package/README.md CHANGED
@@ -50,3 +50,8 @@ import { Modal } from "@stamcat/craftsman/Modal";
50
50
 
51
51
  - `ThemeProvider` injects theme CSS variables and component override rules.
52
52
  - Global styles should be loaded once at app root.
53
+ - Base defaults are emitted in the `craftsman-base` layer and theme overrides in `craftsman-theme`.
54
+ - For equal specificity, `craftsman-theme` overrides `craftsman-base`.
55
+ - `theme.components.input` targets only non-radio and non-checkbox inputs.
56
+ - `theme.root` and `theme.components.*` support JS style objects and raw CSS/Sass strings.
57
+ - For Sass file workflows, import compiled CSS text via `*.scss?inline` and pass that string into the theme object.
package/Styles.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { defaultColors as e, defaultWidths as t } from "./src/styles/utilities/constants.esm.js";
2
2
  import { color as n, colors as r, hexToRgba as i } from "./src/styles/utilities/color.esm.js";
3
- import { BaseWidthSchema as a, BreakpointSchema as o, LayoutWidthsSchema as s, MaxScreenWidthSchema as c, ScreenWidthSchema as l, zLabelPosition as u, zTextInputExclusions as d, zTextInputType as f, zTextInputTypes as p } from "./src/styles/utilities/types.esm.js";
4
- import { breakpoint as m, media as h, width as g, widths as _ } from "./src/styles/utilities/layout.esm.js";
5
- import { themeBuilder as v } from "./src/styles/theme/theme.esm.js";
6
- import { ThemeProvider as y } from "./src/styles/components/ThemeProvider.esm.js";
7
- export { a as BaseWidthSchema, o as BreakpointSchema, s as LayoutWidthsSchema, c as MaxScreenWidthSchema, l as ScreenWidthSchema, y as ThemeProvider, m as breakpoint, n as color, r as colors, e as defaultColors, t as defaultWidths, i as hexToRgba, h as media, v as themeBuilder, g as width, _ as widths, u as zLabelPosition, d as zTextInputExclusions, f as zTextInputType, p as zTextInputTypes };
3
+ import { BaseWidthSchema as a, BreakpointSchema as o, ButtonType as s, LayoutWidthsSchema as c, MaxScreenWidthSchema as l, ScreenWidthSchema as u, zLabelPosition as d, zTextInputExclusions as f, zTextInputType as p, zTextInputTypes as m } from "./src/utilities/types.esm.js";
4
+ import { breakpoint as h, media as g, width as _, widths as v } from "./src/styles/utilities/layout.esm.js";
5
+ import { themeBuilder as y } from "./src/styles/theme/theme.esm.js";
6
+ import { ThemeProvider as b } from "./src/styles/components/ThemeProvider.esm.js";
7
+ export { a as BaseWidthSchema, o as BreakpointSchema, s as ButtonType, c as LayoutWidthsSchema, l as MaxScreenWidthSchema, u as ScreenWidthSchema, b as ThemeProvider, h as breakpoint, n as color, r as colors, e as defaultColors, t as defaultWidths, i as hexToRgba, g as media, y as themeBuilder, _ as width, v as widths, d as zLabelPosition, f as zTextInputExclusions, p as zTextInputType, m as zTextInputTypes };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stamcat/craftsman",
3
- "version": "0.0.27-alpha.2",
3
+ "version": "0.0.27-alpha.4",
4
4
  "type": "module",
5
5
  "description": "A powerful, lightweight framework for design systems",
6
6
  "repository": {
@@ -54,9 +54,6 @@
54
54
  "types": "./src/utilities/index.d.ts",
55
55
  "default": "./Utilities.esm.js"
56
56
  },
57
- "./styles/globalStyles": {
58
- "default": "./src/styles/global/globalStyles.scss"
59
- },
60
57
  "./styles/globalStyles.scss": {
61
58
  "default": "./src/styles/global/globalStyles.scss"
62
59
  },
@@ -84,6 +81,10 @@
84
81
  "types": "./src/components/Checkbox.d.ts",
85
82
  "default": "./src/components/Checkbox.esm.js"
86
83
  },
84
+ "./Textarea": {
85
+ "types": "./src/components/Textarea.d.ts",
86
+ "default": "./src/components/Textarea.esm.js"
87
+ },
87
88
  "./Modal": {
88
89
  "types": "./src/components/Modal.d.ts",
89
90
  "default": "./src/components/Modal.esm.js"
@@ -1,4 +1,4 @@
1
- import { ButtonType } from '../styles/global/components/button';
1
+ import { ButtonType } from '../styles';
2
2
  export type ButtonProps = React.ComponentProps<"button"> & {
3
3
  variant?: ButtonType;
4
4
  size?: number;
@@ -2,27 +2,25 @@
2
2
  import { isEmpty as e } from "../utilities/validations.esm.js";
3
3
  import { width as t } from "../styles/utilities/layout.esm.js";
4
4
  import "../../Styles.esm.js";
5
- import n from "./Button.module.esm.js";
6
- import r from "clsx";
7
- import { Fragment as i, jsx as a } from "react/jsx-runtime";
5
+ import n from "clsx";
6
+ import { Fragment as r, jsx as i } from "react/jsx-runtime";
8
7
  //#region src/components/Button.tsx
9
- var o = (o) => {
10
- let { type: s = "button", variant: c = "default", size: l, styles: u, className: d, style: f, ...p } = o, m = typeof l == "number" ? Math.min(10, Math.max(.1, l)) : void 0, h = e(u) ? void 0 : u, g = m ? {
11
- borderRadius: `calc(var(--btn-border-radius) * ${m})`,
12
- padding: `calc(var(--btn-pad-y) * ${m}) calc(var(--btn-pad-x) * ${m})`,
13
- fontSize: `max(10px, calc(${t("text")} * ${m}))`
8
+ var a = (a) => {
9
+ let { type: o = "button", variant: s = "default", size: c, styles: l, className: u, style: d, ...f } = a, p = typeof c == "number" ? Math.min(10, Math.max(.1, c)) : void 0, m = e(l) ? void 0 : l, h = p ? {
10
+ borderRadius: `calc(var(--btn-border-radius) * ${p})`,
11
+ padding: `calc(var(--btn-pad-y) * ${p}) calc(var(--btn-pad-x) * ${p})`,
12
+ fontSize: `max(10px, calc(${t("text")} * ${p}))`
14
13
  } : {};
15
- return e(o.children) ? /* @__PURE__ */ a(i, {}) : /* @__PURE__ */ a("button", {
16
- type: s,
17
- "data-variant": c,
18
- className: r(n.button, "button", d),
14
+ return e(a.children) ? /* @__PURE__ */ i(r, {}) : /* @__PURE__ */ i("button", {
15
+ type: o,
16
+ className: n(s, u),
19
17
  style: {
20
- ...g,
21
18
  ...h,
22
- ...f
19
+ ...m,
20
+ ...d
23
21
  },
24
- ...p
22
+ ...f
25
23
  });
26
24
  };
27
25
  //#endregion
28
- export { o as Button };
26
+ export { a as Button };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Input as e } from "./Input.esm.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
- //#region src/components/Checkbox.tsx
4
+ //#region src/components/Input/Checkbox.tsx
5
5
  var n = ({ type: n = "checkbox", labelPosition: r = "right", ...i }) => /* @__PURE__ */ t(e, {
6
6
  type: n,
7
7
  labelPosition: r,
@@ -0,0 +1,6 @@
1
+ import { LabeledInput } from './InputWrapper';
2
+ import { TextInputType } from '../../utilities/types';
3
+ export type InputProps = React.ComponentProps<"input"> & LabeledInput & {
4
+ type?: TextInputType;
5
+ };
6
+ export declare const Input: React.FC<InputProps>;
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { isEmpty as e } from "../../utilities/validations.esm.js";
3
+ import t from "./Input.module.esm.js";
4
+ import { InputWrapper as n } from "./InputWrapper.esm.js";
5
+ import r from "clsx";
6
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
+ import { useId as o } from "react";
8
+ //#region src/components/Input/Input.tsx
9
+ var s = ({ label: s, id: c, labelPosition: l = "top", required: u = !1, type: d = "text", error: f, styles: p, endAdornment: m, ...h }) => {
10
+ let g = o(), _ = c || g;
11
+ return /* @__PURE__ */ i(n, {
12
+ label: s,
13
+ labelPosition: l,
14
+ error: f,
15
+ required: u,
16
+ styles: p,
17
+ children: /* @__PURE__ */ a("span", {
18
+ className: t.inputField,
19
+ "data-has-end-adornment": !e(m),
20
+ children: [/* @__PURE__ */ i("input", {
21
+ id: _,
22
+ type: d,
23
+ className: r(t.input, d),
24
+ ...h
25
+ }), !e(m) && /* @__PURE__ */ i("span", {
26
+ className: t.inputAdornment,
27
+ children: m
28
+ })]
29
+ })
30
+ });
31
+ };
32
+ //#endregion
33
+ export { s as Input };
@@ -0,0 +1 @@
1
+ @layer craftsman-base{._wrapper_xzvi1_2[data-label-position=inside]{--react-international-phone-height:50px;--react-international-phone-border-radius:8px;--react-international-phone-border-color:silver;position:relative}}._wrapper_xzvi1_2 label ._inputLabel_xzvi1_9{margin-bottom:calc(var(--w-gutter,var(--w-gutter)px) * .25)}._wrapper_xzvi1_2[data-required=true] label ._inputLabel_xzvi1_9:after{content:"*";color:var(--red700)}._wrapper_xzvi1_2[data-label-position=left] label{align-items:center;display:inline-flex}._wrapper_xzvi1_2[data-label-position=left] label ._inputLabel_xzvi1_9{width:fit-content;margin-right:calc(var(--w-gutter,var(--w-gutter)px) * .75)}._wrapper_xzvi1_2[data-label-position=left]._textarea_xzvi1_24 label{align-items:flex-start}._wrapper_xzvi1_2[data-label-position=bottom] label{flex-direction:column-reverse;align-items:flex-start;display:inline-flex}._wrapper_xzvi1_2[data-label-position=bottom] label ._inputLabel_xzvi1_9{margin-bottom:0;margin-top:calc(var(--w-gutter,var(--w-gutter)px) * .25)}._wrapper_xzvi1_2[data-label-position=right] label{flex-direction:row-reverse;align-items:baseline;display:inline-flex}._wrapper_xzvi1_2[data-label-position=right] label ._inputLabel_xzvi1_9{margin-left:calc(var(--w-gutter,var(--w-gutter)px) * .25);margin-bottom:0}._wrapper_xzvi1_2[data-label-position=inside] ._inputLabel_xzvi1_9{background-color:var(--white);z-index:1;width:fit-content;top:calc(var(--w-gutter,var(--w-gutter)px) * .25);left:calc(var(--w-gutter,var(--w-gutter)px) * .25);pointer-events:none;padding:0 5px;transition:top .15s,left .15s,font-size .15s,color .15s;position:absolute}._wrapper_xzvi1_2[data-label-position=inside]>label>._inputField_xzvi1_56>._input_xzvi1_9,._wrapper_xzvi1_2[data-label-position=inside]>._input_xzvi1_9{transition:border-color .2s}._wrapper_xzvi1_2[data-label-position=inside]:focus-within ._inputLabel_xzvi1_9{top:-.5rem;left:calc(var(--w-gutter,var(--w-gutter)px) * .125);font-size:calc(var(--w-text,var(--w-text)px) * .75);color:var(--blue500)}._wrapper_xzvi1_2[data-label-position=inside]:focus-within ._input_xzvi1_9{border-color:var(--blue500)}._wrapper_xzvi1_2[data-label-position=inside]:focus-within ._input_xzvi1_9::placeholder{opacity:1}._wrapper_xzvi1_2[data-label-position=inside][data-has-input=true] ._inputLabel_xzvi1_9{top:-.5rem;left:calc(var(--w-gutter,var(--w-gutter)px) * .125);font-size:calc(var(--w-text,var(--w-text)px) * .75)}._wrapper_xzvi1_2[data-label-position=inside]:has(._input_xzvi1_9:not(:placeholder-shown)) ._inputLabel_xzvi1_9{top:-.5rem;left:calc(var(--w-gutter,var(--w-gutter)px) * .125);font-size:calc(var(--w-text,var(--w-text)px) * .75)}._wrapper_xzvi1_2[data-label-position=inside]:has(._input_xzvi1_9:-webkit-autofill) ._inputLabel_xzvi1_9{top:-.5rem;left:calc(var(--w-gutter,var(--w-gutter)px) * .125);font-size:calc(var(--w-text,var(--w-text)px) * .75)}._wrapper_xzvi1_2[data-label-position=inside] ._input_xzvi1_9[type=tel]{width:100%}._wrapper_xzvi1_2[data-label-position=inside] ._input_xzvi1_9::placeholder{opacity:0;transition:opacity .2s}._inputField_xzvi1_56{align-items:center;display:inline-flex;position:relative}._inputField_xzvi1_56[data-has-end-adornment=true]>._input_xzvi1_9{width:100%;padding-right:calc(var(--w-gutter,var(--w-gutter)px) * 1.5)}._inputAdornment_xzvi1_95{right:calc(var(--w-gutter,var(--w-gutter)px) * .5);z-index:1;align-items:center;margin-top:0;display:inline-flex;position:absolute;top:50%;transform:translateY(-50%)}._error_xzvi1_106{margin-top:calc(var(--w-gutter,var(--w-gutter)px) * .25);font-size:calc(var(--w-text,var(--w-text)px) * .75);color:var(--red600)}._inputViewToggle_xzvi1_112{align-items:"center";padding:0;line-height:1;display:inline-flex}
@@ -0,0 +1,13 @@
1
+ import './Input.module.css';//#region src/components/Input/Input.module.scss
2
+ var e = "_wrapper_xzvi1_2", t = "_inputLabel_xzvi1_9", n = "_textarea_xzvi1_24", r = "_inputField_xzvi1_56", i = "_input_xzvi1_9", a = "_inputAdornment_xzvi1_95", o = "_error_xzvi1_106", s = "_inputViewToggle_xzvi1_112", c = {
3
+ wrapper: e,
4
+ inputLabel: t,
5
+ textarea: n,
6
+ inputField: r,
7
+ input: i,
8
+ inputAdornment: a,
9
+ error: o,
10
+ inputViewToggle: s
11
+ };
12
+ //#endregion
13
+ export { c as default, o as error, i as input, a as inputAdornment, r as inputField, t as inputLabel, s as inputViewToggle, n as textarea, e as wrapper };
@@ -0,0 +1,165 @@
1
+ @use "../../styles/global/components/input";
2
+ @use "../../styles/utilities/functions" as u;
3
+
4
+
5
+ @mixin inside-input-label-floating {
6
+ top: -0.5rem;
7
+ left: #{u.width("gutter", 0.125)};
8
+ font-size: #{u.width("text", 0.75)};
9
+ }
10
+
11
+ .wrapper {
12
+ label {
13
+ .inputLabel {
14
+ margin-bottom: #{u.width("gutter", 0.25)};
15
+ }
16
+ }
17
+
18
+ &[data-required="true"] {
19
+ label {
20
+ .inputLabel {
21
+ &::after {
22
+ content: "*";
23
+ color: var(--red700);
24
+ }
25
+ }
26
+ }
27
+ }
28
+
29
+ &[data-label-position="left"] {
30
+ label {
31
+ display: inline-flex;
32
+ align-items: center;
33
+
34
+ .inputLabel {
35
+ width: fit-content;
36
+ margin-right: #{u.width("gutter", 0.75)};
37
+ }
38
+ }
39
+ &.textarea {
40
+ label {
41
+ align-items: flex-start;
42
+ }
43
+ }
44
+ }
45
+
46
+ &[data-label-position="bottom"] {
47
+ label {
48
+ display: inline-flex;
49
+ flex-direction: column-reverse;
50
+ align-items: flex-start;
51
+
52
+ .inputLabel {
53
+ margin-bottom: 0;
54
+ margin-top: #{u.width("gutter", 0.25)};
55
+ }
56
+ }
57
+ }
58
+
59
+ &[data-label-position="right"] {
60
+ label {
61
+ display: inline-flex;
62
+ flex-direction: row-reverse;
63
+ align-items: baseline;
64
+
65
+ .inputLabel {
66
+ margin-left: #{u.width("gutter", 0.25)};
67
+ margin-bottom: 0;
68
+ }
69
+ }
70
+ }
71
+
72
+ &[data-label-position="inside"] {
73
+ @extend %inside-input-label-base;
74
+
75
+ .inputLabel {
76
+ position: absolute;
77
+ background-color: var(--white);
78
+ z-index: 1;
79
+ width: fit-content;
80
+ padding: 0 5px;
81
+ top: #{u.width(gutter, 0.25)};
82
+ left: #{u.width(gutter, 0.25)};
83
+ pointer-events: none;
84
+ transition:
85
+ top 150ms ease,
86
+ left 150ms ease,
87
+ font-size 150ms ease,
88
+ color 150ms ease;
89
+ }
90
+
91
+ > label > .inputField > .input,
92
+ > .input {
93
+ transition: border-color 200ms ease;
94
+ }
95
+
96
+ &:focus-within {
97
+ .inputLabel {
98
+ @include inside-input-label-floating;
99
+ color: var(--blue500);
100
+ }
101
+
102
+ .input {
103
+ border-color: var(--blue500);
104
+ }
105
+
106
+ .input::placeholder {
107
+ opacity: 1;
108
+ }
109
+ }
110
+
111
+ &:has(.input:not(:placeholder-shown)),
112
+ &:has(.input:-webkit-autofill),
113
+ &[data-has-input="true"] {
114
+ .inputLabel {
115
+ @include inside-input-label-floating;
116
+ }
117
+ }
118
+
119
+ .input[type="tel"] {
120
+ width: 100%;
121
+ }
122
+
123
+ .input::placeholder {
124
+ opacity: 0;
125
+ transition: opacity 200ms ease;
126
+ }
127
+ }
128
+
129
+ }
130
+
131
+ .inputField {
132
+ position: relative;
133
+ display: inline-flex;
134
+ align-items: center;
135
+
136
+ &[data-has-end-adornment="true"] {
137
+ > .input {
138
+ width: 100%;
139
+ padding-right: #{u.width("gutter", 1.5)};;
140
+ }
141
+ }
142
+ }
143
+
144
+ .inputAdornment {
145
+ position: absolute;
146
+ right: #{u.width("gutter", 0.5)};;
147
+ top: 50%;
148
+ transform: translateY(-50%);
149
+ margin-top: 0;
150
+ z-index: 1;
151
+ display: inline-flex;
152
+ align-items: center;
153
+ }
154
+
155
+ .error {
156
+ margin-top: #{u.width("gutter", 0.25)};;
157
+ font-size: #{u.width("text", 0.75)};;
158
+ color: var(--red600);
159
+ }
160
+ .inputViewToggle {
161
+ padding: 0;
162
+ display: inline-flex;
163
+ align-items: "center";
164
+ line-height: 1;
165
+ };
@@ -1,4 +1,4 @@
1
- import { TextInputType } from '../styles/utilities/types';
1
+ import { TextInputType } from '../../utilities/types';
2
2
  import { InputProps } from './Input';
3
3
  export type InputPasswordProps = React.ComponentProps<"input"> & {} & Omit<InputProps, "type" | "endAdornment"> & {
4
4
  type?: Extract<TextInputType, "password">;
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { Button as e } from "../Button.esm.js";
3
+ import t from "./Input.module.esm.js";
4
+ import { Input as n } from "./Input.esm.js";
5
+ import { jsx as r } from "react/jsx-runtime";
6
+ import { useState as i } from "react";
7
+ import { ImEye as a, ImEyeBlocked as o } from "react-icons/im";
8
+ //#region src/components/Input/InputPassword.tsx
9
+ var s = ({ visible: n, onToggle: i }) => /* @__PURE__ */ r(e, {
10
+ type: "button",
11
+ variant: "text",
12
+ onClick: i,
13
+ "aria-label": n ? "Hide password" : "Show password",
14
+ "aria-pressed": n,
15
+ className: t.inputViewToggle,
16
+ children: r(n ? a : o, { size: 16 })
17
+ }), c = ({ type: e = "password", ...t }) => {
18
+ let [a, o] = i(!1), c = a ? "text" : e;
19
+ return /* @__PURE__ */ r(n, {
20
+ ...t,
21
+ type: c,
22
+ endAdornment: /* @__PURE__ */ r(s, {
23
+ visible: a,
24
+ onToggle: () => o((e) => !e)
25
+ })
26
+ });
27
+ };
28
+ //#endregion
29
+ export { c as InputPassword };
@@ -0,0 +1,11 @@
1
+ import { LabelPosition } from '../../utilities/types';
2
+ export type LabeledInput = {
3
+ label?: string | React.ReactNode;
4
+ labelPosition?: LabelPosition;
5
+ error?: string | boolean | React.ReactNode;
6
+ required?: boolean;
7
+ styles?: React.CSSProperties;
8
+ endAdornment?: React.ReactNode;
9
+ };
10
+ export type InputWrapperProps = React.ComponentProps<"input" | "textarea"> & LabeledInput;
11
+ export declare const InputWrapper: React.FC<InputWrapperProps>;
@@ -0,0 +1,28 @@
1
+ "use client";
2
+ import { isEmpty as e } from "../../utilities/validations.esm.js";
3
+ import t from "./Input.module.esm.js";
4
+ import n from "clsx";
5
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
+ //#region src/components/Input/InputWrapper.tsx
7
+ var a = ({ label: a, labelPosition: o = "top", required: s = !1, error: c, styles: l, className: u, style: d, children: f, value: p, defaultValue: m }) => {
8
+ let h = !e(p) || !e(m), g = e(l) ? void 0 : l;
9
+ return /* @__PURE__ */ i("div", {
10
+ "data-label-position": o,
11
+ "data-required": s,
12
+ "data-has-input": h,
13
+ className: n(t.wrapper, u),
14
+ style: {
15
+ ...g,
16
+ ...d
17
+ },
18
+ children: [e(a) ? f : /* @__PURE__ */ i("label", { children: [o !== "hidden" && /* @__PURE__ */ r("div", {
19
+ className: t.inputLabel,
20
+ children: a
21
+ }), f] }), !e(c) && /* @__PURE__ */ r("div", {
22
+ className: t.error,
23
+ children: c
24
+ })]
25
+ });
26
+ };
27
+ //#endregion
28
+ export { a as InputWrapper };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Input as e } from "./Input.esm.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
- //#region src/components/RadioButton.tsx
4
+ //#region src/components/Input/RadioButton.tsx
5
5
  var n = ({ type: n = "radio", labelPosition: r = "right", ...i }) => /* @__PURE__ */ t(e, {
6
6
  type: n,
7
7
  labelPosition: r,
@@ -0,0 +1,3 @@
1
+ import { LabeledInput } from './InputWrapper';
2
+ export type TextareaProps = React.ComponentProps<"textarea"> & LabeledInput;
3
+ export declare const Textarea: React.FC<TextareaProps>;
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import e from "./Input.module.esm.js";
3
+ import { InputWrapper as t } from "./InputWrapper.esm.js";
4
+ import n from "clsx";
5
+ import { jsx as r } from "react/jsx-runtime";
6
+ import { useId as i } from "react";
7
+ //#region src/components/Input/Textarea.tsx
8
+ var a = ({ labelPosition: a = "top", id: o, label: s, error: c, required: l, className: u, styles: d, ...f }) => {
9
+ let p = i(), m = o || p;
10
+ return /* @__PURE__ */ r(t, {
11
+ label: s,
12
+ className: n(e.textarea, u),
13
+ labelPosition: a,
14
+ error: c,
15
+ required: l,
16
+ styles: d,
17
+ children: /* @__PURE__ */ r("textarea", {
18
+ id: m,
19
+ className: n(e.input),
20
+ ...f
21
+ })
22
+ });
23
+ };
24
+ //#endregion
25
+ export { a as Textarea };
@@ -3,19 +3,12 @@ import { isEmpty as e } from "../utilities/validations.esm.js";
3
3
  import { color as t } from "../styles/utilities/color.esm.js";
4
4
  import { Button as n } from "./Button.esm.js";
5
5
  import r from "./Modal.module.esm.js";
6
- import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
7
- import s from "react";
8
- import { LuX as c } from "react-icons/lu";
6
+ import i from "clsx";
7
+ import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
8
+ import c from "react";
9
+ import { LuX as l } from "react-icons/lu";
9
10
  //#region src/components/Modal.tsx
10
- var l = {
11
- textDecoration: "none",
12
- height: 30,
13
- width: 30,
14
- borderRadius: "50%",
15
- padding: 0,
16
- display: "inline-flex",
17
- justifyContent: "center"
18
- }, u = class extends s.PureComponent {
11
+ var u = class extends c.PureComponent {
19
12
  state = { isClosing: !1 };
20
13
  onDismiss = () => {
21
14
  this.props.onDismiss && (this.setState({ isClosing: !0 }), setTimeout(() => {
@@ -23,39 +16,38 @@ var l = {
23
16
  }, 280));
24
17
  };
25
18
  onClickBackground = () => {
26
- (this.props.backgroundDismiss || !0) === !0 && this.onDismiss();
19
+ (this.props.backgroundDismiss ?? !0) === !0 && this.onDismiss();
27
20
  };
28
21
  render() {
29
- let s = e(this.props.styles) ? void 0 : this.props.styles;
30
- return this.props.visible ? /* @__PURE__ */ o("div", {
22
+ let c = e(this.props.styles) ? void 0 : this.props.styles, u = this.props.type || "dialog";
23
+ return this.props.visible ? /* @__PURE__ */ s("div", {
31
24
  className: r.wrapper,
32
- style: s,
33
- children: [/* @__PURE__ */ o("div", {
34
- className: r.content,
35
- "data-type": this.props.type || "dialog",
25
+ style: c,
26
+ children: [/* @__PURE__ */ s("div", {
27
+ className: i(r.content, r[u]),
36
28
  "data-is-closing": this.state.isClosing,
37
29
  children: [
38
- /* @__PURE__ */ o("header", { children: [this.props.header && /* @__PURE__ */ a(i, { children: this.props.header }), !this.props.hideDismissIcon && /* @__PURE__ */ a(n, {
30
+ /* @__PURE__ */ s("header", { children: [this.props.header && /* @__PURE__ */ o(a, { children: this.props.header }), !this.props.hideDismissIcon && /* @__PURE__ */ o(n, {
39
31
  variant: "primary",
40
- styles: l,
32
+ className: r.closeModal,
41
33
  onClick: this.onDismiss,
42
- children: /* @__PURE__ */ a(c, {
34
+ children: /* @__PURE__ */ o(l, {
43
35
  fill: t("white"),
44
36
  size: 18
45
37
  })
46
38
  })] }),
47
- /* @__PURE__ */ a("section", { children: this.props.children }),
48
- this.props.footer && /* @__PURE__ */ a("footer", {
39
+ /* @__PURE__ */ o("section", { children: this.props.children }),
40
+ this.props.footer && /* @__PURE__ */ o("footer", {
49
41
  className: r.actionContainer,
50
42
  children: this.props.footer
51
43
  })
52
44
  ]
53
- }), /* @__PURE__ */ a("div", {
45
+ }), /* @__PURE__ */ o("div", {
54
46
  className: r.background,
55
47
  "data-is-closing": this.state.isClosing,
56
48
  onClick: this.onClickBackground
57
49
  })]
58
- }) : /* @__PURE__ */ a(i, {});
50
+ }) : /* @__PURE__ */ o(a, {});
59
51
  }
60
52
  };
61
53
  //#endregion