tembro 2.1.8 → 2.1.10

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 (192) hide show
  1. package/dist/components/actions/button-group.cjs +1 -1
  2. package/dist/components/actions/button-group.js +0 -1
  3. package/dist/components/form/form-date-range-input.cjs +1 -1
  4. package/dist/components/form/form-date-range-input.d.ts +1 -1
  5. package/dist/components/form/form-date-range-input.js +1 -1
  6. package/dist/components/form/form-input.cjs +1 -1
  7. package/dist/components/form/form-input.d.ts +7 -7
  8. package/dist/components/form/form-input.js +11 -11
  9. package/dist/components/inputs/index.cjs +1 -1
  10. package/dist/components/inputs/index.d.ts +0 -14
  11. package/dist/components/inputs/index.js +9 -23
  12. package/dist/components/inputs/public.cjs +1 -1
  13. package/dist/components/inputs/public.d.ts +0 -14
  14. package/dist/components/inputs/public.js +9 -23
  15. package/dist/components/ui/input/chrome.cjs +1 -0
  16. package/dist/components/{inputs/input-chrome.js → ui/input/chrome.js} +2 -2
  17. package/dist/components/ui/input/clearable.cjs +1 -0
  18. package/dist/components/{inputs/clearable-input.d.ts → ui/input/clearable.d.ts} +1 -1
  19. package/dist/components/{inputs/clearable-input.js → ui/input/clearable.js} +4 -4
  20. package/dist/components/{inputs/date-range-input.cjs → ui/input/date-range.cjs} +1 -1
  21. package/dist/components/{inputs/date-range-input.d.ts → ui/input/date-range.d.ts} +1 -1
  22. package/dist/components/{inputs/date-range-input.js → ui/input/date-range.js} +3 -3
  23. package/dist/components/ui/input/date.cjs +1 -0
  24. package/dist/components/{inputs/date-input.d.ts → ui/input/date.d.ts} +1 -1
  25. package/dist/components/{inputs/date-input.js → ui/input/date.js} +3 -3
  26. package/dist/components/ui/input/decorator.cjs +1 -0
  27. package/dist/components/{inputs/input-decorator.js → ui/input/decorator.js} +3 -3
  28. package/dist/components/ui/input/index.cjs +1 -1
  29. package/dist/components/ui/input/index.d.ts +10 -10
  30. package/dist/components/ui/input/index.js +13 -13
  31. package/dist/components/ui/input/masked.cjs +1 -0
  32. package/dist/components/{inputs/masked-input.d.ts → ui/input/masked.d.ts} +1 -1
  33. package/dist/components/{inputs/masked-input.js → ui/input/masked.js} +3 -3
  34. package/dist/components/ui/input/money.cjs +1 -0
  35. package/dist/components/{inputs/money-input.js → ui/input/money.js} +5 -5
  36. package/dist/components/ui/input/number.cjs +1 -0
  37. package/dist/components/{inputs/number-input.d.ts → ui/input/number.d.ts} +1 -1
  38. package/dist/components/{inputs/number-input.js → ui/input/number.js} +3 -3
  39. package/dist/components/{inputs → ui/input}/numeric-value.js +1 -1
  40. package/dist/components/ui/input/password.cjs +1 -0
  41. package/dist/components/{inputs/password-input.d.ts → ui/input/password.d.ts} +1 -1
  42. package/dist/components/{inputs/password-input.js → ui/input/password.js} +2 -2
  43. package/dist/components/ui/input/phone.cjs +1 -0
  44. package/dist/components/{inputs/phone-input.d.ts → ui/input/phone.d.ts} +1 -1
  45. package/dist/components/{inputs/phone-input.js → ui/input/phone.js} +2 -2
  46. package/dist/components/ui/input/quantity.cjs +1 -0
  47. package/dist/components/{inputs/quantity-input.js → ui/input/quantity.js} +6 -6
  48. package/dist/components/ui/input/search.cjs +1 -0
  49. package/dist/components/{inputs/search-input.d.ts → ui/input/search.d.ts} +1 -1
  50. package/dist/components/{inputs/search-input.js → ui/input/search.js} +2 -2
  51. package/dist/components/{inputs/input-value.js → ui/input/value.js} +1 -1
  52. package/dist/index.cjs +1 -1
  53. package/dist/index.js +124 -138
  54. package/dist/public-component-surface.cjs +1 -1
  55. package/dist/public-component-surface.js +0 -5
  56. package/dist/showcase/fallback.cjs +3 -3
  57. package/dist/showcase/fallback.js +119 -118
  58. package/dist/showcase/premium/combobox/mock.cjs +4 -3
  59. package/dist/showcase/premium/combobox/mock.js +2 -2
  60. package/dist/showcase/premium/combobox/showcase.cjs +1 -1
  61. package/dist/showcase/premium/combobox/showcase.js +2 -2
  62. package/dist/showcase/premium/date-input/mock.cjs +4 -3
  63. package/dist/showcase/premium/date-input/mock.js +2 -2
  64. package/dist/showcase/premium/date-input/showcase.cjs +1 -1
  65. package/dist/showcase/premium/date-input/showcase.js +2 -1
  66. package/dist/showcase/premium/date-range-input/mock.cjs +4 -3
  67. package/dist/showcase/premium/date-range-input/mock.js +2 -2
  68. package/dist/showcase/premium/date-range-input/showcase.cjs +1 -1
  69. package/dist/showcase/premium/date-range-input/showcase.js +2 -1
  70. package/dist/showcase/premium/masked-input/mock.cjs +4 -3
  71. package/dist/showcase/premium/masked-input/mock.js +2 -2
  72. package/dist/showcase/premium/masked-input/showcase.cjs +1 -1
  73. package/dist/showcase/premium/masked-input/showcase.js +2 -1
  74. package/dist/showcase/premium/money-input/mock.cjs +4 -3
  75. package/dist/showcase/premium/money-input/mock.js +2 -2
  76. package/dist/showcase/premium/money-input/showcase.cjs +1 -1
  77. package/dist/showcase/premium/money-input/showcase.js +2 -1
  78. package/dist/showcase/premium/number-input/mock.cjs +5 -7
  79. package/dist/showcase/premium/number-input/mock.js +2 -2
  80. package/dist/showcase/premium/number-input/showcase.cjs +1 -1
  81. package/dist/showcase/premium/number-input/showcase.js +2 -1
  82. package/dist/showcase/premium/password-input/mock.cjs +3 -2
  83. package/dist/showcase/premium/password-input/mock.js +1 -1
  84. package/dist/showcase/premium/password-input/showcase.cjs +1 -1
  85. package/dist/showcase/premium/password-input/showcase.js +2 -1
  86. package/dist/showcase/premium/phone-input/mock.cjs +5 -4
  87. package/dist/showcase/premium/phone-input/mock.js +2 -2
  88. package/dist/showcase/premium/phone-input/showcase.cjs +1 -1
  89. package/dist/showcase/premium/phone-input/showcase.js +2 -1
  90. package/dist/showcase/premium/quantity-input/mock.cjs +4 -3
  91. package/dist/showcase/premium/quantity-input/mock.js +2 -2
  92. package/dist/showcase/premium/quantity-input/showcase.cjs +1 -1
  93. package/dist/showcase/premium/quantity-input/showcase.js +2 -1
  94. package/dist/showcase/premium/search-input/mock.cjs +3 -2
  95. package/dist/showcase/premium/search-input/mock.js +1 -1
  96. package/dist/showcase/premium/search-input/showcase.cjs +1 -1
  97. package/dist/showcase/premium/search-input/showcase.js +2 -1
  98. package/dist/showcase/premium/simple-select/mock.cjs +3 -3
  99. package/dist/showcase/premium/simple-select/mock.js +2 -2
  100. package/dist/showcase/premium/simple-select/showcase.cjs +1 -1
  101. package/dist/showcase/premium/simple-select/showcase.js +1 -1
  102. package/dist/showcase/registry-specific.cjs +1 -1
  103. package/dist/showcase/registry-specific.js +92 -92
  104. package/dist/showcase/render-registry-preview.cjs +1 -1
  105. package/dist/showcase/render-registry-preview.js +214 -215
  106. package/dist/showcase/tembro-registry.json.cjs +1 -1
  107. package/dist/showcase/tembro-registry.json.js +2 -3
  108. package/package.json +1 -1
  109. package/packages/cli/dist/index.cjs +18 -18
  110. package/packages/cli/vendor/src/components/actions/button-group.tsx +0 -1
  111. package/packages/cli/vendor/src/components/form/form-date-range-input.tsx +5 -5
  112. package/packages/cli/vendor/src/components/form/form-input.tsx +7 -7
  113. package/packages/cli/vendor/src/components/inputs/index.ts +0 -14
  114. package/packages/cli/vendor/src/components/inputs/public.ts +0 -19
  115. package/packages/cli/vendor/src/components/{inputs/clearable-input.tsx → ui/input/clearable.tsx} +2 -2
  116. package/packages/cli/vendor/src/components/{inputs/date-range-input.tsx → ui/input/date-range.tsx} +1 -1
  117. package/packages/cli/vendor/src/components/{inputs/date-input.tsx → ui/input/date.tsx} +2 -2
  118. package/packages/cli/vendor/src/components/ui/input/index.tsx +11 -11
  119. package/packages/cli/vendor/src/components/{inputs/masked-input.tsx → ui/input/masked.tsx} +2 -2
  120. package/packages/cli/vendor/src/components/{inputs/money-input.tsx → ui/input/money.tsx} +3 -3
  121. package/packages/cli/vendor/src/components/{inputs/number-input.tsx → ui/input/number.tsx} +3 -3
  122. package/packages/cli/vendor/src/components/{inputs/password-input.tsx → ui/input/password.tsx} +1 -1
  123. package/packages/cli/vendor/src/components/{inputs/phone-input.tsx → ui/input/phone.tsx} +1 -1
  124. package/packages/cli/vendor/src/components/{inputs/quantity-input.tsx → ui/input/quantity.tsx} +3 -3
  125. package/packages/cli/vendor/src/components/{inputs/search-input.tsx → ui/input/search.tsx} +1 -1
  126. package/packages/cli/vendor/src/public-component-surface.ts +0 -1
  127. package/packages/cli/vendor/src/showcase/fallback.tsx +4 -6
  128. package/packages/cli/vendor/src/showcase/premium/combobox/mock.ts +4 -3
  129. package/packages/cli/vendor/src/showcase/premium/combobox/showcase.tsx +3 -3
  130. package/packages/cli/vendor/src/showcase/premium/date-input/mock.ts +4 -3
  131. package/packages/cli/vendor/src/showcase/premium/date-input/showcase.tsx +3 -2
  132. package/packages/cli/vendor/src/showcase/premium/date-range-input/mock.ts +4 -3
  133. package/packages/cli/vendor/src/showcase/premium/date-range-input/showcase.tsx +3 -2
  134. package/packages/cli/vendor/src/showcase/premium/masked-input/mock.ts +4 -3
  135. package/packages/cli/vendor/src/showcase/premium/masked-input/showcase.tsx +3 -2
  136. package/packages/cli/vendor/src/showcase/premium/money-input/mock.ts +4 -3
  137. package/packages/cli/vendor/src/showcase/premium/money-input/showcase.tsx +3 -2
  138. package/packages/cli/vendor/src/showcase/premium/number-input/mock.ts +5 -7
  139. package/packages/cli/vendor/src/showcase/premium/number-input/showcase.tsx +2 -2
  140. package/packages/cli/vendor/src/showcase/premium/password-input/mock.ts +3 -2
  141. package/packages/cli/vendor/src/showcase/premium/password-input/showcase.tsx +3 -2
  142. package/packages/cli/vendor/src/showcase/premium/phone-input/mock.ts +5 -4
  143. package/packages/cli/vendor/src/showcase/premium/phone-input/showcase.tsx +4 -3
  144. package/packages/cli/vendor/src/showcase/premium/quantity-input/mock.ts +4 -3
  145. package/packages/cli/vendor/src/showcase/premium/quantity-input/showcase.tsx +3 -2
  146. package/packages/cli/vendor/src/showcase/premium/search-input/mock.ts +3 -2
  147. package/packages/cli/vendor/src/showcase/premium/search-input/showcase.tsx +3 -2
  148. package/packages/cli/vendor/src/showcase/premium/simple-select/mock.ts +3 -3
  149. package/packages/cli/vendor/src/showcase/premium/simple-select/showcase.tsx +3 -3
  150. package/packages/cli/vendor/src/showcase/registry-specific.tsx +1 -2
  151. package/packages/cli/vendor/src/showcase/render-registry-preview.tsx +2 -4
  152. package/packages/cli/vendor/src/showcase/tembro-registry.json +1 -3
  153. package/registry.json +1 -3
  154. package/dist/components/inputs/clearable-input.cjs +0 -1
  155. package/dist/components/inputs/color-input.cjs +0 -1
  156. package/dist/components/inputs/color-input.d.ts +0 -11
  157. package/dist/components/inputs/color-input.js +0 -42
  158. package/dist/components/inputs/combobox.cjs +0 -1
  159. package/dist/components/inputs/combobox.d.ts +0 -29
  160. package/dist/components/inputs/combobox.js +0 -113
  161. package/dist/components/inputs/date-input.cjs +0 -1
  162. package/dist/components/inputs/input-chrome.cjs +0 -1
  163. package/dist/components/inputs/input-decorator.cjs +0 -1
  164. package/dist/components/inputs/masked-input.cjs +0 -1
  165. package/dist/components/inputs/money-input.cjs +0 -1
  166. package/dist/components/inputs/number-input.cjs +0 -1
  167. package/dist/components/inputs/password-input.cjs +0 -1
  168. package/dist/components/inputs/phone-input.cjs +0 -1
  169. package/dist/components/inputs/quantity-input.cjs +0 -1
  170. package/dist/components/inputs/quantity-stepper.cjs +0 -1
  171. package/dist/components/inputs/quantity-stepper.d.ts +0 -12
  172. package/dist/components/inputs/quantity-stepper.js +0 -52
  173. package/dist/components/inputs/search-input.cjs +0 -1
  174. package/dist/components/inputs/simple-select.cjs +0 -1
  175. package/dist/components/inputs/simple-select.d.ts +0 -13
  176. package/dist/components/inputs/simple-select.js +0 -8
  177. package/packages/cli/vendor/src/components/inputs/color-input.tsx +0 -49
  178. package/packages/cli/vendor/src/components/inputs/combobox.tsx +0 -180
  179. package/packages/cli/vendor/src/components/inputs/quantity-stepper.tsx +0 -51
  180. package/packages/cli/vendor/src/components/inputs/simple-select.tsx +0 -23
  181. /package/dist/components/{inputs/input-chrome.d.ts → ui/input/chrome.d.ts} +0 -0
  182. /package/dist/components/{inputs/input-decorator.d.ts → ui/input/decorator.d.ts} +0 -0
  183. /package/dist/components/{inputs/money-input.d.ts → ui/input/money.d.ts} +0 -0
  184. /package/dist/components/{inputs → ui/input}/numeric-value.cjs +0 -0
  185. /package/dist/components/{inputs → ui/input}/numeric-value.d.ts +0 -0
  186. /package/dist/components/{inputs/quantity-input.d.ts → ui/input/quantity.d.ts} +0 -0
  187. /package/dist/components/{inputs/input-value.cjs → ui/input/value.cjs} +0 -0
  188. /package/dist/components/{inputs/input-value.d.ts → ui/input/value.d.ts} +0 -0
  189. /package/packages/cli/vendor/src/components/{inputs/input-chrome.tsx → ui/input/chrome.tsx} +0 -0
  190. /package/packages/cli/vendor/src/components/{inputs/input-decorator.tsx → ui/input/decorator.tsx} +0 -0
  191. /package/packages/cli/vendor/src/components/{inputs → ui/input}/numeric-value.ts +0 -0
  192. /package/packages/cli/vendor/src/components/{inputs/input-value.ts → ui/input/value.ts} +0 -0
@@ -1,11 +1,12 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import { useState } from "react"
2
- import { DateInput } from "tembro"
2
+ import { Input } from "tembro"
3
3
 
4
4
  export function Example() {
5
5
  const [value, setValue] = useState("2026-06-19")
6
6
 
7
7
  return (
8
- <DateInput
8
+ <Input
9
+ kind="date"
9
10
  value={value}
10
11
  onValueChange={setValue}
11
12
  min="2026-06-01"
@@ -13,4 +14,4 @@ export function Example() {
13
14
  placeholder="YYYY-MM-DD"
14
15
  />
15
16
  )
16
- }`,htmlCode:`<label for="date">Date</label><input id="date" type="text" value="2026-06-19" placeholder="YYYY-MM-DD" />`,cliCommand:`npx tembro add date-input`,highlights:[`ISO-like string format assumptions`,`min/max constraints`,`Controlled editing`,`Clear disabled behavior`],relatedBlockSlugs:[`dashboard-starter`,`crm-dashboard`,`settings-form`],scenarios:[{title:`Birth date`,description:`Enforce a valid date window with min/max.`},{title:`Report filter`,description:`Use as single date boundary for dashboards.`},{title:`Default timezone`,description:`Keep string values and normalize at API boundary.`},{title:`Locked fields`,description:`Disable editing during restricted status windows.`}],capabilityNotes:[`Store normalized date string outside the component for stable API integration.`,`Show explicit range with helper text when min/max are enforced.`,`Validate parsed date and format on submit as an app-level safety layer.`,`Align placeholder format with your backend contract (ISO/locale).`]};exports.dateInputMock=e;
17
+ }`,htmlCode:`<label for="date">Date</label><input id="date" type="text" value="2026-06-19" placeholder="YYYY-MM-DD" />`,cliCommand:`npx tembro add input`,highlights:[`ISO-like string format assumptions`,`min/max constraints`,`Controlled editing`,`Clear disabled behavior`],relatedBlockSlugs:[`dashboard-starter`,`crm-dashboard`,`settings-form`],scenarios:[{title:`Birth date`,description:`Enforce a valid date window with min/max.`},{title:`Report filter`,description:`Use as single date boundary for dashboards.`},{title:`Default timezone`,description:`Keep string values and normalize at API boundary.`},{title:`Locked fields`,description:`Disable editing during restricted status windows.`}],capabilityNotes:[`Store normalized date string outside the component for stable API integration.`,`Show explicit range with helper text when min/max are enforced.`,`Validate parsed date and format on submit as an app-level safety layer.`,`Align placeholder format with your backend contract (ISO/locale).`]};exports.dateInputMock=e;
@@ -1,8 +1,8 @@
1
1
  //#region src/showcase/premium/date-input/mock.ts
2
2
  var e = {
3
- code: "import { useState } from \"react\"\nimport { DateInput } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState(\"2026-06-19\")\n\n return (\n <DateInput\n value={value}\n onValueChange={setValue}\n min=\"2026-06-01\"\n max=\"2026-12-31\"\n placeholder=\"YYYY-MM-DD\"\n />\n )\n}",
3
+ code: "import { useState } from \"react\"\nimport { Input } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState(\"2026-06-19\")\n\n return (\n <Input\n kind=\"date\"\n value={value}\n onValueChange={setValue}\n min=\"2026-06-01\"\n max=\"2026-12-31\"\n placeholder=\"YYYY-MM-DD\"\n />\n )\n}",
4
4
  htmlCode: "<label for=\"date\">Date</label><input id=\"date\" type=\"text\" value=\"2026-06-19\" placeholder=\"YYYY-MM-DD\" />",
5
- cliCommand: "npx tembro add date-input",
5
+ cliCommand: "npx tembro add input",
6
6
  highlights: [
7
7
  "ISO-like string format assumptions",
8
8
  "min/max constraints",
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/inputs/date-input.cjs");let t=require("react"),n=require("react/jsx-runtime");function r({mode:r}){let[i,a]=(0,t.useState)(`2026-06-19`);return(0,n.jsxs)(`div`,{className:`space-y-4`,children:[(0,n.jsx)(e.DateInput,{value:i,onValueChange:e=>a(e),min:`2026-06-01`,max:`2026-12-31`}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Value: `,i||`—`]}),(0,n.jsxs)(`p`,{className:`aui-text-muted text-sm`,children:[`Mode: `,r]})]})}exports.DateInputShowcase=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/ui/input/index.cjs");let t=require("react"),n=require("react/jsx-runtime");function r({mode:r}){let[i,a]=(0,t.useState)(`2026-06-19`);return(0,n.jsxs)(`div`,{className:`space-y-4`,children:[(0,n.jsx)(e.Input,{kind:`date`,value:i,onValueChange:e=>a(e),min:`2026-06-01`,max:`2026-12-31`}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Value: `,i||`—`]}),(0,n.jsxs)(`p`,{className:`aui-text-muted text-sm`,children:[`Mode: `,r]})]})}exports.DateInputShowcase=r;
@@ -1,4 +1,4 @@
1
- import { DateInput as e } from "../../../components/inputs/date-input.js";
1
+ import { Input as e } from "../../../components/ui/input/index.js";
2
2
  import { useState as t } from "react";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  //#region src/showcase/premium/date-input/showcase.tsx
@@ -8,6 +8,7 @@ function i({ mode: i }) {
8
8
  className: "space-y-4",
9
9
  children: [
10
10
  /* @__PURE__ */ n(e, {
11
+ kind: "date",
11
12
  value: a,
12
13
  onValueChange: (e) => o(e),
13
14
  min: "2026-06-01",
@@ -1,11 +1,12 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import { useState } from "react"
2
- import { DateRangeInput } from "@/index"
2
+ import { Input } from "tembro"
3
3
 
4
4
  export function Example() {
5
5
  const [value, setValue] = useState({ from: "2026-06-01", to: "2026-06-30" })
6
6
 
7
7
  return (
8
- <DateRangeInput
8
+ <Input
9
+ kind="date-range"
9
10
  value={value}
10
11
  onValueChange={(nextValue) => setValue({ from: nextValue.from ?? "", to: nextValue.to ?? "" })}
11
12
  fromInputProps={{ min: "2026-06-01" }}
@@ -13,4 +14,4 @@ export function Example() {
13
14
  required
14
15
  />
15
16
  )
16
- }`,htmlCode:`<label for="date-range">Date range</label><input id="date-range" type="text" value="2026-06-01 to 2026-06-30" />`,cliCommand:`npx tembro add date-range-input`,highlights:[`from/to object contract`,`range behavior`,`min/max boundaries`,`single source of truth formatting`],relatedBlockSlugs:[`dashboard-starter`,`crm-dashboard`,`users-table`],scenarios:[{title:`Billing period`,description:`Keep report windows with explicit start/end boundaries.`},{title:`Dashboard filters`,description:`Use range to fetch metrics for a period.`},{title:`Date lock`,description:`Enforce required bounds while user is in restricted flow.`},{title:`Export window`,description:`Share range object to backend for date-interval export.`}],capabilityNotes:[`Treat partial ranges as invalid until both ends are present.`,`Validate from <= to at app layer to avoid inverted ranges.`,`Normalize all range values to canonical storage format.`,`Show user hint text for format and required bounds.`]};exports.dateRangeInputMock=e;
17
+ }`,htmlCode:`<label for="date-range">Date range</label><input id="date-range" type="text" value="2026-06-01 to 2026-06-30" />`,cliCommand:`npx tembro add input`,highlights:[`from/to object contract`,`range behavior`,`min/max boundaries`,`single source of truth formatting`],relatedBlockSlugs:[`dashboard-starter`,`crm-dashboard`,`users-table`],scenarios:[{title:`Billing period`,description:`Keep report windows with explicit start/end boundaries.`},{title:`Dashboard filters`,description:`Use range to fetch metrics for a period.`},{title:`Date lock`,description:`Enforce required bounds while user is in restricted flow.`},{title:`Export window`,description:`Share range object to backend for date-interval export.`}],capabilityNotes:[`Treat partial ranges as invalid until both ends are present.`,`Validate from <= to at app layer to avoid inverted ranges.`,`Normalize all range values to canonical storage format.`,`Show user hint text for format and required bounds.`]};exports.dateRangeInputMock=e;
@@ -1,8 +1,8 @@
1
1
  //#region src/showcase/premium/date-range-input/mock.ts
2
2
  var e = {
3
- code: "import { useState } from \"react\"\nimport { DateRangeInput } from \"@/index\"\n\nexport function Example() {\n const [value, setValue] = useState({ from: \"2026-06-01\", to: \"2026-06-30\" })\n\n return (\n <DateRangeInput\n value={value}\n onValueChange={(nextValue) => setValue({ from: nextValue.from ?? \"\", to: nextValue.to ?? \"\" })}\n fromInputProps={{ min: \"2026-06-01\" }}\n toInputProps={{ max: \"2026-12-31\" }}\n required\n />\n )\n}",
3
+ code: "import { useState } from \"react\"\nimport { Input } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState({ from: \"2026-06-01\", to: \"2026-06-30\" })\n\n return (\n <Input\n kind=\"date-range\"\n value={value}\n onValueChange={(nextValue) => setValue({ from: nextValue.from ?? \"\", to: nextValue.to ?? \"\" })}\n fromInputProps={{ min: \"2026-06-01\" }}\n toInputProps={{ max: \"2026-12-31\" }}\n required\n />\n )\n}",
4
4
  htmlCode: "<label for=\"date-range\">Date range</label><input id=\"date-range\" type=\"text\" value=\"2026-06-01 to 2026-06-30\" />",
5
- cliCommand: "npx tembro add date-range-input",
5
+ cliCommand: "npx tembro add input",
6
6
  highlights: [
7
7
  "from/to object contract",
8
8
  "range behavior",
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/inputs/date-range-input.cjs");let t=require("react"),n=require("react/jsx-runtime");function r({mode:r}){let[i,a]=(0,t.useState)({from:`2026-06-01`,to:`2026-06-30`});return(0,n.jsxs)(`div`,{className:`space-y-4`,children:[(0,n.jsx)(e.DateRangeInput,{value:i,onValueChange:e=>a({from:e.from??``,to:e.to??``}),fromInputProps:{min:`2026-06-01`},toInputProps:{max:`2026-12-31`}}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Range: `,i.from,` → `,i.to]}),(0,n.jsxs)(`p`,{className:`aui-text-muted text-sm`,children:[`Mode: `,r]})]})}exports.DateRangeInputShowcase=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/ui/input/index.cjs");let t=require("react"),n=require("react/jsx-runtime");function r({mode:r}){let[i,a]=(0,t.useState)({from:`2026-06-01`,to:`2026-06-30`});return(0,n.jsxs)(`div`,{className:`space-y-4`,children:[(0,n.jsx)(e.Input,{kind:`date-range`,value:i,onValueChange:e=>a({from:e.from??``,to:e.to??``}),fromInputProps:{min:`2026-06-01`},toInputProps:{max:`2026-12-31`}}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Range: `,i.from,` → `,i.to]}),(0,n.jsxs)(`p`,{className:`aui-text-muted text-sm`,children:[`Mode: `,r]})]})}exports.DateRangeInputShowcase=r;
@@ -1,4 +1,4 @@
1
- import { DateRangeInput as e } from "../../../components/inputs/date-range-input.js";
1
+ import { Input as e } from "../../../components/ui/input/index.js";
2
2
  import { useState as t } from "react";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  //#region src/showcase/premium/date-range-input/showcase.tsx
@@ -11,6 +11,7 @@ function i({ mode: i }) {
11
11
  className: "space-y-4",
12
12
  children: [
13
13
  /* @__PURE__ */ n(e, {
14
+ kind: "date-range",
14
15
  value: a,
15
16
  onValueChange: (e) => o({
16
17
  from: e.from ?? "",
@@ -1,11 +1,12 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import { useState } from "react"
2
- import { MaskedInput } from "tembro"
2
+ import { Input } from "tembro"
3
3
 
4
4
  export function Example() {
5
5
  const [value, setValue] = useState("AA-123")
6
6
 
7
7
  return (
8
- <MaskedInput
8
+ <Input
9
+ kind="masked"
9
10
  value={value}
10
11
  onValueChange={(nextValue) => setValue(nextValue)}
11
12
  mask={(raw: string) => raw.toUpperCase().slice(0, 6).replace(/(.{3})(?=.)/, "$1-")}
@@ -13,4 +14,4 @@ export function Example() {
13
14
  />
14
15
  )
15
16
  }
16
- `,htmlCode:`<label for="masked">Referral code</label><input id="masked" type="text" value="AA-123" placeholder="AA-123" />`,cliCommand:`npx tembro add masked-input`,highlights:[`Mask callback runs on each edit`,`Uppercase and slicing are explicit formatting assumptions`,`Raw value assumptions should be mirrored in validation and submit payloads`,`Use a deterministic placeholder that matches the mask contract`],relatedBlockSlugs:[`settings-form`,`crm-dashboard`,`auth-sign-in`],scenarios:[{title:`Referral codes`,description:`Use fixed pattern for short identifiers while typing.`},{title:`License keys`,description:`Apply grouping with a strict uppercase format and controlled length.`},{title:`Display normalization`,description:`Normalize display while preserving form-level expectations.`},{title:`Validation gate`,description:`Reject submission when value shape does not match mask contract.`}],capabilityNotes:[`Document whether callback receives raw text or already masked text.`,`If you need raw payload, sanitize before submit and keep canonical storage layer separate.`,`Use one mask function source for both form and API submission paths.`,`Treat partially typed values as invalid until user completion conditions are met.`]};exports.maskedInputMock=e;
17
+ `,htmlCode:`<label for="masked">Referral code</label><input id="masked" type="text" value="AA-123" placeholder="AA-123" />`,cliCommand:`npx tembro add input`,highlights:[`Mask callback runs on each edit`,`Uppercase and slicing are explicit formatting assumptions`,`Raw value assumptions should be mirrored in validation and submit payloads`,`Use a deterministic placeholder that matches the mask contract`],relatedBlockSlugs:[`settings-form`,`crm-dashboard`,`auth-sign-in`],scenarios:[{title:`Referral codes`,description:`Use fixed pattern for short identifiers while typing.`},{title:`License keys`,description:`Apply grouping with a strict uppercase format and controlled length.`},{title:`Display normalization`,description:`Normalize display while preserving form-level expectations.`},{title:`Validation gate`,description:`Reject submission when value shape does not match mask contract.`}],capabilityNotes:[`Document whether callback receives raw text or already masked text.`,`If you need raw payload, sanitize before submit and keep canonical storage layer separate.`,`Use one mask function source for both form and API submission paths.`,`Treat partially typed values as invalid until user completion conditions are met.`]};exports.maskedInputMock=e;
@@ -1,8 +1,8 @@
1
1
  //#region src/showcase/premium/masked-input/mock.ts
2
2
  var e = {
3
- code: "import { useState } from \"react\"\nimport { MaskedInput } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState(\"AA-123\")\n\n return (\n <MaskedInput\n value={value}\n onValueChange={(nextValue) => setValue(nextValue)}\n mask={(raw: string) => raw.toUpperCase().slice(0, 6).replace(/(.{3})(?=.)/, \"$1-\")}\n placeholder=\"AA-123\"\n />\n )\n}\n",
3
+ code: "import { useState } from \"react\"\nimport { Input } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState(\"AA-123\")\n\n return (\n <Input\n kind=\"masked\"\n value={value}\n onValueChange={(nextValue) => setValue(nextValue)}\n mask={(raw: string) => raw.toUpperCase().slice(0, 6).replace(/(.{3})(?=.)/, \"$1-\")}\n placeholder=\"AA-123\"\n />\n )\n}\n",
4
4
  htmlCode: "<label for=\"masked\">Referral code</label><input id=\"masked\" type=\"text\" value=\"AA-123\" placeholder=\"AA-123\" />",
5
- cliCommand: "npx tembro add masked-input",
5
+ cliCommand: "npx tembro add input",
6
6
  highlights: [
7
7
  "Mask callback runs on each edit",
8
8
  "Uppercase and slicing are explicit formatting assumptions",
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/inputs/masked-input.cjs");let t=require("react"),n=require("react/jsx-runtime");function r({mode:r}){let[i,a]=(0,t.useState)(`AA-123`);return(0,n.jsxs)(`div`,{className:`space-y-4`,children:[(0,n.jsx)(e.MaskedInput,{value:i,onValueChange:e=>a(e),mask:e=>e.toUpperCase().slice(0,6).replace(/(.{3})(?=.)/,`$1-`),placeholder:`AA-123`}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Display value: `,i||`—`]}),(0,n.jsx)(`p`,{className:`aui-text-muted text-sm`,children:`Task focus: fixed-format field where raw/display value assumptions should be documented.`}),(0,n.jsxs)(`p`,{className:`aui-text-muted text-sm`,children:[`Mode: `,r]})]})}exports.MaskedInputShowcase=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/ui/input/index.cjs");let t=require("react"),n=require("react/jsx-runtime");function r({mode:r}){let[i,a]=(0,t.useState)(`AA-123`);return(0,n.jsxs)(`div`,{className:`space-y-4`,children:[(0,n.jsx)(e.Input,{kind:`masked`,value:i,onValueChange:e=>a(e),mask:e=>e.toUpperCase().slice(0,6).replace(/(.{3})(?=.)/,`$1-`),placeholder:`AA-123`}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Display value: `,i||`—`]}),(0,n.jsx)(`p`,{className:`aui-text-muted text-sm`,children:`Task focus: fixed-format field where raw/display value assumptions should be documented.`}),(0,n.jsxs)(`p`,{className:`aui-text-muted text-sm`,children:[`Mode: `,r]})]})}exports.MaskedInputShowcase=r;
@@ -1,4 +1,4 @@
1
- import { MaskedInput as e } from "../../../components/inputs/masked-input.js";
1
+ import { Input as e } from "../../../components/ui/input/index.js";
2
2
  import { useState as t } from "react";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  //#region src/showcase/premium/masked-input/showcase.tsx
@@ -8,6 +8,7 @@ function i({ mode: i }) {
8
8
  className: "space-y-4",
9
9
  children: [
10
10
  /* @__PURE__ */ n(e, {
11
+ kind: "masked",
11
12
  value: a,
12
13
  onValueChange: (e) => o(e),
13
14
  mask: (e) => e.toUpperCase().slice(0, 6).replace(/(.{3})(?=.)/, "$1-"),
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import { useState } from "react"
2
- import { MoneyInput } from "tembro"
2
+ import { Input } from "tembro"
3
3
 
4
4
  export function Example() {
5
5
  const [value, setValue] = useState<number | null>(2990.5)
@@ -7,7 +7,8 @@ export function Example() {
7
7
 
8
8
  return (
9
9
  <div className="space-y-3">
10
- <MoneyInput
10
+ <Input
11
+ kind="money"
11
12
  value={value}
12
13
  onValueChange={(nextValue, rawValue) => {
13
14
  setValue(nextValue)
@@ -24,4 +25,4 @@ export function Example() {
24
25
  <p className="text-sm aui-text-muted">Use inputMode to match expected currency input source.</p>
25
26
  </div>
26
27
  )
27
- }`,htmlCode:`<label for="money">Budget</label><div>$<input id="money" inputmode="decimal" type="text" /></div>`,cliCommand:`npx tembro add money-input`,highlights:[`Currency prefix/suffix`,`Numeric payload`,`Invalid text handling`,`Custom keyboard mode`],relatedBlockSlugs:[`settings-form`,`users-table`,`crm-dashboard`],scenarios:[{title:`Pricing`,description:`Capture billing amounts with stable parsing and formatting behavior.`},{title:`Raw display vs parsed value`,description:`Keep display string separate from numeric payload.`},{title:`Invalid input`,description:`Handle temporary invalid values while editing before form submit.`},{title:`Negative guard`,description:`Prevent or allow negatives based on financial rules.`}],capabilityNotes:["Use `onValueChange` for canonical numeric value and raw typed value.","Pair `MoneyInput` with schema validation to reject negative or extreme values.",`Use prefix/suffix that matches locale and accounting conventions.`,`In multi-currency systems, normalize and convert right after parsing.`]};exports.moneyInputMock=e;
28
+ }`,htmlCode:`<label for="money">Budget</label><div>$<input id="money" inputmode="decimal" type="text" /></div>`,cliCommand:`npx tembro add input`,highlights:[`Currency prefix/suffix`,`Numeric payload`,`Invalid text handling`,`Custom keyboard mode`],relatedBlockSlugs:[`settings-form`,`users-table`,`crm-dashboard`],scenarios:[{title:`Pricing`,description:`Capture billing amounts with stable parsing and formatting behavior.`},{title:`Raw display vs parsed value`,description:`Keep display string separate from numeric payload.`},{title:`Invalid input`,description:`Handle temporary invalid values while editing before form submit.`},{title:`Negative guard`,description:`Prevent or allow negatives based on financial rules.`}],capabilityNotes:["Use `onValueChange` for canonical numeric value and raw typed value.","Pair `MoneyInput` with schema validation to reject negative or extreme values.",`Use prefix/suffix that matches locale and accounting conventions.`,`In multi-currency systems, normalize and convert right after parsing.`]};exports.moneyInputMock=e;
@@ -1,8 +1,8 @@
1
1
  //#region src/showcase/premium/money-input/mock.ts
2
2
  var e = {
3
- code: "import { useState } from \"react\"\nimport { MoneyInput } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState<number | null>(2990.5)\n const [raw, setRaw] = useState(\"$2,990.50\")\n\n return (\n <div className=\"space-y-3\">\n <MoneyInput\n value={value}\n onValueChange={(nextValue, rawValue) => {\n setValue(nextValue)\n setRaw(rawValue)\n }}\n prefix=\"$\"\n inputMode=\"decimal\"\n step={0.5}\n />\n <p className=\"text-sm aui-text-subtle\">\n Numeric value: <strong>{value === null ? \"invalid\" : value}</strong>\n </p>\n <p className=\"text-sm aui-text-muted\">Raw input: {raw}</p>\n <p className=\"text-sm aui-text-muted\">Use inputMode to match expected currency input source.</p>\n </div>\n )\n}",
3
+ code: "import { useState } from \"react\"\nimport { Input } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState<number | null>(2990.5)\n const [raw, setRaw] = useState(\"$2,990.50\")\n\n return (\n <div className=\"space-y-3\">\n <Input\n kind=\"money\"\n value={value}\n onValueChange={(nextValue, rawValue) => {\n setValue(nextValue)\n setRaw(rawValue)\n }}\n prefix=\"$\"\n inputMode=\"decimal\"\n step={0.5}\n />\n <p className=\"text-sm aui-text-subtle\">\n Numeric value: <strong>{value === null ? \"invalid\" : value}</strong>\n </p>\n <p className=\"text-sm aui-text-muted\">Raw input: {raw}</p>\n <p className=\"text-sm aui-text-muted\">Use inputMode to match expected currency input source.</p>\n </div>\n )\n}",
4
4
  htmlCode: "<label for=\"money\">Budget</label><div>$<input id=\"money\" inputmode=\"decimal\" type=\"text\" /></div>",
5
- cliCommand: "npx tembro add money-input",
5
+ cliCommand: "npx tembro add input",
6
6
  highlights: [
7
7
  "Currency prefix/suffix",
8
8
  "Numeric payload",
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/inputs/money-input.cjs");let t=require("react"),n=require("react/jsx-runtime");function r(){let[r,i]=(0,t.useState)(125.75);return(0,n.jsxs)(`div`,{className:`space-y-3`,children:[(0,n.jsx)(e.MoneyInput,{value:r,onValueChange:e=>i(e),prefix:`$`}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Parsed amount: `,r===null?`invalid`:`$${r.toFixed(2)}`]})]})}exports.MoneyInputShowcase=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/ui/input/index.cjs");let t=require("react"),n=require("react/jsx-runtime");function r(){let[r,i]=(0,t.useState)(125.75);return(0,n.jsxs)(`div`,{className:`space-y-3`,children:[(0,n.jsx)(e.Input,{kind:`money`,value:r,onValueChange:e=>i(e),prefix:`$`}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Parsed amount: `,r===null?`invalid`:`$${r.toFixed(2)}`]})]})}exports.MoneyInputShowcase=r;
@@ -1,4 +1,4 @@
1
- import { MoneyInput as e } from "../../../components/inputs/money-input.js";
1
+ import { Input as e } from "../../../components/ui/input/index.js";
2
2
  import { useState as t } from "react";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  //#region src/showcase/premium/money-input/showcase.tsx
@@ -7,6 +7,7 @@ function i() {
7
7
  return /* @__PURE__ */ r("div", {
8
8
  className: "space-y-3",
9
9
  children: [/* @__PURE__ */ n(e, {
10
+ kind: "money",
10
11
  value: i,
11
12
  onValueChange: (e) => a(e),
12
13
  prefix: "$"
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import { useState } from "react"
2
- import { NumberInput, parseNumberInput } from "tembro"
2
+ import { Input } from "tembro"
3
3
 
4
4
  export function Example() {
5
5
  const [value, setValue] = useState<number | null>(14)
@@ -7,16 +7,14 @@ export function Example() {
7
7
 
8
8
  return (
9
9
  <div className="space-y-3">
10
- <NumberInput
10
+ <Input
11
+ kind="number"
11
12
  value={value}
12
13
  onNumberChange={(nextValue) => {
13
14
  setValue(nextValue)
14
15
  setRaw(String(nextValue ?? ""))
15
16
  }}
16
- onChange={(event) => {
17
- const candidate = parseNumberInput(event.target.value)
18
- if (candidate === null) setRaw(event.target.value)
19
- }}
17
+ onChange={(event) => setRaw(event.target.value)}
20
18
  min={0}
21
19
  max={100}
22
20
  step={5}
@@ -31,4 +29,4 @@ export function Example() {
31
29
  </p>
32
30
  </div>
33
31
  )
34
- }`,htmlCode:`<label for="example-number">Amount</label><input id="example-number" inputmode="decimal" type="text" />`,cliCommand:`npx tembro add number-input`,highlights:[`Numeric parsing`,`Min/max constraints`,`Decimal steps`,`allowEmpty fallback`],relatedBlockSlugs:[`settings-form`,`users-table`,`crm-dashboard`],scenarios:[{title:`Budget field`,description:`Keep values inside business bounds while editing quickly.`},{title:`Invalid input`,description:`Use parser path to avoid NaN leaks into form data.`},{title:`Stepper steps`,description:`Use step values that match your business precision.`},{title:`Uncontrolled mode`,description:`Use defaultValue and HTML value when rapid typing is enough.`}],capabilityNotes:[`The component supports controlled numeric state and keeps string display behavior under user editing.`,"Use `min`/`max` with `clamp` semantics when downstream systems expect bounded values.","`allowEmpty` helps avoid forced 0 when field is cleared temporarily.",`Prefer controlled usage in forms that need instant validation and submit-time serialization.`]};exports.numberInputMock=e;
32
+ }`,htmlCode:`<label for="example-number">Amount</label><input id="example-number" inputmode="decimal" type="text" />`,cliCommand:`npx tembro add input`,highlights:[`Numeric parsing`,`Min/max constraints`,`Decimal steps`,`allowEmpty fallback`],relatedBlockSlugs:[`settings-form`,`users-table`,`crm-dashboard`],scenarios:[{title:`Budget field`,description:`Keep values inside business bounds while editing quickly.`},{title:`Invalid input`,description:`Use parser path to avoid NaN leaks into form data.`},{title:`Stepper steps`,description:`Use step values that match your business precision.`},{title:`Uncontrolled mode`,description:`Use defaultValue and HTML value when rapid typing is enough.`}],capabilityNotes:[`The component supports controlled numeric state and keeps string display behavior under user editing.`,"Use `min`/`max` with `clamp` semantics when downstream systems expect bounded values.","`allowEmpty` helps avoid forced 0 when field is cleared temporarily.",`Prefer controlled usage in forms that need instant validation and submit-time serialization.`]};exports.numberInputMock=e;
@@ -1,8 +1,8 @@
1
1
  //#region src/showcase/premium/number-input/mock.ts
2
2
  var e = {
3
- code: "import { useState } from \"react\"\nimport { NumberInput, parseNumberInput } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState<number | null>(14)\n const [raw, setRaw] = useState(\"14\")\n\n return (\n <div className=\"space-y-3\">\n <NumberInput\n value={value}\n onNumberChange={(nextValue) => {\n setValue(nextValue)\n setRaw(String(nextValue ?? \"\"))\n }}\n onChange={(event) => {\n const candidate = parseNumberInput(event.target.value)\n if (candidate === null) setRaw(event.target.value)\n }}\n min={0}\n max={100}\n step={5}\n allowEmpty\n />\n <p className=\"text-sm aui-text-subtle\">\n Parsed numeric: <strong>{value === null ? \"unset\" : value}</strong>\n </p>\n <p className=\"text-sm aui-text-muted\">Raw text: {raw}</p>\n <p className=\"text-sm aui-text-muted\">\n Try entering invalid chars to see how parse and clamp rules apply.\n </p>\n </div>\n )\n}",
3
+ code: "import { useState } from \"react\"\nimport { Input } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState<number | null>(14)\n const [raw, setRaw] = useState(\"14\")\n\n return (\n <div className=\"space-y-3\">\n <Input\n kind=\"number\"\n value={value}\n onNumberChange={(nextValue) => {\n setValue(nextValue)\n setRaw(String(nextValue ?? \"\"))\n }}\n onChange={(event) => setRaw(event.target.value)}\n min={0}\n max={100}\n step={5}\n allowEmpty\n />\n <p className=\"text-sm aui-text-subtle\">\n Parsed numeric: <strong>{value === null ? \"unset\" : value}</strong>\n </p>\n <p className=\"text-sm aui-text-muted\">Raw text: {raw}</p>\n <p className=\"text-sm aui-text-muted\">\n Try entering invalid chars to see how parse and clamp rules apply.\n </p>\n </div>\n )\n}",
4
4
  htmlCode: "<label for=\"example-number\">Amount</label><input id=\"example-number\" inputmode=\"decimal\" type=\"text\" />",
5
- cliCommand: "npx tembro add number-input",
5
+ cliCommand: "npx tembro add input",
6
6
  highlights: [
7
7
  "Numeric parsing",
8
8
  "Min/max constraints",
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/inputs/number-input.cjs");let t=require("react"),n=require("react/jsx-runtime");function r(){let[r,i]=(0,t.useState)(12);return(0,n.jsxs)(`div`,{className:`space-y-3`,children:[(0,n.jsx)(e.NumberInput,{value:r,onNumberChange:i,min:0,max:30,step:1}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Current value: `,r??`unset`]})]})}exports.NumberInputShowcase=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/ui/input/index.cjs");let t=require("react"),n=require("react/jsx-runtime");function r(){let[r,i]=(0,t.useState)(12);return(0,n.jsxs)(`div`,{className:`space-y-3`,children:[(0,n.jsx)(e.Input,{kind:`number`,value:r,onNumberChange:i,min:0,max:30,step:1}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Current value: `,r??`unset`]})]})}exports.NumberInputShowcase=r;
@@ -1,4 +1,4 @@
1
- import { NumberInput as e } from "../../../components/inputs/number-input.js";
1
+ import { Input as e } from "../../../components/ui/input/index.js";
2
2
  import { useState as t } from "react";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  //#region src/showcase/premium/number-input/showcase.tsx
@@ -7,6 +7,7 @@ function i() {
7
7
  return /* @__PURE__ */ r("div", {
8
8
  className: "space-y-3",
9
9
  children: [/* @__PURE__ */ n(e, {
10
+ kind: "number",
10
11
  value: i,
11
12
  onNumberChange: a,
12
13
  min: 0,
@@ -1,11 +1,12 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import * as React from "react"
2
- import { PasswordInput } from "tembro"
2
+ import { Input } from "tembro"
3
3
 
4
4
  export function Example() {
5
5
  const [value, setValue] = React.useState("")
6
6
 
7
7
  return (
8
- <PasswordInput
8
+ <Input
9
+ kind="password"
9
10
  value={value}
10
11
  onValueChange={setValue}
11
12
  placeholder="Enter workspace password"
@@ -1,6 +1,6 @@
1
1
  //#region src/showcase/premium/password-input/mock.ts
2
2
  var e = {
3
- code: "import * as React from \"react\"\nimport { PasswordInput } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = React.useState(\"\")\n\n return (\n <PasswordInput\n value={value}\n onValueChange={setValue}\n placeholder=\"Enter workspace password\"\n showCapsLockWarning\n />\n )\n}",
3
+ code: "import * as React from \"react\"\nimport { Input } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = React.useState(\"\")\n\n return (\n <Input\n kind=\"password\"\n value={value}\n onValueChange={setValue}\n placeholder=\"Enter workspace password\"\n showCapsLockWarning\n />\n )\n}",
4
4
  highlights: [
5
5
  "Visibility toggle",
6
6
  "Caps Lock warning support",
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../components/inputs/password-input.cjs"),n=require("../../../components/ui/badge/index.cjs");let r=require("react");r=e.__toESM(r,1);let i=require("react/jsx-runtime");var a=`rounded-[22px] border border-[color:var(--aui-divider)] bg-[color:var(--aui-page-bg)] p-5`;function o({mode:e}){let[o,s]=r.useState(``),[c,l]=r.useState(!1),u=o.length>=12?`Strong`:o.length>=8?`Good`:o.length>=1?`Weak`:`Empty`;return(0,i.jsxs)(`div`,{className:`space-y-5`,children:[(0,i.jsx)(`section`,{className:`rounded-[24px] border border-[color:var(--aui-divider)] bg-[color:var(--aui-page-bg)] p-5 sm:p-6`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 xl:flex-row xl:items-start xl:justify-between`,children:[(0,i.jsxs)(`div`,{className:`max-w-xl`,children:[(0,i.jsx)(`p`,{className:`text-xs font-semibold uppercase tracking-[0.26em] aui-text-muted`,children:`Sensitive field`}),(0,i.jsx)(`h3`,{className:`mt-3 text-2xl font-semibold tracking-tight aui-text-strong`,children:`PasswordInput should reduce mistakes in high-friction moments`}),(0,i.jsx)(`p`,{className:`mt-3 max-w-lg text-sm leading-6 aui-text-muted`,children:`The control should keep visibility, warnings, and state feedback inside one clean field instead of pushing users into extra UI.`})]}),(0,i.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,i.jsx)(n.Badge,{variant:`outline`,className:`rounded-full`,children:`Visibility toggle`}),(0,i.jsx)(n.Badge,{variant:`outline`,className:`rounded-full`,children:`Caps Lock aware`})]})]})}),(0,i.jsx)(`section`,{className:a,children:(0,i.jsx)(t.PasswordInput,{value:o,onValueChange:s,visible:c,onVisibleChange:l,placeholder:`Enter workspace password`,showCapsLockWarning:!0})}),(0,i.jsxs)(`div`,{className:`grid gap-4 xl:grid-cols-2`,children:[(0,i.jsxs)(`section`,{className:a,children:[(0,i.jsx)(`p`,{className:`text-sm font-medium aui-text-muted`,children:`Field state`}),(0,i.jsxs)(`div`,{className:`mt-4 space-y-2 text-sm leading-6 aui-text-muted`,children:[(0,i.jsxs)(`p`,{children:[`Length: `,(0,i.jsx)(`span`,{className:`font-medium aui-text-strong`,children:o.length})]}),(0,i.jsxs)(`p`,{children:[`Visibility: `,(0,i.jsx)(`span`,{className:`font-medium aui-text-strong`,children:c?`visible`:`hidden`})]}),(0,i.jsxs)(`p`,{children:[`Strength: `,(0,i.jsx)(`span`,{className:`font-medium aui-text-strong`,children:u})]})]})]}),(0,i.jsxs)(`section`,{className:a,children:[(0,i.jsx)(`p`,{className:`text-sm font-medium aui-text-muted`,children:`Usage note`}),(0,i.jsx)(`p`,{className:`mt-4 text-sm leading-6 aui-text-muted`,children:`Password fields should be operational and quiet. The user should not need a second component just to show, hide, or understand entry state.`})]})]}),e===`playground`?(0,i.jsx)(`section`,{className:a,children:(0,i.jsx)(`p`,{className:`text-sm aui-text-muted`,children:`Desktopda Caps Lock yoqib ko‘rsangiz warning ham shu field ichida ko‘rinadi.`})}):null]})}exports.PasswordInputShowcase=o;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../components/ui/input/index.cjs"),n=require("../../../components/ui/badge/index.cjs");let r=require("react");r=e.__toESM(r,1);let i=require("react/jsx-runtime");var a=`rounded-[22px] border border-[color:var(--aui-divider)] bg-[color:var(--aui-page-bg)] p-5`;function o({mode:e}){let[o,s]=r.useState(``),[c,l]=r.useState(!1),u=o.length>=12?`Strong`:o.length>=8?`Good`:o.length>=1?`Weak`:`Empty`;return(0,i.jsxs)(`div`,{className:`space-y-5`,children:[(0,i.jsx)(`section`,{className:`rounded-[24px] border border-[color:var(--aui-divider)] bg-[color:var(--aui-page-bg)] p-5 sm:p-6`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 xl:flex-row xl:items-start xl:justify-between`,children:[(0,i.jsxs)(`div`,{className:`max-w-xl`,children:[(0,i.jsx)(`p`,{className:`text-xs font-semibold uppercase tracking-[0.26em] aui-text-muted`,children:`Sensitive field`}),(0,i.jsx)(`h3`,{className:`mt-3 text-2xl font-semibold tracking-tight aui-text-strong`,children:`PasswordInput should reduce mistakes in high-friction moments`}),(0,i.jsx)(`p`,{className:`mt-3 max-w-lg text-sm leading-6 aui-text-muted`,children:`The control should keep visibility, warnings, and state feedback inside one clean field instead of pushing users into extra UI.`})]}),(0,i.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,i.jsx)(n.Badge,{variant:`outline`,className:`rounded-full`,children:`Visibility toggle`}),(0,i.jsx)(n.Badge,{variant:`outline`,className:`rounded-full`,children:`Caps Lock aware`})]})]})}),(0,i.jsx)(`section`,{className:a,children:(0,i.jsx)(t.Input,{kind:`password`,value:o,onValueChange:s,visible:c,onVisibleChange:l,placeholder:`Enter workspace password`,showCapsLockWarning:!0})}),(0,i.jsxs)(`div`,{className:`grid gap-4 xl:grid-cols-2`,children:[(0,i.jsxs)(`section`,{className:a,children:[(0,i.jsx)(`p`,{className:`text-sm font-medium aui-text-muted`,children:`Field state`}),(0,i.jsxs)(`div`,{className:`mt-4 space-y-2 text-sm leading-6 aui-text-muted`,children:[(0,i.jsxs)(`p`,{children:[`Length: `,(0,i.jsx)(`span`,{className:`font-medium aui-text-strong`,children:o.length})]}),(0,i.jsxs)(`p`,{children:[`Visibility: `,(0,i.jsx)(`span`,{className:`font-medium aui-text-strong`,children:c?`visible`:`hidden`})]}),(0,i.jsxs)(`p`,{children:[`Strength: `,(0,i.jsx)(`span`,{className:`font-medium aui-text-strong`,children:u})]})]})]}),(0,i.jsxs)(`section`,{className:a,children:[(0,i.jsx)(`p`,{className:`text-sm font-medium aui-text-muted`,children:`Usage note`}),(0,i.jsx)(`p`,{className:`mt-4 text-sm leading-6 aui-text-muted`,children:`Password fields should be operational and quiet. The user should not need a second component just to show, hide, or understand entry state.`})]})]}),e===`playground`?(0,i.jsx)(`section`,{className:a,children:(0,i.jsx)(`p`,{className:`text-sm aui-text-muted`,children:`Desktopda Caps Lock yoqib ko‘rsangiz warning ham shu field ichida ko‘rinadi.`})}):null]})}exports.PasswordInputShowcase=o;
@@ -1,4 +1,4 @@
1
- import { PasswordInput as e } from "../../../components/inputs/password-input.js";
1
+ import { Input as e } from "../../../components/ui/input/index.js";
2
2
  import { Badge as t } from "../../../components/ui/badge/index.js";
3
3
  import * as n from "react";
4
4
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
@@ -46,6 +46,7 @@ function o({ mode: o }) {
46
46
  /* @__PURE__ */ r("section", {
47
47
  className: a,
48
48
  children: /* @__PURE__ */ r(e, {
49
+ kind: "password",
49
50
  value: s,
50
51
  onValueChange: c,
51
52
  visible: l,
@@ -1,16 +1,17 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import { useState } from "react"
2
- import { PhoneInput } from "tembro"
2
+ import { Input } from "tembro"
3
3
 
4
4
  export function Example() {
5
5
  const [value, setValue] = useState("+998 90 123 45 67")
6
6
 
7
7
  return (
8
- <PhoneInput
8
+ <Input
9
+ kind="phone"
9
10
  value={value}
10
11
  onValueChange={setValue}
11
- defaultCountry="UZ"
12
+ countryCode="+998"
12
13
  placeholder="+998 90 123 45 67"
13
14
  />
14
15
  )
15
16
  }
16
- `,htmlCode:`<label for="phone">Phone</label><input id="phone" type="tel" inputmode="tel" placeholder="+998 90 123 45 67" />`,cliCommand:`npx tembro add phone-input`,highlights:[`Phone formatting assumptions`,`Locale/defaultCountry behavior`,`Controlled value contract`,`Raw vs displayed phone forms`],relatedBlockSlugs:[`users-table`,`settings-form`,`pricing-section`],scenarios:[{title:`Profile contact`,description:`Capture customer phone with predictable display behavior.`},{title:`Checkout phone`,description:`Format validation before creating verification records.`},{title:`Country switch`,description:`Change defaultCountry and keep callback contract stable.`},{title:`Backend integration`,description:`Persist normalized phone payload while rendering localized format.`}],capabilityNotes:[`Write down whether your backend expects E.164 or local phone format.`,`Avoid mixing formatted display and raw storage in schema validation.`,`For country-aware inputs, keep default country explicit in docs and migration notes.`,`Use one validator shared by form and API integration layers.`]};exports.phoneInputMock=e;
17
+ `,htmlCode:`<label for="phone">Phone</label><input id="phone" type="tel" inputmode="tel" placeholder="+998 90 123 45 67" />`,cliCommand:`npx tembro add input`,highlights:[`Phone formatting assumptions`,`Locale/defaultCountry behavior`,`Controlled value contract`,`Raw vs displayed phone forms`],relatedBlockSlugs:[`users-table`,`settings-form`,`pricing-section`],scenarios:[{title:`Profile contact`,description:`Capture customer phone with predictable display behavior.`},{title:`Checkout phone`,description:`Format validation before creating verification records.`},{title:`Country switch`,description:`Change defaultCountry and keep callback contract stable.`},{title:`Backend integration`,description:`Persist normalized phone payload while rendering localized format.`}],capabilityNotes:[`Write down whether your backend expects E.164 or local phone format.`,`Avoid mixing formatted display and raw storage in schema validation.`,`For country-aware inputs, keep default country explicit in docs and migration notes.`,`Use one validator shared by form and API integration layers.`]};exports.phoneInputMock=e;
@@ -1,8 +1,8 @@
1
1
  //#region src/showcase/premium/phone-input/mock.ts
2
2
  var e = {
3
- code: "import { useState } from \"react\"\nimport { PhoneInput } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState(\"+998 90 123 45 67\")\n\n return (\n <PhoneInput\n value={value}\n onValueChange={setValue}\n defaultCountry=\"UZ\"\n placeholder=\"+998 90 123 45 67\"\n />\n )\n}\n",
3
+ code: "import { useState } from \"react\"\nimport { Input } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = useState(\"+998 90 123 45 67\")\n\n return (\n <Input\n kind=\"phone\"\n value={value}\n onValueChange={setValue}\n countryCode=\"+998\"\n placeholder=\"+998 90 123 45 67\"\n />\n )\n}\n",
4
4
  htmlCode: "<label for=\"phone\">Phone</label><input id=\"phone\" type=\"tel\" inputmode=\"tel\" placeholder=\"+998 90 123 45 67\" />",
5
- cliCommand: "npx tembro add phone-input",
5
+ cliCommand: "npx tembro add input",
6
6
  highlights: [
7
7
  "Phone formatting assumptions",
8
8
  "Locale/defaultCountry behavior",
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/inputs/phone-input.cjs");let t=require("react"),n=require("react/jsx-runtime");function r({mode:r}){let[i,a]=(0,t.useState)(`+998 90 123 45 67`);return(0,n.jsxs)(`div`,{className:`space-y-4`,children:[(0,n.jsx)(e.PhoneInput,{value:i,onValueChange:e=>a(e),countryCode:`+998`,placeholder:`+998 90 123 45 67`}),(0,n.jsxs)(`p`,{className:`aui-text-strong text-sm`,children:[`Canonical value: `,i||`—`]}),(0,n.jsx)(`p`,{className:`aui-text-muted text-sm`,children:`Display format is formatted for UX; raw value strategy is app-specific.`}),(0,n.jsxs)(`p`,{className:`aui-text-muted text-sm`,children:[`Mode: `,r]})]})}exports.PhoneInputShowcase=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/ui/input/index.cjs");let t=require("react"),n=require("react/jsx-runtime");function r({mode:r}){let[i,a]=(0,t.useState)(`+998 90 123 45 67`);return(0,n.jsxs)(`div`,{className:`space-y-4`,children:[(0,n.jsx)(e.Input,{kind:`phone`,value:i,onValueChange:e=>a(e),countryCode:`+998`,placeholder:`+998 90 123 45 67`}),(0,n.jsxs)(`p`,{className:`aui-text-strong text-sm`,children:[`Canonical value: `,i||`—`]}),(0,n.jsx)(`p`,{className:`aui-text-muted text-sm`,children:`Display format is formatted for UX; raw value strategy is app-specific.`}),(0,n.jsxs)(`p`,{className:`aui-text-muted text-sm`,children:[`Mode: `,r]})]})}exports.PhoneInputShowcase=r;
@@ -1,4 +1,4 @@
1
- import { PhoneInput as e } from "../../../components/inputs/phone-input.js";
1
+ import { Input as e } from "../../../components/ui/input/index.js";
2
2
  import { useState as t } from "react";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  //#region src/showcase/premium/phone-input/showcase.tsx
@@ -8,6 +8,7 @@ function i({ mode: i }) {
8
8
  className: "space-y-4",
9
9
  children: [
10
10
  /* @__PURE__ */ n(e, {
11
+ kind: "phone",
11
12
  value: a,
12
13
  onValueChange: (e) => o(e),
13
14
  countryCode: "+998",
@@ -1,12 +1,13 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import { useState } from "react"
2
- import { QuantityInput } from "tembro"
2
+ import { Input } from "tembro"
3
3
 
4
4
  export function Example() {
5
5
  const [quantity, setQuantity] = useState<number | null>(3)
6
6
 
7
7
  return (
8
8
  <div className="space-y-3">
9
- <QuantityInput
9
+ <Input
10
+ kind="quantity"
10
11
  value={quantity}
11
12
  onValueChange={(nextValue: number | null) => setQuantity(nextValue)}
12
13
  min={0}
@@ -25,4 +26,4 @@ export function Example() {
25
26
  </p>
26
27
  </div>
27
28
  )
28
- }`,htmlCode:`<label for="qty">Quantity</label><input id="qty" type="text" inputmode="numeric" />`,cliCommand:`npx tembro add quantity-input`,highlights:[`Stepper controls`,`min/max boundaries`,`controlled usage`,`compact row compatibility`],relatedBlockSlugs:[`crm-dashboard`,`users-table`,`settings-form`],scenarios:[{title:`Line item quantity`,description:`Use in carts and order forms with strict bounds.`},{title:`Inventory controls`,description:`Keep increments aligned with backend-stock constraints.`},{title:`Form tables`,description:`Compact control rendering works well in inline editable rows.`},{title:`Bounded values`,description:`Reject edits below zero and above maximum.`}],capabilityNotes:[`Show inline controls for quick adjustments when quantity edits are frequent.`,"Set `min`/`max` to protect impossible states in business rules.",`Use controlled flow to persist updates across rows and validation passes.`,`Disable controls when quantity is not editable to avoid inconsistent states.`]};exports.quantityInputMock=e;
29
+ }`,htmlCode:`<label for="qty">Quantity</label><input id="qty" type="text" inputmode="numeric" />`,cliCommand:`npx tembro add input`,highlights:[`Stepper controls`,`min/max boundaries`,`controlled usage`,`compact row compatibility`],relatedBlockSlugs:[`crm-dashboard`,`users-table`,`settings-form`],scenarios:[{title:`Line item quantity`,description:`Use in carts and order forms with strict bounds.`},{title:`Inventory controls`,description:`Keep increments aligned with backend-stock constraints.`},{title:`Form tables`,description:`Compact control rendering works well in inline editable rows.`},{title:`Bounded values`,description:`Reject edits below zero and above maximum.`}],capabilityNotes:[`Show inline controls for quick adjustments when quantity edits are frequent.`,"Set `min`/`max` to protect impossible states in business rules.",`Use controlled flow to persist updates across rows and validation passes.`,`Disable controls when quantity is not editable to avoid inconsistent states.`]};exports.quantityInputMock=e;
@@ -1,8 +1,8 @@
1
1
  //#region src/showcase/premium/quantity-input/mock.ts
2
2
  var e = {
3
- code: "import { useState } from \"react\"\nimport { QuantityInput } from \"tembro\"\n\nexport function Example() {\n const [quantity, setQuantity] = useState<number | null>(3)\n\n return (\n <div className=\"space-y-3\">\n <QuantityInput\n value={quantity}\n onValueChange={(nextValue: number | null) => setQuantity(nextValue)}\n min={0}\n max={10}\n step={1}\n showControls\n />\n <p className=\"text-sm aui-text-subtle\">\n Items: <strong>{quantity ?? \"unset\"}</strong>\n </p>\n <p className=\"text-sm aui-text-muted\">\n Controls should stay aligned with adjacent action columns in compact table rows.\n </p>\n <p className=\"text-sm aui-text-muted\">\n Try increment/decrement at bounds to validate guardrails.\n </p>\n </div>\n )\n}",
3
+ code: "import { useState } from \"react\"\nimport { Input } from \"tembro\"\n\nexport function Example() {\n const [quantity, setQuantity] = useState<number | null>(3)\n\n return (\n <div className=\"space-y-3\">\n <Input\n kind=\"quantity\"\n value={quantity}\n onValueChange={(nextValue: number | null) => setQuantity(nextValue)}\n min={0}\n max={10}\n step={1}\n showControls\n />\n <p className=\"text-sm aui-text-subtle\">\n Items: <strong>{quantity ?? \"unset\"}</strong>\n </p>\n <p className=\"text-sm aui-text-muted\">\n Controls should stay aligned with adjacent action columns in compact table rows.\n </p>\n <p className=\"text-sm aui-text-muted\">\n Try increment/decrement at bounds to validate guardrails.\n </p>\n </div>\n )\n}",
4
4
  htmlCode: "<label for=\"qty\">Quantity</label><input id=\"qty\" type=\"text\" inputmode=\"numeric\" />",
5
- cliCommand: "npx tembro add quantity-input",
5
+ cliCommand: "npx tembro add input",
6
6
  highlights: [
7
7
  "Stepper controls",
8
8
  "min/max boundaries",
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/inputs/quantity-input.cjs");let t=require("react"),n=require("react/jsx-runtime");function r(){let[r,i]=(0,t.useState)(2);return(0,n.jsxs)(`div`,{className:`space-y-3`,children:[(0,n.jsx)(e.QuantityInput,{value:r,onValueChange:i,min:0,max:12,showControls:!0}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Quantity: `,r??`unset`]})]})}exports.QuantityInputShowcase=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../components/ui/input/index.cjs");let t=require("react"),n=require("react/jsx-runtime");function r(){let[r,i]=(0,t.useState)(2);return(0,n.jsxs)(`div`,{className:`space-y-3`,children:[(0,n.jsx)(e.Input,{kind:`quantity`,value:r,onValueChange:i,min:0,max:12,showControls:!0}),(0,n.jsxs)(`p`,{className:`aui-text-subtle text-sm`,children:[`Quantity: `,r??`unset`]})]})}exports.QuantityInputShowcase=r;
@@ -1,4 +1,4 @@
1
- import { QuantityInput as e } from "../../../components/inputs/quantity-input.js";
1
+ import { Input as e } from "../../../components/ui/input/index.js";
2
2
  import { useState as t } from "react";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  //#region src/showcase/premium/quantity-input/showcase.tsx
@@ -7,6 +7,7 @@ function i() {
7
7
  return /* @__PURE__ */ r("div", {
8
8
  className: "space-y-3",
9
9
  children: [/* @__PURE__ */ n(e, {
10
+ kind: "quantity",
10
11
  value: i,
11
12
  onValueChange: a,
12
13
  min: 0,
@@ -1,11 +1,12 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import * as React from "react"
2
- import { Kbd, SearchInput } from "tembro"
2
+ import { Input, Kbd } from "tembro"
3
3
 
4
4
  export function Example() {
5
5
  const [value, setValue] = React.useState("")
6
6
 
7
7
  return (
8
- <SearchInput
8
+ <Input
9
+ kind="search"
9
10
  value={value}
10
11
  onValueChange={setValue}
11
12
  placeholder="Search customers, invoices, or routes..."
@@ -1,6 +1,6 @@
1
1
  //#region src/showcase/premium/search-input/mock.ts
2
2
  var e = {
3
- code: "import * as React from \"react\"\nimport { Kbd, SearchInput } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = React.useState(\"\")\n\n return (\n <SearchInput\n value={value}\n onValueChange={setValue}\n placeholder=\"Search customers, invoices, or routes...\"\n resultCount={18}\n shortcut={<Kbd>Ctrl+K</Kbd>}\n debounceMs={250}\n />\n )\n}",
3
+ code: "import * as React from \"react\"\nimport { Input, Kbd } from \"tembro\"\n\nexport function Example() {\n const [value, setValue] = React.useState(\"\")\n\n return (\n <Input\n kind=\"search\"\n value={value}\n onValueChange={setValue}\n placeholder=\"Search customers, invoices, or routes...\"\n resultCount={18}\n shortcut={<Kbd>Ctrl+K</Kbd>}\n debounceMs={250}\n />\n )\n}",
4
4
  highlights: [
5
5
  "Search icon, result count, and shortcut support",
6
6
  "Debounced value callback",
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../components/inputs/search-input.cjs"),n=require("../../../components/ui/badge/index.cjs"),r=require("../../../components/ui/kbd/index.cjs");let i=require("react");i=e.__toESM(i,1);let a=require("react/jsx-runtime");var o=`rounded-[22px] border border-[color:var(--aui-divider)] bg-[color:var(--aui-page-bg)] p-5`,s=[`Acme Growth workspace`,`Invoice 2048 approval`,`Northwind billing route`,`Customer retention dashboard`,`Workspace member access`,`Export usage report`];function c({mode:e}){let[c,l]=i.useState(``),[u,d]=i.useState(``),f=i.useMemo(()=>{let e=u.trim().toLowerCase();return e?s.filter(t=>t.toLowerCase().includes(e)):s},[u]);return(0,a.jsxs)(`div`,{className:`space-y-5`,children:[(0,a.jsx)(`section`,{className:`rounded-[24px] border border-[color:var(--aui-divider)] bg-[color:var(--aui-page-bg)] p-5 sm:p-6`,children:(0,a.jsxs)(`div`,{className:`flex flex-col gap-6 xl:flex-row xl:items-start xl:justify-between`,children:[(0,a.jsxs)(`div`,{className:`max-w-xl`,children:[(0,a.jsx)(`p`,{className:`text-xs font-semibold uppercase tracking-[0.26em] aui-text-muted`,children:`Search control`}),(0,a.jsx)(`h3`,{className:`mt-3 text-2xl font-semibold tracking-tight aui-text-strong`,children:`SearchInput should shorten finding, not add interface noise`}),(0,a.jsx)(`p`,{className:`mt-3 max-w-lg text-sm leading-6 aui-text-muted`,children:`A good search field exposes intent clearly: what can be searched, how many matches remain, and whether the query is still being processed.`})]}),(0,a.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,a.jsx)(n.Badge,{variant:`outline`,className:`rounded-full`,children:`Debounced`}),(0,a.jsx)(n.Badge,{variant:`outline`,className:`rounded-full`,children:`Shortcut aware`})]})]})}),(0,a.jsx)(`section`,{className:o,children:(0,a.jsx)(t.SearchInput,{value:c,onValueChange:l,onDebouncedValueChange:d,placeholder:`Search customers, invoices, or routes...`,resultCount:f.length,shortcut:(0,a.jsx)(r.Kbd,{children:`Ctrl+K`}),debounceMs:250})}),(0,a.jsxs)(`div`,{className:`grid gap-4 xl:grid-cols-[0.95fr_1.05fr]`,children:[(0,a.jsxs)(`section`,{className:o,children:[(0,a.jsx)(`p`,{className:`text-sm font-medium aui-text-muted`,children:`Resolved query`}),(0,a.jsx)(`p`,{className:`mt-3 text-base font-medium aui-text-strong`,children:u||`No active query`}),(0,a.jsx)(`p`,{className:`mt-2 text-sm leading-6 aui-text-muted`,children:`The debounced value represents what should usually drive remote or expensive filters.`})]}),(0,a.jsxs)(`section`,{className:o,children:[(0,a.jsx)(`p`,{className:`text-sm font-medium aui-text-muted`,children:`Preview results`}),(0,a.jsx)(`div`,{className:`mt-4 space-y-2 text-sm`,children:f.map(e=>(0,a.jsx)(`div`,{className:`rounded-2xl border border-[color:var(--aui-divider)] px-3 py-2 aui-text-muted`,children:e},e))})]})]}),e===`playground`?(0,a.jsx)(`section`,{className:o,children:(0,a.jsx)(`p`,{className:`text-sm aui-text-muted`,children:"Try searching for `invoice`, `workspace`, or `billing`."})}):null]})}exports.SearchInputShowcase=c;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../_virtual/_rolldown/runtime.cjs"),t=require("../../../components/ui/input/index.cjs"),n=require("../../../components/ui/badge/index.cjs"),r=require("../../../components/ui/kbd/index.cjs");let i=require("react");i=e.__toESM(i,1);let a=require("react/jsx-runtime");var o=`rounded-[22px] border border-[color:var(--aui-divider)] bg-[color:var(--aui-page-bg)] p-5`,s=[`Acme Growth workspace`,`Invoice 2048 approval`,`Northwind billing route`,`Customer retention dashboard`,`Workspace member access`,`Export usage report`];function c({mode:e}){let[c,l]=i.useState(``),[u,d]=i.useState(``),f=i.useMemo(()=>{let e=u.trim().toLowerCase();return e?s.filter(t=>t.toLowerCase().includes(e)):s},[u]);return(0,a.jsxs)(`div`,{className:`space-y-5`,children:[(0,a.jsx)(`section`,{className:`rounded-[24px] border border-[color:var(--aui-divider)] bg-[color:var(--aui-page-bg)] p-5 sm:p-6`,children:(0,a.jsxs)(`div`,{className:`flex flex-col gap-6 xl:flex-row xl:items-start xl:justify-between`,children:[(0,a.jsxs)(`div`,{className:`max-w-xl`,children:[(0,a.jsx)(`p`,{className:`text-xs font-semibold uppercase tracking-[0.26em] aui-text-muted`,children:`Search control`}),(0,a.jsx)(`h3`,{className:`mt-3 text-2xl font-semibold tracking-tight aui-text-strong`,children:`SearchInput should shorten finding, not add interface noise`}),(0,a.jsx)(`p`,{className:`mt-3 max-w-lg text-sm leading-6 aui-text-muted`,children:`A good search field exposes intent clearly: what can be searched, how many matches remain, and whether the query is still being processed.`})]}),(0,a.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,a.jsx)(n.Badge,{variant:`outline`,className:`rounded-full`,children:`Debounced`}),(0,a.jsx)(n.Badge,{variant:`outline`,className:`rounded-full`,children:`Shortcut aware`})]})]})}),(0,a.jsx)(`section`,{className:o,children:(0,a.jsx)(t.Input,{kind:`search`,value:c,onValueChange:l,onDebouncedValueChange:d,placeholder:`Search customers, invoices, or routes...`,resultCount:f.length,shortcut:(0,a.jsx)(r.Kbd,{children:`Ctrl+K`}),debounceMs:250})}),(0,a.jsxs)(`div`,{className:`grid gap-4 xl:grid-cols-[0.95fr_1.05fr]`,children:[(0,a.jsxs)(`section`,{className:o,children:[(0,a.jsx)(`p`,{className:`text-sm font-medium aui-text-muted`,children:`Resolved query`}),(0,a.jsx)(`p`,{className:`mt-3 text-base font-medium aui-text-strong`,children:u||`No active query`}),(0,a.jsx)(`p`,{className:`mt-2 text-sm leading-6 aui-text-muted`,children:`The debounced value represents what should usually drive remote or expensive filters.`})]}),(0,a.jsxs)(`section`,{className:o,children:[(0,a.jsx)(`p`,{className:`text-sm font-medium aui-text-muted`,children:`Preview results`}),(0,a.jsx)(`div`,{className:`mt-4 space-y-2 text-sm`,children:f.map(e=>(0,a.jsx)(`div`,{className:`rounded-2xl border border-[color:var(--aui-divider)] px-3 py-2 aui-text-muted`,children:e},e))})]})]}),e===`playground`?(0,a.jsx)(`section`,{className:o,children:(0,a.jsx)(`p`,{className:`text-sm aui-text-muted`,children:"Try searching for `invoice`, `workspace`, or `billing`."})}):null]})}exports.SearchInputShowcase=c;
@@ -1,4 +1,4 @@
1
- import { SearchInput as e } from "../../../components/inputs/search-input.js";
1
+ import { Input as e } from "../../../components/ui/input/index.js";
2
2
  import { Badge as t } from "../../../components/ui/badge/index.js";
3
3
  import { Kbd as n } from "../../../components/ui/kbd/index.js";
4
4
  import * as r from "react";
@@ -57,6 +57,7 @@ function c({ mode: c }) {
57
57
  /* @__PURE__ */ i("section", {
58
58
  className: o,
59
59
  children: /* @__PURE__ */ i(e, {
60
+ kind: "search",
60
61
  value: l,
61
62
  onValueChange: u,
62
63
  onDebouncedValueChange: f,
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={code:`import { useState } from "react"
2
- import { Button, SimpleSelect } from "tembro"
2
+ import { Button, Select } from "tembro"
3
3
 
4
4
  const selectOptions = [
5
5
  { value: "public", label: "Public", disabled: false },
@@ -13,7 +13,7 @@ export function Example() {
13
13
 
14
14
  return (
15
15
  <div className="space-y-3">
16
- <SimpleSelect
16
+ <Select
17
17
  options={selectOptions}
18
18
  value={value}
19
19
  onValueChange={(nextValue) => setValue(nextValue ?? "private")}
@@ -26,4 +26,4 @@ export function Example() {
26
26
  <Button variant="outline" onClick={() => setValue("public")}>Reset public</Button>
27
27
  </div>
28
28
  )
29
- }`,htmlCode:`<button data-slot="simple-select-trigger">Open options</button>`,cliCommand:`npx tembro add simple-select`,highlights:[`Controlled usage`,`Static options`,`Clear default value`,`Disabled option handling`],relatedBlockSlugs:[`settings-form`,`users-table`,`crm-dashboard`],scenarios:[{title:`Controlled visibility`,description:"Use controlled `value` when parent flow tracks visibility state."},{title:`Static catalog`,description:`Use fixed options for status and tier fields.`},{title:`Clear/reset flow`,description:`Expose a reset path before destructive transitions.`},{title:`Compact trigger`,description:`Use small size in dense row or toolbar layouts.`}],capabilityNotes:[`SimpleSelect is best for local option lists that don't require async loading.`,`Avoid rebuilding options each render; memoize if options are computed.`,`Use disabled options to communicate temporarily unavailable targets.`,`Always keep selected value in a controlled parent when used in complex forms.`]};exports.simpleSelectMock=e;
29
+ }`,htmlCode:`<button data-slot="simple-select-trigger">Open options</button>`,cliCommand:`npx tembro add select`,highlights:[`Controlled usage`,`Static options`,`Clear default value`,`Disabled option handling`],relatedBlockSlugs:[`settings-form`,`users-table`,`crm-dashboard`],scenarios:[{title:`Controlled visibility`,description:"Use controlled `value` when parent flow tracks visibility state."},{title:`Static catalog`,description:`Use fixed options for status and tier fields.`},{title:`Clear/reset flow`,description:`Expose a reset path before destructive transitions.`},{title:`Compact trigger`,description:`Use small size in dense row or toolbar layouts.`}],capabilityNotes:[`SimpleSelect is best for local option lists that don't require async loading.`,`Avoid rebuilding options each render; memoize if options are computed.`,`Use disabled options to communicate temporarily unavailable targets.`,`Always keep selected value in a controlled parent when used in complex forms.`]};exports.simpleSelectMock=e;