@studio-piot/native-ui 0.1.0

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 (247) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +91 -0
  3. package/dist/components/Button/Button.d.ts +16 -0
  4. package/dist/components/Button/Button.d.ts.map +1 -0
  5. package/dist/components/Button/Button.js +44 -0
  6. package/dist/components/Button/Button.js.map +1 -0
  7. package/dist/components/Button/buttonRadius.d.ts +3 -0
  8. package/dist/components/Button/buttonRadius.d.ts.map +1 -0
  9. package/dist/components/Button/buttonRadius.js +17 -0
  10. package/dist/components/Button/buttonRadius.js.map +1 -0
  11. package/dist/components/Button/index.d.ts +3 -0
  12. package/dist/components/Button/index.d.ts.map +1 -0
  13. package/dist/components/Button/index.js +8 -0
  14. package/dist/components/Button/index.js.map +1 -0
  15. package/dist/components/Field/FieldText.d.ts +3 -0
  16. package/dist/components/Field/FieldText.d.ts.map +1 -0
  17. package/dist/components/Field/FieldText.js +9 -0
  18. package/dist/components/Field/FieldText.js.map +1 -0
  19. package/dist/components/Field/FieldTextarea.d.ts +3 -0
  20. package/dist/components/Field/FieldTextarea.d.ts.map +1 -0
  21. package/dist/components/Field/FieldTextarea.js +10 -0
  22. package/dist/components/Field/FieldTextarea.js.map +1 -0
  23. package/dist/components/Field/fieldChrome.d.ts +10 -0
  24. package/dist/components/Field/fieldChrome.d.ts.map +1 -0
  25. package/dist/components/Field/fieldChrome.js +100 -0
  26. package/dist/components/Field/fieldChrome.js.map +1 -0
  27. package/dist/components/Field/fieldThemeRoles.d.ts +13 -0
  28. package/dist/components/Field/fieldThemeRoles.d.ts.map +1 -0
  29. package/dist/components/Field/fieldThemeRoles.js +15 -0
  30. package/dist/components/Field/fieldThemeRoles.js.map +1 -0
  31. package/dist/components/Field/index.d.ts +6 -0
  32. package/dist/components/Field/index.d.ts.map +1 -0
  33. package/dist/components/Field/index.js +10 -0
  34. package/dist/components/Field/index.js.map +1 -0
  35. package/dist/components/Field/resolveFieldBorder.d.ts +16 -0
  36. package/dist/components/Field/resolveFieldBorder.d.ts.map +1 -0
  37. package/dist/components/Field/resolveFieldBorder.js +20 -0
  38. package/dist/components/Field/resolveFieldBorder.js.map +1 -0
  39. package/dist/components/Field/resolveFieldColor.d.ts +7 -0
  40. package/dist/components/Field/resolveFieldColor.d.ts.map +1 -0
  41. package/dist/components/Field/resolveFieldColor.js +21 -0
  42. package/dist/components/Field/resolveFieldColor.js.map +1 -0
  43. package/dist/components/Field/types.d.ts +46 -0
  44. package/dist/components/Field/types.d.ts.map +1 -0
  45. package/dist/components/Field/types.js +3 -0
  46. package/dist/components/Field/types.js.map +1 -0
  47. package/dist/components/Field/useResolvedFieldColor.d.ts +2 -0
  48. package/dist/components/Field/useResolvedFieldColor.d.ts.map +1 -0
  49. package/dist/components/Field/useResolvedFieldColor.js +15 -0
  50. package/dist/components/Field/useResolvedFieldColor.js.map +1 -0
  51. package/dist/components/Form/Form.d.ts +3 -0
  52. package/dist/components/Form/Form.d.ts.map +1 -0
  53. package/dist/components/Form/Form.js +100 -0
  54. package/dist/components/Form/Form.js.map +1 -0
  55. package/dist/components/Form/FormCloseButton.d.ts +4 -0
  56. package/dist/components/Form/FormCloseButton.d.ts.map +1 -0
  57. package/dist/components/Form/FormCloseButton.js +17 -0
  58. package/dist/components/Form/FormCloseButton.js.map +1 -0
  59. package/dist/components/Form/index.d.ts +4 -0
  60. package/dist/components/Form/index.d.ts.map +1 -0
  61. package/dist/components/Form/index.js +8 -0
  62. package/dist/components/Form/index.js.map +1 -0
  63. package/dist/components/Form/resolveThemeColor.d.ts +11 -0
  64. package/dist/components/Form/resolveThemeColor.d.ts.map +1 -0
  65. package/dist/components/Form/resolveThemeColor.js +21 -0
  66. package/dist/components/Form/resolveThemeColor.js.map +1 -0
  67. package/dist/components/Form/types.d.ts +30 -0
  68. package/dist/components/Form/types.d.ts.map +1 -0
  69. package/dist/components/Form/types.js +3 -0
  70. package/dist/components/Form/types.js.map +1 -0
  71. package/dist/components/Form/useResolvedThemeColor.d.ts +2 -0
  72. package/dist/components/Form/useResolvedThemeColor.d.ts.map +1 -0
  73. package/dist/components/Form/useResolvedThemeColor.js +15 -0
  74. package/dist/components/Form/useResolvedThemeColor.js.map +1 -0
  75. package/dist/components/Form/withAlpha.d.ts +2 -0
  76. package/dist/components/Form/withAlpha.d.ts.map +1 -0
  77. package/dist/components/Form/withAlpha.js +12 -0
  78. package/dist/components/Form/withAlpha.js.map +1 -0
  79. package/dist/components/LinkBlocks/LinkBlocks.d.ts +3 -0
  80. package/dist/components/LinkBlocks/LinkBlocks.d.ts.map +1 -0
  81. package/dist/components/LinkBlocks/LinkBlocks.js +75 -0
  82. package/dist/components/LinkBlocks/LinkBlocks.js.map +1 -0
  83. package/dist/components/LinkBlocks/filterGroups.d.ts +3 -0
  84. package/dist/components/LinkBlocks/filterGroups.d.ts.map +1 -0
  85. package/dist/components/LinkBlocks/filterGroups.js +7 -0
  86. package/dist/components/LinkBlocks/filterGroups.js.map +1 -0
  87. package/dist/components/LinkBlocks/index.d.ts +4 -0
  88. package/dist/components/LinkBlocks/index.d.ts.map +1 -0
  89. package/dist/components/LinkBlocks/index.js +8 -0
  90. package/dist/components/LinkBlocks/index.js.map +1 -0
  91. package/dist/components/LinkBlocks/types.d.ts +26 -0
  92. package/dist/components/LinkBlocks/types.d.ts.map +1 -0
  93. package/dist/components/LinkBlocks/types.js +3 -0
  94. package/dist/components/LinkBlocks/types.js.map +1 -0
  95. package/dist/components/RadioField/RadioField.d.ts +3 -0
  96. package/dist/components/RadioField/RadioField.d.ts.map +1 -0
  97. package/dist/components/RadioField/RadioField.js +76 -0
  98. package/dist/components/RadioField/RadioField.js.map +1 -0
  99. package/dist/components/RadioField/RadioMark.d.ts +7 -0
  100. package/dist/components/RadioField/RadioMark.d.ts.map +1 -0
  101. package/dist/components/RadioField/RadioMark.js +32 -0
  102. package/dist/components/RadioField/RadioMark.js.map +1 -0
  103. package/dist/components/RadioField/index.d.ts +4 -0
  104. package/dist/components/RadioField/index.d.ts.map +1 -0
  105. package/dist/components/RadioField/index.js +8 -0
  106. package/dist/components/RadioField/index.js.map +1 -0
  107. package/dist/components/RadioField/radioThemeRoles.d.ts +11 -0
  108. package/dist/components/RadioField/radioThemeRoles.d.ts.map +1 -0
  109. package/dist/components/RadioField/radioThemeRoles.js +13 -0
  110. package/dist/components/RadioField/radioThemeRoles.js.map +1 -0
  111. package/dist/components/RadioField/types.d.ts +24 -0
  112. package/dist/components/RadioField/types.d.ts.map +1 -0
  113. package/dist/components/RadioField/types.js +3 -0
  114. package/dist/components/RadioField/types.js.map +1 -0
  115. package/dist/components/Select/Select.d.ts +3 -0
  116. package/dist/components/Select/Select.d.ts.map +1 -0
  117. package/dist/components/Select/Select.js +137 -0
  118. package/dist/components/Select/Select.js.map +1 -0
  119. package/dist/components/Select/SelectCloseButton.d.ts +4 -0
  120. package/dist/components/Select/SelectCloseButton.d.ts.map +1 -0
  121. package/dist/components/Select/SelectCloseButton.js +17 -0
  122. package/dist/components/Select/SelectCloseButton.js.map +1 -0
  123. package/dist/components/Select/index.d.ts +6 -0
  124. package/dist/components/Select/index.d.ts.map +1 -0
  125. package/dist/components/Select/index.js +14 -0
  126. package/dist/components/Select/index.js.map +1 -0
  127. package/dist/components/Select/resolveSelectDetentIndex.d.ts +9 -0
  128. package/dist/components/Select/resolveSelectDetentIndex.d.ts.map +1 -0
  129. package/dist/components/Select/resolveSelectDetentIndex.js +16 -0
  130. package/dist/components/Select/resolveSelectDetentIndex.js.map +1 -0
  131. package/dist/components/Select/selectThemeRoles.d.ts +12 -0
  132. package/dist/components/Select/selectThemeRoles.d.ts.map +1 -0
  133. package/dist/components/Select/selectThemeRoles.js +14 -0
  134. package/dist/components/Select/selectThemeRoles.js.map +1 -0
  135. package/dist/components/Select/types.d.ts +35 -0
  136. package/dist/components/Select/types.d.ts.map +1 -0
  137. package/dist/components/Select/types.js +3 -0
  138. package/dist/components/Select/types.js.map +1 -0
  139. package/dist/components/index.d.ts +7 -0
  140. package/dist/components/index.d.ts.map +1 -0
  141. package/dist/components/index.js +27 -0
  142. package/dist/components/index.js.map +1 -0
  143. package/dist/index.d.ts +10 -0
  144. package/dist/index.d.ts.map +1 -0
  145. package/dist/index.js +66 -0
  146. package/dist/index.js.map +1 -0
  147. package/dist/layout/index.d.ts +2 -0
  148. package/dist/layout/index.d.ts.map +1 -0
  149. package/dist/layout/index.js +6 -0
  150. package/dist/layout/index.js.map +1 -0
  151. package/dist/layout/screenPadding.d.ts +3 -0
  152. package/dist/layout/screenPadding.d.ts.map +1 -0
  153. package/dist/layout/screenPadding.js +6 -0
  154. package/dist/layout/screenPadding.js.map +1 -0
  155. package/dist/theme/ThemeProvider.d.ts +11 -0
  156. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  157. package/dist/theme/ThemeProvider.js +11 -0
  158. package/dist/theme/ThemeProvider.js.map +1 -0
  159. package/dist/theme/index.d.ts +6 -0
  160. package/dist/theme/index.d.ts.map +1 -0
  161. package/dist/theme/index.js +12 -0
  162. package/dist/theme/index.js.map +1 -0
  163. package/dist/theme/resolveColorScheme.d.ts +2 -0
  164. package/dist/theme/resolveColorScheme.d.ts.map +1 -0
  165. package/dist/theme/resolveColorScheme.js +7 -0
  166. package/dist/theme/resolveColorScheme.js.map +1 -0
  167. package/dist/theme/types.d.ts +8 -0
  168. package/dist/theme/types.d.ts.map +1 -0
  169. package/dist/theme/types.js +3 -0
  170. package/dist/theme/types.js.map +1 -0
  171. package/dist/theme/useColorScheme.d.ts +2 -0
  172. package/dist/theme/useColorScheme.d.ts.map +1 -0
  173. package/dist/theme/useColorScheme.js +16 -0
  174. package/dist/theme/useColorScheme.js.map +1 -0
  175. package/dist/theme/useThemeColor.d.ts +5 -0
  176. package/dist/theme/useThemeColor.d.ts.map +1 -0
  177. package/dist/theme/useThemeColor.js +25 -0
  178. package/dist/theme/useThemeColor.js.map +1 -0
  179. package/docs/components/button.md +162 -0
  180. package/docs/components/field.md +128 -0
  181. package/docs/components/form.md +86 -0
  182. package/docs/components/link-blocks.md +120 -0
  183. package/docs/components/radio-field.md +100 -0
  184. package/docs/components/select.md +59 -0
  185. package/docs/superpowers/plans/2026-09-24-field.md +583 -0
  186. package/docs/superpowers/plans/2026-09-24-link-blocks.md +414 -0
  187. package/docs/superpowers/plans/2026-09-24-theme-provider-button.md +493 -0
  188. package/docs/superpowers/plans/2026-09-25-radio-field.md +516 -0
  189. package/docs/superpowers/plans/2026-09-25-select.md +22 -0
  190. package/docs/superpowers/specs/2026-09-24-field-design.md +205 -0
  191. package/docs/superpowers/specs/2026-09-24-link-blocks-design.md +167 -0
  192. package/docs/superpowers/specs/2026-09-24-theme-provider-button-design.md +178 -0
  193. package/docs/superpowers/specs/2026-09-25-radio-field-design.md +136 -0
  194. package/docs/superpowers/specs/2026-09-25-select-design.md +164 -0
  195. package/package.json +75 -0
  196. package/src/components/Button/Button.tsx +97 -0
  197. package/src/components/Button/buttonRadius.test.ts +16 -0
  198. package/src/components/Button/buttonRadius.ts +24 -0
  199. package/src/components/Button/index.ts +2 -0
  200. package/src/components/Field/FieldText.tsx +6 -0
  201. package/src/components/Field/FieldTextarea.tsx +18 -0
  202. package/src/components/Field/fieldChrome.tsx +219 -0
  203. package/src/components/Field/fieldThemeRoles.ts +13 -0
  204. package/src/components/Field/index.ts +5 -0
  205. package/src/components/Field/resolveFieldBorder.test.ts +76 -0
  206. package/src/components/Field/resolveFieldBorder.ts +40 -0
  207. package/src/components/Field/resolveFieldColor.test.ts +92 -0
  208. package/src/components/Field/resolveFieldColor.ts +26 -0
  209. package/src/components/Field/types.ts +53 -0
  210. package/src/components/Field/useResolvedFieldColor.ts +15 -0
  211. package/src/components/Form/Form.tsx +205 -0
  212. package/src/components/Form/FormCloseButton.tsx +19 -0
  213. package/src/components/Form/index.ts +3 -0
  214. package/src/components/Form/resolveThemeColor.ts +24 -0
  215. package/src/components/Form/types.ts +30 -0
  216. package/src/components/Form/useResolvedThemeColor.ts +15 -0
  217. package/src/components/Form/withAlpha.test.ts +13 -0
  218. package/src/components/Form/withAlpha.ts +9 -0
  219. package/src/components/LinkBlocks/LinkBlocks.tsx +165 -0
  220. package/src/components/LinkBlocks/filterGroups.test.ts +37 -0
  221. package/src/components/LinkBlocks/filterGroups.ts +7 -0
  222. package/src/components/LinkBlocks/index.ts +7 -0
  223. package/src/components/LinkBlocks/types.ts +28 -0
  224. package/src/components/RadioField/RadioField.tsx +168 -0
  225. package/src/components/RadioField/RadioMark.tsx +54 -0
  226. package/src/components/RadioField/index.ts +3 -0
  227. package/src/components/RadioField/radioThemeRoles.test.ts +15 -0
  228. package/src/components/RadioField/radioThemeRoles.ts +11 -0
  229. package/src/components/RadioField/types.ts +25 -0
  230. package/src/components/Select/Select.tsx +279 -0
  231. package/src/components/Select/SelectCloseButton.tsx +19 -0
  232. package/src/components/Select/index.ts +13 -0
  233. package/src/components/Select/resolveSelectDetentIndex.test.ts +20 -0
  234. package/src/components/Select/resolveSelectDetentIndex.ts +16 -0
  235. package/src/components/Select/selectThemeRoles.ts +12 -0
  236. package/src/components/Select/types.ts +39 -0
  237. package/src/components/index.ts +42 -0
  238. package/src/index.ts +50 -0
  239. package/src/layout/index.ts +1 -0
  240. package/src/layout/screenPadding.ts +2 -0
  241. package/src/theme/ThemeProvider.tsx +20 -0
  242. package/src/theme/index.ts +5 -0
  243. package/src/theme/resolveColorScheme.test.ts +16 -0
  244. package/src/theme/resolveColorScheme.ts +5 -0
  245. package/src/theme/types.ts +5 -0
  246. package/src/theme/useColorScheme.ts +13 -0
  247. package/src/theme/useThemeColor.ts +25 -0
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveSelectDetentIndex = exports.DEFAULT_SELECT_INITIAL_DETENT = exports.DEFAULT_SELECT_DETENTS = exports.SELECT_THEME_ROLES = exports.SelectCloseButton = exports.Select = exports.RADIO_THEME_ROLES = exports.RadioField = exports.FormCloseButton = exports.Form = exports.FIELD_THEME_ROLES = exports.FieldTextarea = exports.FieldText = exports.filterLinkBlockGroups = exports.LinkBlocks = exports.buttonRadiusValue = exports.Button = void 0;
4
+ var Button_1 = require("./Button");
5
+ Object.defineProperty(exports, "Button", { enumerable: true, get: function () { return Button_1.Button; } });
6
+ Object.defineProperty(exports, "buttonRadiusValue", { enumerable: true, get: function () { return Button_1.buttonRadiusValue; } });
7
+ var LinkBlocks_1 = require("./LinkBlocks");
8
+ Object.defineProperty(exports, "LinkBlocks", { enumerable: true, get: function () { return LinkBlocks_1.LinkBlocks; } });
9
+ Object.defineProperty(exports, "filterLinkBlockGroups", { enumerable: true, get: function () { return LinkBlocks_1.filterLinkBlockGroups; } });
10
+ var Field_1 = require("./Field");
11
+ Object.defineProperty(exports, "FieldText", { enumerable: true, get: function () { return Field_1.FieldText; } });
12
+ Object.defineProperty(exports, "FieldTextarea", { enumerable: true, get: function () { return Field_1.FieldTextarea; } });
13
+ Object.defineProperty(exports, "FIELD_THEME_ROLES", { enumerable: true, get: function () { return Field_1.FIELD_THEME_ROLES; } });
14
+ var Form_1 = require("./Form");
15
+ Object.defineProperty(exports, "Form", { enumerable: true, get: function () { return Form_1.Form; } });
16
+ Object.defineProperty(exports, "FormCloseButton", { enumerable: true, get: function () { return Form_1.FormCloseButton; } });
17
+ var RadioField_1 = require("./RadioField");
18
+ Object.defineProperty(exports, "RadioField", { enumerable: true, get: function () { return RadioField_1.RadioField; } });
19
+ Object.defineProperty(exports, "RADIO_THEME_ROLES", { enumerable: true, get: function () { return RadioField_1.RADIO_THEME_ROLES; } });
20
+ var Select_1 = require("./Select");
21
+ Object.defineProperty(exports, "Select", { enumerable: true, get: function () { return Select_1.Select; } });
22
+ Object.defineProperty(exports, "SelectCloseButton", { enumerable: true, get: function () { return Select_1.SelectCloseButton; } });
23
+ Object.defineProperty(exports, "SELECT_THEME_ROLES", { enumerable: true, get: function () { return Select_1.SELECT_THEME_ROLES; } });
24
+ Object.defineProperty(exports, "DEFAULT_SELECT_DETENTS", { enumerable: true, get: function () { return Select_1.DEFAULT_SELECT_DETENTS; } });
25
+ Object.defineProperty(exports, "DEFAULT_SELECT_INITIAL_DETENT", { enumerable: true, get: function () { return Select_1.DEFAULT_SELECT_INITIAL_DETENT; } });
26
+ Object.defineProperty(exports, "resolveSelectDetentIndex", { enumerable: true, get: function () { return Select_1.resolveSelectDetentIndex; } });
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":";;;AAAA,mCAKkB;AAJhB,gGAAA,MAAM,OAAA;AAEN,2GAAA,iBAAiB,OAAA;AAGnB,2CAMsB;AALpB,wGAAA,UAAU,OAAA;AACV,mHAAA,qBAAqB,OAAA;AAKvB,iCAQiB;AAPf,kGAAA,SAAS,OAAA;AACT,sGAAA,aAAa,OAAA;AACb,0GAAA,iBAAiB,OAAA;AAMnB,+BAA+D;AAAtD,4FAAA,IAAI,OAAA;AAAE,uGAAA,eAAe,OAAA;AAC9B,2CAMsB;AALpB,wGAAA,UAAU,OAAA;AACV,+GAAA,iBAAiB,OAAA;AAKnB,mCAWkB;AAVhB,gGAAA,MAAM,OAAA;AACN,2GAAA,iBAAiB,OAAA;AACjB,4GAAA,kBAAkB,OAAA;AAClB,gHAAA,sBAAsB,OAAA;AACtB,uHAAA,6BAA6B,OAAA;AAC7B,kHAAA,wBAAwB,OAAA"}
@@ -0,0 +1,10 @@
1
+ export declare const version = "0.1.0";
2
+ export * from "./theme";
3
+ export { Button, type ButtonProps, buttonRadiusValue, type ButtonRadius, } from "./components/Button";
4
+ export { LinkBlocks, filterLinkBlockGroups, type LinkBlockGroup, type LinkBlockItem, type LinkBlocksProps, } from "./components/LinkBlocks";
5
+ export { FieldText, FieldTextarea, FIELD_THEME_ROLES, type FieldThemeColorProp, type FieldSharedProps, type FieldTextProps, type FieldTextareaProps, } from "./components/Field";
6
+ export { Form, FormCloseButton, type FormProps, } from "./components/Form";
7
+ export { RadioField, RADIO_THEME_ROLES, type RadioThemeColorProp, type RadioOption, type RadioFieldProps, } from "./components/RadioField";
8
+ export { Select, SelectCloseButton, SELECT_THEME_ROLES, DEFAULT_SELECT_DETENTS, DEFAULT_SELECT_INITIAL_DETENT, resolveSelectDetentIndex, type SelectThemeColorProp, type SelectOption, type SelectProps, type SelectCloseButtonProp, } from "./components/Select";
9
+ export * as components from "./components";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,MAAM,EACN,KAAK,WAAW,EAChB,iBAAiB,EACjB,KAAK,YAAY,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,IAAI,EACJ,eAAe,EACf,KAAK,SAAS,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,6BAA6B,EAC7B,wBAAwB,EACxB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
19
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
20
+ };
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.components = exports.resolveSelectDetentIndex = exports.DEFAULT_SELECT_INITIAL_DETENT = exports.DEFAULT_SELECT_DETENTS = exports.SELECT_THEME_ROLES = exports.SelectCloseButton = exports.Select = exports.RADIO_THEME_ROLES = exports.RadioField = exports.FormCloseButton = exports.Form = exports.FIELD_THEME_ROLES = exports.FieldTextarea = exports.FieldText = exports.filterLinkBlockGroups = exports.LinkBlocks = exports.buttonRadiusValue = exports.Button = exports.version = void 0;
40
+ exports.version = "0.1.0";
41
+ __exportStar(require("./theme"), exports);
42
+ var Button_1 = require("./components/Button");
43
+ Object.defineProperty(exports, "Button", { enumerable: true, get: function () { return Button_1.Button; } });
44
+ Object.defineProperty(exports, "buttonRadiusValue", { enumerable: true, get: function () { return Button_1.buttonRadiusValue; } });
45
+ var LinkBlocks_1 = require("./components/LinkBlocks");
46
+ Object.defineProperty(exports, "LinkBlocks", { enumerable: true, get: function () { return LinkBlocks_1.LinkBlocks; } });
47
+ Object.defineProperty(exports, "filterLinkBlockGroups", { enumerable: true, get: function () { return LinkBlocks_1.filterLinkBlockGroups; } });
48
+ var Field_1 = require("./components/Field");
49
+ Object.defineProperty(exports, "FieldText", { enumerable: true, get: function () { return Field_1.FieldText; } });
50
+ Object.defineProperty(exports, "FieldTextarea", { enumerable: true, get: function () { return Field_1.FieldTextarea; } });
51
+ Object.defineProperty(exports, "FIELD_THEME_ROLES", { enumerable: true, get: function () { return Field_1.FIELD_THEME_ROLES; } });
52
+ var Form_1 = require("./components/Form");
53
+ Object.defineProperty(exports, "Form", { enumerable: true, get: function () { return Form_1.Form; } });
54
+ Object.defineProperty(exports, "FormCloseButton", { enumerable: true, get: function () { return Form_1.FormCloseButton; } });
55
+ var RadioField_1 = require("./components/RadioField");
56
+ Object.defineProperty(exports, "RadioField", { enumerable: true, get: function () { return RadioField_1.RadioField; } });
57
+ Object.defineProperty(exports, "RADIO_THEME_ROLES", { enumerable: true, get: function () { return RadioField_1.RADIO_THEME_ROLES; } });
58
+ var Select_1 = require("./components/Select");
59
+ Object.defineProperty(exports, "Select", { enumerable: true, get: function () { return Select_1.Select; } });
60
+ Object.defineProperty(exports, "SelectCloseButton", { enumerable: true, get: function () { return Select_1.SelectCloseButton; } });
61
+ Object.defineProperty(exports, "SELECT_THEME_ROLES", { enumerable: true, get: function () { return Select_1.SELECT_THEME_ROLES; } });
62
+ Object.defineProperty(exports, "DEFAULT_SELECT_DETENTS", { enumerable: true, get: function () { return Select_1.DEFAULT_SELECT_DETENTS; } });
63
+ Object.defineProperty(exports, "DEFAULT_SELECT_INITIAL_DETENT", { enumerable: true, get: function () { return Select_1.DEFAULT_SELECT_INITIAL_DETENT; } });
64
+ Object.defineProperty(exports, "resolveSelectDetentIndex", { enumerable: true, get: function () { return Select_1.resolveSelectDetentIndex; } });
65
+ exports.components = __importStar(require("./components"));
66
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAa,QAAA,OAAO,GAAG,OAAO,CAAC;AAE/B,0CAAwB;AACxB,8CAK6B;AAJ3B,gGAAA,MAAM,OAAA;AAEN,2GAAA,iBAAiB,OAAA;AAGnB,sDAMiC;AAL/B,wGAAA,UAAU,OAAA;AACV,mHAAA,qBAAqB,OAAA;AAKvB,4CAQ4B;AAP1B,kGAAA,SAAS,OAAA;AACT,sGAAA,aAAa,OAAA;AACb,0GAAA,iBAAiB,OAAA;AAMnB,0CAI2B;AAHzB,4FAAA,IAAI,OAAA;AACJ,uGAAA,eAAe,OAAA;AAGjB,sDAMiC;AAL/B,wGAAA,UAAU,OAAA;AACV,+GAAA,iBAAiB,OAAA;AAKnB,8CAW6B;AAV3B,gGAAA,MAAM,OAAA;AACN,2GAAA,iBAAiB,OAAA;AACjB,4GAAA,kBAAkB,OAAA;AAClB,gHAAA,sBAAsB,OAAA;AACtB,uHAAA,6BAA6B,OAAA;AAC7B,kHAAA,wBAAwB,OAAA;AAM1B,2DAA2C"}
@@ -0,0 +1,2 @@
1
+ export { screenPaddingHorizontal } from "./screenPadding";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.screenPaddingHorizontal = void 0;
4
+ var screenPadding_1 = require("./screenPadding");
5
+ Object.defineProperty(exports, "screenPaddingHorizontal", { enumerable: true, get: function () { return screenPadding_1.screenPaddingHorizontal; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":";;;AAAA,iDAA0D;AAAjD,wHAAA,uBAAuB,OAAA"}
@@ -0,0 +1,3 @@
1
+ /** Default inset from screen edges for Form header, content, and footer. */
2
+ export declare const screenPaddingHorizontal = 16;
3
+ //# sourceMappingURL=screenPadding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenPadding.d.ts","sourceRoot":"","sources":["../../src/layout/screenPadding.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,KAAK,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.screenPaddingHorizontal = void 0;
4
+ /** Default inset from screen edges for Form header, content, and footer. */
5
+ exports.screenPaddingHorizontal = 16;
6
+ //# sourceMappingURL=screenPadding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenPadding.js","sourceRoot":"","sources":["../../src/layout/screenPadding.ts"],"names":[],"mappings":";;;AAAA,4EAA4E;AAC/D,QAAA,uBAAuB,GAAG,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type ReactNode } from "react";
2
+ import type { ThemeColors, ThemeContextValue } from "./types";
3
+ export declare const ThemeContext: import("react").Context<ThemeContextValue | null>;
4
+ export declare function ThemeProvider({ colors, children, }: {
5
+ colors: {
6
+ light: ThemeColors;
7
+ dark: ThemeColors;
8
+ };
9
+ children: ReactNode;
10
+ }): import("react").FunctionComponentElement<import("react").ProviderProps<ThemeContextValue | null>>;
11
+ //# sourceMappingURL=ThemeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../src/theme/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE9D,eAAO,MAAM,YAAY,mDAAgD,CAAC;AAE1E,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,QAAQ,GACT,EAAE;IACD,MAAM,EAAE;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;IAClD,QAAQ,EAAE,SAAS,CAAC;CACrB,qGAGA"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ThemeContext = void 0;
4
+ exports.ThemeProvider = ThemeProvider;
5
+ const react_1 = require("react");
6
+ exports.ThemeContext = (0, react_1.createContext)(null);
7
+ function ThemeProvider({ colors, children, }) {
8
+ const value = (0, react_1.useMemo)(() => ({ colors }), [colors]);
9
+ return (0, react_1.createElement)(exports.ThemeContext.Provider, { value }, children);
10
+ }
11
+ //# sourceMappingURL=ThemeProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeProvider.js","sourceRoot":"","sources":["../../src/theme/ThemeProvider.tsx"],"names":[],"mappings":";;;AAUA,sCASC;AAnBD,iCAKe;AAGF,QAAA,YAAY,GAAG,IAAA,qBAAa,EAA2B,IAAI,CAAC,CAAC;AAE1E,SAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,QAAQ,GAIT;IACC,MAAM,KAAK,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACpD,OAAO,IAAA,qBAAa,EAAC,oBAAY,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,6 @@
1
+ export type { ThemeColors, ThemeContextValue } from "./types";
2
+ export { ThemeProvider } from "./ThemeProvider";
3
+ export { useColorScheme } from "./useColorScheme";
4
+ export { useThemeColor } from "./useThemeColor";
5
+ export { resolveColorScheme } from "./resolveColorScheme";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveColorScheme = exports.useThemeColor = exports.useColorScheme = exports.ThemeProvider = void 0;
4
+ var ThemeProvider_1 = require("./ThemeProvider");
5
+ Object.defineProperty(exports, "ThemeProvider", { enumerable: true, get: function () { return ThemeProvider_1.ThemeProvider; } });
6
+ var useColorScheme_1 = require("./useColorScheme");
7
+ Object.defineProperty(exports, "useColorScheme", { enumerable: true, get: function () { return useColorScheme_1.useColorScheme; } });
8
+ var useThemeColor_1 = require("./useThemeColor");
9
+ Object.defineProperty(exports, "useThemeColor", { enumerable: true, get: function () { return useThemeColor_1.useThemeColor; } });
10
+ var resolveColorScheme_1 = require("./resolveColorScheme");
11
+ Object.defineProperty(exports, "resolveColorScheme", { enumerable: true, get: function () { return resolveColorScheme_1.resolveColorScheme; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":";;;AACA,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA"}
@@ -0,0 +1,2 @@
1
+ export declare function resolveColorScheme(scheme: string | null | undefined): "light" | "dark";
2
+ //# sourceMappingURL=resolveColorScheme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveColorScheme.d.ts","sourceRoot":"","sources":["../../src/theme/resolveColorScheme.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAChC,OAAO,GAAG,MAAM,CAElB"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveColorScheme = resolveColorScheme;
4
+ function resolveColorScheme(scheme) {
5
+ return scheme === "dark" ? "dark" : "light";
6
+ }
7
+ //# sourceMappingURL=resolveColorScheme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveColorScheme.js","sourceRoot":"","sources":["../../src/theme/resolveColorScheme.ts"],"names":[],"mappings":";;AAAA,gDAIC;AAJD,SAAgB,kBAAkB,CAChC,MAAiC;IAEjC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,8 @@
1
+ export type ThemeColors = Record<string, string>;
2
+ export type ThemeContextValue = {
3
+ colors: {
4
+ light: ThemeColors;
5
+ dark: ThemeColors;
6
+ };
7
+ };
8
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/theme/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;CACnD,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/theme/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare function useColorScheme(): "light" | "dark";
2
+ //# sourceMappingURL=useColorScheme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useColorScheme.d.ts","sourceRoot":"","sources":["../../src/theme/useColorScheme.ts"],"names":[],"mappings":"AAKA,wBAAgB,cAAc,IAAI,OAAO,GAAG,MAAM,CAOjD"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useColorScheme = useColorScheme;
4
+ const react_1 = require("react");
5
+ const react_native_1 = require("react-native");
6
+ const resolveColorScheme_1 = require("./resolveColorScheme");
7
+ const ThemeProvider_1 = require("./ThemeProvider");
8
+ function useColorScheme() {
9
+ const ctx = (0, react_1.useContext)(ThemeProvider_1.ThemeContext);
10
+ const systemScheme = (0, react_native_1.useColorScheme)();
11
+ if (!ctx) {
12
+ throw new Error("useColorScheme must be used within ThemeProvider");
13
+ }
14
+ return (0, resolveColorScheme_1.resolveColorScheme)(systemScheme);
15
+ }
16
+ //# sourceMappingURL=useColorScheme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useColorScheme.js","sourceRoot":"","sources":["../../src/theme/useColorScheme.ts"],"names":[],"mappings":";;AAKA,wCAOC;AAZD,iCAAmC;AACnC,+CAAsE;AACtE,6DAA0D;AAC1D,mDAA+C;AAE/C,SAAgB,cAAc;IAC5B,MAAM,GAAG,GAAG,IAAA,kBAAU,EAAC,4BAAY,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,IAAA,6BAAoB,GAAE,CAAC;IAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,IAAA,uCAAkB,EAAC,YAAY,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function useThemeColor(colorName: string, overrides?: {
2
+ light?: string;
3
+ dark?: string;
4
+ }): string;
5
+ //# sourceMappingURL=useThemeColor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useThemeColor.d.ts","sourceRoot":"","sources":["../../src/theme/useThemeColor.ts"],"names":[],"mappings":"AAKA,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,MAAM,CAgBR"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useThemeColor = useThemeColor;
4
+ const react_1 = require("react");
5
+ const react_native_1 = require("react-native");
6
+ const resolveColorScheme_1 = require("./resolveColorScheme");
7
+ const ThemeProvider_1 = require("./ThemeProvider");
8
+ function useThemeColor(colorName, overrides) {
9
+ const ctx = (0, react_1.useContext)(ThemeProvider_1.ThemeContext);
10
+ const systemScheme = (0, react_native_1.useColorScheme)();
11
+ if (!ctx) {
12
+ throw new Error("useThemeColor must be used within ThemeProvider");
13
+ }
14
+ const scheme = (0, resolveColorScheme_1.resolveColorScheme)(systemScheme);
15
+ const override = overrides?.[scheme];
16
+ if (override != null) {
17
+ return override;
18
+ }
19
+ const value = ctx.colors[scheme][colorName];
20
+ if (value == null) {
21
+ throw new Error(`Unknown theme colour "${colorName}" for scheme "${scheme}"`);
22
+ }
23
+ return value;
24
+ }
25
+ //# sourceMappingURL=useThemeColor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useThemeColor.js","sourceRoot":"","sources":["../../src/theme/useThemeColor.ts"],"names":[],"mappings":";;AAKA,sCAmBC;AAxBD,iCAAmC;AACnC,+CAAsE;AACtE,6DAA0D;AAC1D,mDAA+C;AAE/C,SAAgB,aAAa,CAC3B,SAAiB,EACjB,SAA6C;IAE7C,MAAM,GAAG,GAAG,IAAA,kBAAU,EAAC,4BAAY,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,IAAA,6BAAoB,GAAE,CAAC;IAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,uCAAkB,EAAC,YAAY,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QACrB,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,yBAAyB,SAAS,iBAAiB,MAAM,GAAG,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,162 @@
1
+ # Theme provider and Button — usage
2
+
3
+ How to theme an app with `@studio-piot/native-ui` and use `Button`.
4
+
5
+ For the design contract, see [the theme provider and Button design](../superpowers/specs/2026-09-24-theme-provider-button-design.md).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @studio-piot/native-ui
11
+ ```
12
+
13
+ `react` and `react-native` are peer dependencies.
14
+
15
+ ## Theme
16
+
17
+ The package does not ship a palette. Your app owns colour roles. Mount `ThemeProvider` near the root with light and dark maps that share the same keys:
18
+
19
+ ```tsx
20
+ import { ThemeProvider } from "@studio-piot/native-ui";
21
+ import { Colors } from "./config/colors";
22
+
23
+ export function Root({ children }: { children: React.ReactNode }) {
24
+ return <ThemeProvider colors={Colors}>{children}</ThemeProvider>;
25
+ }
26
+ ```
27
+
28
+ ```ts
29
+ // Example app colours — role names are yours
30
+ export const Colors = {
31
+ light: {
32
+ buttonBackground: "#FF4F16",
33
+ buttonLabel: "#22201D",
34
+ },
35
+ dark: {
36
+ buttonBackground: "#FF4F16",
37
+ buttonLabel: "#22201D",
38
+ },
39
+ } as const;
40
+ ```
41
+
42
+ ### `useThemeColor`
43
+
44
+ Resolves a role for the current scheme (React Native `useColorScheme`; anything other than `"dark"` is light):
45
+
46
+ ```tsx
47
+ import { useThemeColor } from "@studio-piot/native-ui";
48
+
49
+ const backgroundColor = useThemeColor("buttonBackground");
50
+ const labelColor = useThemeColor("buttonLabel");
51
+ ```
52
+
53
+ Optional overrides for one scheme:
54
+
55
+ ```tsx
56
+ useThemeColor("buttonBackground", { dark: "#000000" });
57
+ ```
58
+
59
+ Must be used inside `ThemeProvider`. A missing role throws.
60
+
61
+ ### `useColorScheme`
62
+
63
+ ```tsx
64
+ import { useColorScheme } from "@studio-piot/native-ui";
65
+
66
+ const scheme = useColorScheme(); // "light" | "dark"
67
+ ```
68
+
69
+ The package does not store preferences or call `Appearance.setColorScheme`. If your app overrides the window appearance, do that yourself; these hooks will follow the resolved scheme.
70
+
71
+ ## Button
72
+
73
+ `Button` is presentational. Pass the colours you want. Full width of its parent is fixed.
74
+
75
+ ```tsx
76
+ import { Button, useThemeColor } from "@studio-piot/native-ui";
77
+
78
+ export function SaveButton({ onPress }: { onPress: () => void }) {
79
+ return (
80
+ <Button
81
+ label="Save"
82
+ onPress={onPress}
83
+ backgroundColor={useThemeColor("buttonBackground")}
84
+ labelColor={useThemeColor("buttonLabel")}
85
+ />
86
+ );
87
+ }
88
+ ```
89
+
90
+ ### Props
91
+
92
+ | Prop | Type | Default | Notes |
93
+ |---|---|---|---|
94
+ | `label` | `string` | — | Required |
95
+ | `onPress` | `() => void` | — | Required |
96
+ | `backgroundColor` | `string` | — | Required. Filled: fill. Outline: border + label |
97
+ | `labelColor` | `string` | — | Required. Filled: label + spinner |
98
+ | `variant` | `"filled" \| "outline"` | `"filled"` | |
99
+ | `radius` | see below | `"xl"` | Tailwind-style steps |
100
+ | `disabled` | `boolean` | `false` | Opacity treatment; same colours |
101
+ | `loading` | `boolean` | `false` | Spinner instead of label; non-interactive |
102
+ | `style` | view style | — | Merged after the shell |
103
+ | `labelStyle` | text style | — | Merged after the label |
104
+
105
+ ### Variants
106
+
107
+ - **filled** — `backgroundColor` fill, `labelColor` text/spinner
108
+ - **outline** — transparent fill, border and label from `backgroundColor`. `labelColor` is still required but unused for the outline label; the outline spinner uses `backgroundColor`.
109
+
110
+ ### Radius
111
+
112
+ | Value | Border radius |
113
+ |---|---|
114
+ | `none` | `0` |
115
+ | `sm` | `2` |
116
+ | `md` | `6` |
117
+ | `lg` | `8` |
118
+ | `xl` | `12` (default) |
119
+ | `2xl` | `16` |
120
+ | `3xl` | `24` |
121
+ | `full` | pill (`999`) |
122
+
123
+ ```tsx
124
+ <Button
125
+ label="Continue"
126
+ onPress={onContinue}
127
+ backgroundColor={backgroundColor}
128
+ labelColor={labelColor}
129
+ radius="full"
130
+ variant="outline"
131
+ />
132
+ ```
133
+
134
+ ### Loading and disabled
135
+
136
+ ```tsx
137
+ <Button
138
+ label="Saving…"
139
+ onPress={onSave}
140
+ backgroundColor={backgroundColor}
141
+ labelColor={labelColor}
142
+ loading={isSaving}
143
+ disabled={!canSave}
144
+ />
145
+ ```
146
+
147
+ When `loading` or `disabled` is true, the control does not fire `onPress` and uses reduced opacity.
148
+
149
+ ## Imports
150
+
151
+ ```ts
152
+ import {
153
+ Button,
154
+ ThemeProvider,
155
+ useColorScheme,
156
+ useThemeColor,
157
+ version,
158
+ } from "@studio-piot/native-ui";
159
+
160
+ // Or components only:
161
+ import { Button } from "@studio-piot/native-ui/components";
162
+ ```
@@ -0,0 +1,128 @@
1
+ # Field — usage
2
+
3
+ Presentational single-line and multiline text inputs with optional label, description, focus and error chrome, and an optional clear affordance. Colours default from `ThemeProvider`; pass props only to override. Your app owns icons and form state.
4
+
5
+ For the design contract, see [Field design](../superpowers/specs/2026-09-24-field-design.md).
6
+
7
+ For `ThemeProvider` and `useThemeColor`, see [theme provider and Button usage](./button.md).
8
+
9
+ ## FieldText and FieldTextarea
10
+
11
+ `FieldText` and `FieldTextarea` are controlled only (`value` + `onChangeText`). When colour props are omitted, Field reads fixed roles from `ThemeProvider` (see below). Explicit colour props always win. `ThemeProvider` is required only when at least one colour prop is omitted. Full width of the parent is fixed. The package does not import icon libraries; pass `clearIcon` as an opaque `ReactNode` when you want a clear control.
12
+
13
+ ```tsx
14
+ import { FieldText, FieldTextarea, useThemeColor } from "@studio-piot/native-ui";
15
+ import Ionicons from "@expo/vector-icons/Ionicons";
16
+ import { useState } from "react";
17
+
18
+ export function ProfileFields() {
19
+ const [email, setEmail] = useState("");
20
+ const [notes, setNotes] = useState("");
21
+ const emailError =
22
+ email.length > 0 && !email.includes("@") ? "Enter a valid email" : undefined;
23
+ const textSecondary = useThemeColor("textSecondary");
24
+
25
+ return (
26
+ <>
27
+ <FieldText
28
+ label="Email"
29
+ value={email}
30
+ onChangeText={setEmail}
31
+ placeholder="you@example.com"
32
+ description="Used for login and receipts."
33
+ error={emailError}
34
+ keyboardType="email-address"
35
+ autoCapitalize="none"
36
+ clearIcon={
37
+ <Ionicons name="close-circle" size={20} color={textSecondary} />
38
+ }
39
+ />
40
+
41
+ <FieldTextarea
42
+ label="Notes"
43
+ value={notes}
44
+ onChangeText={setNotes}
45
+ />
46
+ </>
47
+ );
48
+ }
49
+ ```
50
+
51
+ Your `ThemeProvider` colour maps must include the default roles listed below (same keys in light and dark).
52
+
53
+ ### Colour props (optional overrides)
54
+
55
+ | Prop | Default theme role | Role |
56
+ |---|---|---|
57
+ | `borderColor` | `fieldBorder` | Resting border |
58
+ | `focusedBorderColor` | `fieldFocusedBorder` | Focused border when there is no error |
59
+ | `errorColor` | `fieldError` | Error border and error message text |
60
+ | `textColor` | `fieldText` | Input value |
61
+ | `labelColor` | `fieldLabel` | Label above the input |
62
+ | `placeholderColor` | `fieldPlaceholder` | Placeholder |
63
+ | `backgroundColor` | `fieldBackground` | Input fill |
64
+
65
+ Optional helper text uses theme role `fieldDescription`. When `error` is set, the error message replaces the description under the input.
66
+
67
+ ### Shared props
68
+
69
+ | Prop | Type | Default | Notes |
70
+ |---|---|---|---|
71
+ | `value` | `string` | — | Required. Controlled |
72
+ | `onChangeText` | `(text: string) => void` | — | Required |
73
+ | `borderColor` | `string` | theme `fieldBorder` | Optional override |
74
+ | `focusedBorderColor` | `string` | theme `fieldFocusedBorder` | Optional override |
75
+ | `errorColor` | `string` | theme `fieldError` | Optional override |
76
+ | `textColor` | `string` | theme `fieldText` | Optional override |
77
+ | `labelColor` | `string` | theme `fieldLabel` | Optional override |
78
+ | `placeholderColor` | `string` | theme `fieldPlaceholder` | Optional override |
79
+ | `backgroundColor` | `string` | theme `fieldBackground` | Optional override |
80
+ | `label` | `string` | — | Caption above the input |
81
+ | `description` | `string` | — | Helper under the input; hidden while `error` is set |
82
+ | `error` | `string` | — | Shown under the input; non-empty string drives error border |
83
+ | `placeholder` | `string` | — | |
84
+ | `radius` | `ButtonRadius` | `"xl"` | Same steps as `Button` |
85
+ | `editable` | `boolean` | `true` | `false` → reduced opacity (same treatment as `Button`) |
86
+ | `clearIcon` | `React.ReactNode` | — | Clear shown only with non-empty `value`, this prop, and `editable` |
87
+ | `onClear` | `() => void` | calls `onChangeText("")` | If you pass `onClear`, you must clear the value yourself (e.g. `setState("")`); the component does not also call `onChangeText("")`. |
88
+ | `style` | view style | — | Outer column |
89
+ | `inputStyle` | text style | — | Merged onto `TextInput` |
90
+
91
+ Common `TextInput` passthroughs are supported (e.g. `secureTextEntry`, `keyboardType`, `autoCapitalize`, `autoComplete`, `textContentType`, `onFocus`, `onBlur`, `ref`). Pass `editable` as-is — do not invert it.
92
+
93
+ ### FieldTextarea extras
94
+
95
+ | Prop | Type | Default | Notes |
96
+ |---|---|---|---|
97
+ | `numberOfLines` | `number` | `4` | Drives minimum height; always multiline, top-aligned text |
98
+
99
+ ### Focus, error, and clear
100
+
101
+ - **Resting** — `borderWidth: 1`, colour `borderColor`.
102
+ - **Focused (no error)** — `borderWidth: 2`, colour `focusedBorderColor`. Horizontal padding is reduced by 1 so the control does not grow when the stroke doubles.
103
+ - **Error** — When `error` is a non-empty string, the border uses `errorColor` and the message renders below the input in `errorColor`. If the field is also focused, error colour still wins and the double stroke remains. Error replaces the description when both would show.
104
+ - **Clear** — Visible only when `value` is non-empty, `clearIcon` is provided, and the field is `editable`. Tapping clear runs `onClear` if provided; otherwise the default handler calls `onChangeText("")`. When you supply `onClear`, clearing the controlled value is your responsibility. Extra trailing padding keeps text from overlapping the control.
105
+
106
+ ### Radius
107
+
108
+ Uses the same Tailwind-style steps as `Button` (`buttonRadiusValue`). Default `"xl"` (12px). See the [Button radius table](./button.md#radius).
109
+
110
+ ### Accessibility
111
+
112
+ When `label` is set, it is used for the input’s accessibility label. Error text is exposed to assistive tech. The clear control has an accessibility label (e.g. “Clear”).
113
+
114
+ ## Imports
115
+
116
+ ```ts
117
+ import {
118
+ FieldText,
119
+ FieldTextarea,
120
+ FIELD_THEME_ROLES,
121
+ type FieldSharedProps,
122
+ type FieldTextProps,
123
+ type FieldTextareaProps,
124
+ } from "@studio-piot/native-ui";
125
+
126
+ // Or components only:
127
+ import { FieldText, FieldTextarea } from "@studio-piot/native-ui/components";
128
+ ```