@tribepad/themis 1.5.8 → 1.6.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 (233) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/elements/AlertDialog/index.js +1 -1
  3. package/dist/elements/AlertDialog/index.js.map +1 -1
  4. package/dist/elements/AlertDialog/index.mjs +1 -1
  5. package/dist/elements/AlertDialog/index.mjs.map +1 -1
  6. package/dist/elements/Badge/index.js +1 -1
  7. package/dist/elements/Badge/index.js.map +1 -1
  8. package/dist/elements/Badge/index.mjs +1 -1
  9. package/dist/elements/Badge/index.mjs.map +1 -1
  10. package/dist/elements/Breadcrumbs/index.js +1 -1
  11. package/dist/elements/Breadcrumbs/index.js.map +1 -1
  12. package/dist/elements/Breadcrumbs/index.mjs +1 -1
  13. package/dist/elements/Breadcrumbs/index.mjs.map +1 -1
  14. package/dist/elements/Button/index.js +1 -1
  15. package/dist/elements/Button/index.js.map +1 -1
  16. package/dist/elements/Button/index.mjs +1 -1
  17. package/dist/elements/Button/index.mjs.map +1 -1
  18. package/dist/elements/Card/index.js +1 -1
  19. package/dist/elements/Card/index.js.map +1 -1
  20. package/dist/elements/Card/index.mjs +1 -1
  21. package/dist/elements/Card/index.mjs.map +1 -1
  22. package/dist/elements/Carousel/index.js +1 -1
  23. package/dist/elements/Carousel/index.js.map +1 -1
  24. package/dist/elements/Carousel/index.mjs +1 -1
  25. package/dist/elements/Carousel/index.mjs.map +1 -1
  26. package/dist/elements/Chart/index.js +1 -1
  27. package/dist/elements/Chart/index.js.map +1 -1
  28. package/dist/elements/Chart/index.mjs +1 -1
  29. package/dist/elements/Chart/index.mjs.map +1 -1
  30. package/dist/elements/ChatInterface/index.js +1 -1
  31. package/dist/elements/ChatInterface/index.js.map +1 -1
  32. package/dist/elements/ChatInterface/index.mjs +1 -1
  33. package/dist/elements/ChatInterface/index.mjs.map +1 -1
  34. package/dist/elements/Checkbox/Checkbox.d.ts.map +1 -1
  35. package/dist/elements/Checkbox/index.js +1 -1
  36. package/dist/elements/Checkbox/index.js.map +1 -1
  37. package/dist/elements/Checkbox/index.mjs +1 -1
  38. package/dist/elements/Checkbox/index.mjs.map +1 -1
  39. package/dist/elements/CheckboxGroup/index.js +1 -1
  40. package/dist/elements/CheckboxGroup/index.js.map +1 -1
  41. package/dist/elements/CheckboxGroup/index.mjs +1 -1
  42. package/dist/elements/CheckboxGroup/index.mjs.map +1 -1
  43. package/dist/elements/ColorPicker/index.js +1 -1
  44. package/dist/elements/ColorPicker/index.js.map +1 -1
  45. package/dist/elements/ColorPicker/index.mjs +1 -1
  46. package/dist/elements/ColorPicker/index.mjs.map +1 -1
  47. package/dist/elements/Combobox/Combobox.styles.d.ts.map +1 -1
  48. package/dist/elements/Combobox/index.js +1 -1
  49. package/dist/elements/Combobox/index.js.map +1 -1
  50. package/dist/elements/Combobox/index.mjs +1 -1
  51. package/dist/elements/Combobox/index.mjs.map +1 -1
  52. package/dist/elements/DatePicker/index.js +1 -1
  53. package/dist/elements/DatePicker/index.js.map +1 -1
  54. package/dist/elements/DatePicker/index.mjs +1 -1
  55. package/dist/elements/DatePicker/index.mjs.map +1 -1
  56. package/dist/elements/Dropdown/index.js +1 -1
  57. package/dist/elements/Dropdown/index.js.map +1 -1
  58. package/dist/elements/Dropdown/index.mjs +1 -1
  59. package/dist/elements/Dropdown/index.mjs.map +1 -1
  60. package/dist/elements/FileField/index.js +1 -1
  61. package/dist/elements/FileField/index.js.map +1 -1
  62. package/dist/elements/FileField/index.mjs +1 -1
  63. package/dist/elements/FileField/index.mjs.map +1 -1
  64. package/dist/elements/Filters/AppliedFilters.d.ts +4 -0
  65. package/dist/elements/Filters/AppliedFilters.d.ts.map +1 -0
  66. package/dist/elements/Filters/FilterPopover.d.ts +33 -0
  67. package/dist/elements/Filters/FilterPopover.d.ts.map +1 -0
  68. package/dist/elements/Filters/Filters.d.ts +25 -0
  69. package/dist/elements/Filters/Filters.d.ts.map +1 -0
  70. package/dist/elements/Filters/Filters.styles.d.ts +24 -0
  71. package/dist/elements/Filters/Filters.styles.d.ts.map +1 -0
  72. package/dist/elements/Filters/Filters.types.d.ts +123 -0
  73. package/dist/elements/Filters/Filters.types.d.ts.map +1 -0
  74. package/dist/elements/Filters/FiltersContext.d.ts +36 -0
  75. package/dist/elements/Filters/FiltersContext.d.ts.map +1 -0
  76. package/dist/elements/Filters/index.css +2 -0
  77. package/dist/elements/Filters/index.css.map +1 -0
  78. package/dist/elements/Filters/index.d.ts +26 -0
  79. package/dist/elements/Filters/index.d.ts.map +1 -0
  80. package/dist/elements/Filters/index.js +3 -0
  81. package/dist/elements/Filters/index.js.map +1 -0
  82. package/dist/elements/Filters/index.mjs +3 -0
  83. package/dist/elements/Filters/index.mjs.map +1 -0
  84. package/dist/elements/Modal/Modal.styles.d.ts.map +1 -1
  85. package/dist/elements/Modal/index.js +1 -1
  86. package/dist/elements/Modal/index.js.map +1 -1
  87. package/dist/elements/Modal/index.mjs +1 -1
  88. package/dist/elements/Modal/index.mjs.map +1 -1
  89. package/dist/elements/NumberField/index.js +1 -1
  90. package/dist/elements/NumberField/index.js.map +1 -1
  91. package/dist/elements/NumberField/index.mjs +1 -1
  92. package/dist/elements/NumberField/index.mjs.map +1 -1
  93. package/dist/elements/PageTitle/PageTitle.d.ts.map +1 -1
  94. package/dist/elements/PageTitle/PageTitle.styles.d.ts.map +1 -1
  95. package/dist/elements/PageTitle/index.js +1 -1
  96. package/dist/elements/PageTitle/index.js.map +1 -1
  97. package/dist/elements/PageTitle/index.mjs +1 -1
  98. package/dist/elements/PageTitle/index.mjs.map +1 -1
  99. package/dist/elements/Pagination/index.js +1 -1
  100. package/dist/elements/Pagination/index.js.map +1 -1
  101. package/dist/elements/Pagination/index.mjs +1 -1
  102. package/dist/elements/Pagination/index.mjs.map +1 -1
  103. package/dist/elements/Panel/Panel.d.ts.map +1 -1
  104. package/dist/elements/Panel/index.js +1 -1
  105. package/dist/elements/Panel/index.js.map +1 -1
  106. package/dist/elements/Panel/index.mjs +1 -1
  107. package/dist/elements/Panel/index.mjs.map +1 -1
  108. package/dist/elements/PasswordField/PasswordField.types.d.ts +34 -34
  109. package/dist/elements/PasswordField/index.js +1 -1
  110. package/dist/elements/PasswordField/index.js.map +1 -1
  111. package/dist/elements/PasswordField/index.mjs +1 -1
  112. package/dist/elements/PasswordField/index.mjs.map +1 -1
  113. package/dist/elements/RadioGroup/index.js +1 -1
  114. package/dist/elements/RadioGroup/index.js.map +1 -1
  115. package/dist/elements/RadioGroup/index.mjs +1 -1
  116. package/dist/elements/RadioGroup/index.mjs.map +1 -1
  117. package/dist/elements/RatingScale/RatingScale.styles.d.ts.map +1 -1
  118. package/dist/elements/RatingScale/index.js +1 -1
  119. package/dist/elements/RatingScale/index.js.map +1 -1
  120. package/dist/elements/RatingScale/index.mjs +1 -1
  121. package/dist/elements/RatingScale/index.mjs.map +1 -1
  122. package/dist/elements/Resizable/components/ResizablePopover.d.ts.map +1 -1
  123. package/dist/elements/Resizable/index.js +1 -1
  124. package/dist/elements/Resizable/index.js.map +1 -1
  125. package/dist/elements/Resizable/index.mjs +1 -1
  126. package/dist/elements/Resizable/index.mjs.map +1 -1
  127. package/dist/elements/SearchField/index.js +1 -1
  128. package/dist/elements/SearchField/index.js.map +1 -1
  129. package/dist/elements/SearchField/index.mjs +1 -1
  130. package/dist/elements/SearchField/index.mjs.map +1 -1
  131. package/dist/elements/Select/Select.styles.d.ts.map +1 -1
  132. package/dist/elements/Select/index.js +1 -1
  133. package/dist/elements/Select/index.js.map +1 -1
  134. package/dist/elements/Select/index.mjs +1 -1
  135. package/dist/elements/Select/index.mjs.map +1 -1
  136. package/dist/elements/Sidebar/Sidebar.styles.d.ts +34 -3
  137. package/dist/elements/Sidebar/Sidebar.styles.d.ts.map +1 -1
  138. package/dist/elements/Sidebar/Sidebar.types.d.ts +6 -0
  139. package/dist/elements/Sidebar/Sidebar.types.d.ts.map +1 -1
  140. package/dist/elements/Sidebar/SidebarPanel.d.ts.map +1 -1
  141. package/dist/elements/Sidebar/SidebarRail.d.ts.map +1 -1
  142. package/dist/elements/Sidebar/index.js +1 -1
  143. package/dist/elements/Sidebar/index.js.map +1 -1
  144. package/dist/elements/Sidebar/index.mjs +1 -1
  145. package/dist/elements/Sidebar/index.mjs.map +1 -1
  146. package/dist/elements/SituationalJudgement/index.js +1 -1
  147. package/dist/elements/SituationalJudgement/index.js.map +1 -1
  148. package/dist/elements/SituationalJudgement/index.mjs +1 -1
  149. package/dist/elements/SituationalJudgement/index.mjs.map +1 -1
  150. package/dist/elements/Switch/index.js +1 -1
  151. package/dist/elements/Switch/index.js.map +1 -1
  152. package/dist/elements/Switch/index.mjs +1 -1
  153. package/dist/elements/Switch/index.mjs.map +1 -1
  154. package/dist/elements/Table/BulkActionBar.d.ts +5 -0
  155. package/dist/elements/Table/BulkActionBar.d.ts.map +1 -0
  156. package/dist/elements/Table/BulkActionBar.styles.d.ts +17 -0
  157. package/dist/elements/Table/BulkActionBar.styles.d.ts.map +1 -0
  158. package/dist/elements/Table/BulkActionBar.types.d.ts +136 -0
  159. package/dist/elements/Table/BulkActionBar.types.d.ts.map +1 -0
  160. package/dist/elements/Table/Table.d.ts.map +1 -1
  161. package/dist/elements/Table/Table.styles.d.ts +2 -2
  162. package/dist/elements/Table/Table.styles.d.ts.map +1 -1
  163. package/dist/elements/Table/Table.types.d.ts +14 -4
  164. package/dist/elements/Table/Table.types.d.ts.map +1 -1
  165. package/dist/elements/Table/TableCardList.d.ts +25 -0
  166. package/dist/elements/Table/TableCardList.d.ts.map +1 -0
  167. package/dist/elements/Table/TableCardList.styles.d.ts +15 -0
  168. package/dist/elements/Table/TableCardList.styles.d.ts.map +1 -0
  169. package/dist/elements/Table/TableCardList.types.d.ts +48 -0
  170. package/dist/elements/Table/TableCardList.types.d.ts.map +1 -0
  171. package/dist/elements/Table/index.d.ts +9 -0
  172. package/dist/elements/Table/index.d.ts.map +1 -1
  173. package/dist/elements/Table/index.js +1 -1
  174. package/dist/elements/Table/index.js.map +1 -1
  175. package/dist/elements/Table/index.mjs +1 -1
  176. package/dist/elements/Table/index.mjs.map +1 -1
  177. package/dist/elements/Table/resolveSelectedCount.d.ts +20 -0
  178. package/dist/elements/Table/resolveSelectedCount.d.ts.map +1 -0
  179. package/dist/elements/Table/useBulkActionShortcut.d.ts +29 -0
  180. package/dist/elements/Table/useBulkActionShortcut.d.ts.map +1 -0
  181. package/dist/elements/Tabs/Tabs.d.ts.map +1 -1
  182. package/dist/elements/Tabs/index.js +1 -1
  183. package/dist/elements/Tabs/index.js.map +1 -1
  184. package/dist/elements/Tabs/index.mjs +1 -1
  185. package/dist/elements/Tabs/index.mjs.map +1 -1
  186. package/dist/elements/TextField/TextField.types.d.ts +68 -68
  187. package/dist/elements/TextField/index.js +1 -1
  188. package/dist/elements/TextField/index.js.map +1 -1
  189. package/dist/elements/TextField/index.mjs +1 -1
  190. package/dist/elements/TextField/index.mjs.map +1 -1
  191. package/dist/elements/Toast/Toast.d.ts.map +1 -1
  192. package/dist/elements/Toast/index.js +1 -1
  193. package/dist/elements/Toast/index.js.map +1 -1
  194. package/dist/elements/Toast/index.mjs +1 -1
  195. package/dist/elements/Toast/index.mjs.map +1 -1
  196. package/dist/elements/Tooltip/index.js +1 -1
  197. package/dist/elements/Tooltip/index.js.map +1 -1
  198. package/dist/elements/Tooltip/index.mjs +1 -1
  199. package/dist/elements/Tooltip/index.mjs.map +1 -1
  200. package/dist/elements/Wizard/index.js +1 -1
  201. package/dist/elements/Wizard/index.js.map +1 -1
  202. package/dist/elements/Wizard/index.mjs +1 -1
  203. package/dist/elements/Wizard/index.mjs.map +1 -1
  204. package/dist/elements/index.d.ts +4 -1
  205. package/dist/elements/index.d.ts.map +1 -1
  206. package/dist/elements/index.js +1 -1
  207. package/dist/elements/index.js.map +1 -1
  208. package/dist/elements/index.mjs +1 -1
  209. package/dist/elements/index.mjs.map +1 -1
  210. package/dist/hooks/index.d.ts +1 -0
  211. package/dist/hooks/index.d.ts.map +1 -1
  212. package/dist/hooks/index.js +1 -1
  213. package/dist/hooks/index.js.map +1 -1
  214. package/dist/hooks/index.mjs +1 -1
  215. package/dist/hooks/index.mjs.map +1 -1
  216. package/dist/hooks/useContainerNarrow.d.ts +15 -0
  217. package/dist/hooks/useContainerNarrow.d.ts.map +1 -0
  218. package/dist/index.js +2 -2
  219. package/dist/index.js.map +1 -1
  220. package/dist/index.mjs +2 -2
  221. package/dist/index.mjs.map +1 -1
  222. package/dist/styles/defaults.css +15 -0
  223. package/dist/styles/index.js +1 -1
  224. package/dist/styles/index.js.map +1 -1
  225. package/dist/styles/index.mjs +1 -1
  226. package/dist/styles/index.mjs.map +1 -1
  227. package/dist/styles/interaction-states.d.ts +2 -2
  228. package/dist/styles/interaction-states.d.ts.map +1 -1
  229. package/package.json +6 -1
  230. package/src/elements/Filters/Filters.stories.tsx +148 -0
  231. package/src/elements/PageTitle/PageTitle.stories.tsx +15 -19
  232. package/src/elements/Sidebar/Sidebar.stories.tsx +13 -2
  233. package/src/elements/Table/Table.stories.tsx +467 -10
@@ -42,6 +42,11 @@
42
42
  --accent-foreground: #1f2937;
43
43
  --accent-background: #f3f4f6;
44
44
 
45
+ /* Selection tint — selected table rows + the bulk-action toolbar band.
46
+ A light brand-purple lilac on light surfaces; dark/high-contrast themes
47
+ darken instead of lighten (see their blocks below). */
48
+ --selected: #f3eefe;
49
+
45
50
  /* Muted Colors */
46
51
  --muted: #f9fafb;
47
52
  --muted-foreground: #6b7280;
@@ -150,6 +155,9 @@
150
155
  --accent-foreground: #f9fafb;
151
156
  --accent-background: #1a1a1a;
152
157
 
158
+ /* Selection tint — darker, elevated violet on the dark surface (not lighter). */
159
+ --selected: #2a2140;
160
+
153
161
  --muted: #1f2937;
154
162
  --muted-foreground: #9ca3af;
155
163
 
@@ -240,6 +248,10 @@
240
248
  --accent-foreground: #ffffff;
241
249
  --accent-background: #333333;
242
250
 
251
+ /* Selection tint — a clearly distinct dark surface on the black background
252
+ (high-contrast conveys selection via the checkbox/focus ring too). */
253
+ --selected: #333333;
254
+
243
255
  /* Muted */
244
256
  --muted: #1a1a1a;
245
257
  --muted-foreground: #cccccc;
@@ -318,6 +330,9 @@
318
330
  --primary: #1e40af;
319
331
  --primary-foreground: #ffffff;
320
332
 
333
+ /* Selection tint — light blue tint of the colorblind-safe primary. */
334
+ --selected: #e8eefb;
335
+
321
336
  /* Destructive — Orange instead of red (7.52:1 on white) */
322
337
  --destructive-background: #9a3412;
323
338
  --destructive-foreground: #ffffff;
@@ -1,2 +1,2 @@
1
- 'use strict';var n="data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2",i="data-[pressed]:scale-[0.97]",E="data-[pressed]:transition-transform data-[pressed]:duration-100",r="data-[hovered]:shadow-md",S="data-[hovered]:transition-shadow data-[hovered]:duration-200",t="hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground",a="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",s="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground",d=`${t} ${a} ${s}`,_="disabled:pointer-events-none disabled:opacity-50",T=`${n} ${i} ${r} ${t} ${a} ${s}`,I=`${n} ${t}`,A="cursor-default select-none";var x=["focus-within:outline-none","focus-within:ring-2","focus-within:ring-[var(--ring)]","focus-within:ring-offset-2"],u=["focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2"],O=["focus:outline-none","focus:ring-2","focus:ring-[var(--ring)]"],N=["focus:outline-none","focus:bg-[var(--accent)]","focus:text-[var(--accent-foreground)]"],R=["disabled:pointer-events-none","disabled:opacity-50"],g=["data-[disabled]:pointer-events-none","data-[disabled]:opacity-50","data-[disabled]:cursor-not-allowed"],p={sm:"text-xs",default:"text-sm",lg:"text-base"},f={sm:"text-sm",default:"text-base",lg:"text-lg"},l=["min-h-[44px]","min-w-[44px]"],L={sm:"h-9 w-9",default:"h-11 w-11",lg:"h-14 w-14"},e={sm:"h-9",default:"h-10",lg:"h-11"},C={sm:`${e.sm} px-2 text-xs`,default:`${e.default} px-3 text-sm`,lg:`${e.lg} px-4 text-base`},D="min-h-[44px] flex items-center",m=["flex","items-center","gap-1.5","text-[var(--destructive-background)]"],H=["flex","items-center","gap-1.5","text-[var(--success-background)]"],v=["text-[var(--menu-muted)]"],U=["font-medium","text-[var(--content-foreground)]"],h="after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]",b=["data-[entering]:animate-in","data-[entering]:fade-in-0","data-[entering]:zoom-in-95"],G=["data-[exiting]:animate-out","data-[exiting]:fade-out-0","data-[exiting]:zoom-out-95"];var M=["motion-reduce:transition-none","motion-reduce:animate-none"],B=["transition-colors","duration-200"],F=["transition-colors","duration-150"],V=["hover:bg-[var(--accent)]","hover:text-[var(--accent-foreground)]"];function P(...c){return c.flatMap(o=>Array.isArray(o)?[...o]:[o])}exports.DEFAULT_INTERACTIONS=T;exports.DESCRIPTION_BASE=v;exports.DISABLED_DATA_ATTR=g;exports.DISABLED_STANDARD=R;exports.DISABLED_STYLES=_;exports.ERROR_MESSAGE_BASE=m;exports.FIELD_HEIGHTS=e;exports.FIELD_INPUT_SIZES=C;exports.FIELD_TOUCH_TARGET=D;exports.FOCUS_HIGHLIGHT=N;exports.FOCUS_RING=O;exports.FOCUS_STYLES=n;exports.FOCUS_VISIBLE_RING=u;exports.FOCUS_WITHIN_RING=x;exports.HIGH_CONTRAST_FOCUS=t;exports.HIGH_CONTRAST_HOVER=a;exports.HIGH_CONTRAST_INTERACTIONS=d;exports.HIGH_CONTRAST_PRESSED=s;exports.HOVER_ACCENT=V;exports.HOVER_STYLES=r;exports.HOVER_STYLES_BASE=S;exports.INTERACTIVE_SIZES=L;exports.LABEL_BASE=U;exports.NON_INTERACTIVE=A;exports.POPOVER_ANIMATION_IN=b;exports.POPOVER_ANIMATION_OUT=G;exports.PRESSED_STYLES=i;exports.PRESSED_STYLES_BASE=E;exports.REDUCED_MOTION=M;exports.REQUIRED_INDICATOR=h;exports.SUBTLE_INTERACTIONS=I;exports.SUCCESS_MESSAGE_BASE=H;exports.TEXT_SIZE_MEDIUM_SCALE=f;exports.TEXT_SIZE_SMALL_SCALE=p;exports.TOUCH_TARGET_MIN=l;exports.TRANSITION_COLORS=B;exports.TRANSITION_FAST=F;exports.combineStyles=P;//# sourceMappingURL=index.js.map
1
+ 'use strict';var n="data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2",i="data-[pressed]:scale-[0.97]",c="data-[pressed]:transition-transform data-[pressed]:duration-100",E="",S="data-[hovered]:transition-shadow data-[hovered]:duration-200",t="hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground",a="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",s="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground",_=`${t} ${a} ${s}`,d="disabled:pointer-events-none disabled:opacity-50",T=`${n} ${i} ${t} ${a} ${s}`,I=`${n} ${t}`,A="cursor-default select-none";var x=["focus-within:outline-none","focus-within:ring-2","focus-within:ring-[var(--ring)]","focus-within:ring-offset-2"],u=["focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2"],O=["focus:outline-none","focus:ring-2","focus:ring-[var(--ring)]"],N=["focus:outline-none","focus:bg-[var(--accent)]","focus:text-[var(--accent-foreground)]"],R=["disabled:pointer-events-none","disabled:opacity-50"],g=["data-[disabled]:pointer-events-none","data-[disabled]:opacity-50","data-[disabled]:cursor-not-allowed"],p={sm:"text-xs",default:"text-sm",lg:"text-base"},f={sm:"text-sm",default:"text-base",lg:"text-lg"},l=["min-h-[44px]","min-w-[44px]"],L={sm:"h-9 w-9",default:"h-11 w-11",lg:"h-14 w-14"},e={sm:"h-9",default:"h-10",lg:"h-11"},C={sm:`${e.sm} px-2 text-xs`,default:`${e.default} px-3 text-sm`,lg:`${e.lg} px-4 text-base`},D="min-h-[44px] flex items-center",m=["flex","items-center","gap-1.5","text-[var(--destructive-background)]"],H=["flex","items-center","gap-1.5","text-[var(--success-background)]"],v=["text-[var(--menu-muted)]"],U=["font-medium","text-[var(--content-foreground)]"],h="after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]",b=["data-[entering]:animate-in","data-[entering]:fade-in-0","data-[entering]:zoom-in-95"],G=["data-[exiting]:animate-out","data-[exiting]:fade-out-0","data-[exiting]:zoom-out-95"];var M=["motion-reduce:transition-none","motion-reduce:animate-none"],B=["transition-colors","duration-200"],F=["transition-colors","duration-150"],V=["hover:bg-[var(--accent)]","hover:text-[var(--accent-foreground)]"];function P(...r){return r.flatMap(o=>Array.isArray(o)?[...o]:[o])}exports.DEFAULT_INTERACTIONS=T;exports.DESCRIPTION_BASE=v;exports.DISABLED_DATA_ATTR=g;exports.DISABLED_STANDARD=R;exports.DISABLED_STYLES=d;exports.ERROR_MESSAGE_BASE=m;exports.FIELD_HEIGHTS=e;exports.FIELD_INPUT_SIZES=C;exports.FIELD_TOUCH_TARGET=D;exports.FOCUS_HIGHLIGHT=N;exports.FOCUS_RING=O;exports.FOCUS_STYLES=n;exports.FOCUS_VISIBLE_RING=u;exports.FOCUS_WITHIN_RING=x;exports.HIGH_CONTRAST_FOCUS=t;exports.HIGH_CONTRAST_HOVER=a;exports.HIGH_CONTRAST_INTERACTIONS=_;exports.HIGH_CONTRAST_PRESSED=s;exports.HOVER_ACCENT=V;exports.HOVER_STYLES=E;exports.HOVER_STYLES_BASE=S;exports.INTERACTIVE_SIZES=L;exports.LABEL_BASE=U;exports.NON_INTERACTIVE=A;exports.POPOVER_ANIMATION_IN=b;exports.POPOVER_ANIMATION_OUT=G;exports.PRESSED_STYLES=i;exports.PRESSED_STYLES_BASE=c;exports.REDUCED_MOTION=M;exports.REQUIRED_INDICATOR=h;exports.SUBTLE_INTERACTIONS=I;exports.SUCCESS_MESSAGE_BASE=H;exports.TEXT_SIZE_MEDIUM_SCALE=f;exports.TEXT_SIZE_SMALL_SCALE=p;exports.TOUCH_TARGET_MIN=l;exports.TRANSITION_COLORS=B;exports.TRANSITION_FAST=F;exports.combineStyles=P;//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/styles/interaction-states.ts","../../src/styles/shared-variants.ts"],"names":["FOCUS_STYLES","PRESSED_STYLES","PRESSED_STYLES_BASE","HOVER_STYLES","HOVER_STYLES_BASE","HIGH_CONTRAST_FOCUS","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","HIGH_CONTRAST_INTERACTIONS","DISABLED_STYLES","DEFAULT_INTERACTIONS","SUBTLE_INTERACTIONS","NON_INTERACTIVE","FOCUS_WITHIN_RING","FOCUS_VISIBLE_RING","FOCUS_RING","FOCUS_HIGHLIGHT","DISABLED_STANDARD","DISABLED_DATA_ATTR","TEXT_SIZE_SMALL_SCALE","TEXT_SIZE_MEDIUM_SCALE","TOUCH_TARGET_MIN","INTERACTIVE_SIZES","FIELD_HEIGHTS","FIELD_INPUT_SIZES","FIELD_TOUCH_TARGET","ERROR_MESSAGE_BASE","SUCCESS_MESSAGE_BASE","DESCRIPTION_BASE","LABEL_BASE","REQUIRED_INDICATOR","POPOVER_ANIMATION_IN","POPOVER_ANIMATION_OUT","REDUCED_MOTION","TRANSITION_COLORS","TRANSITION_FAST","HOVER_ACCENT","combineStyles","styles","s"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"data-[hovered]:shadow-md\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-10', // 40px\n lg: 'h-11', // 44px\n} as const;\n\n/**\n * Layer 2: Visual sizing for form field inputs (height + padding + font).\n * Use on the <input>, <select>, or trigger element itself.\n *\n * Components may append additional classes (e.g. gap-* for segmented fields, py-* for text inputs).\n */\nexport const FIELD_INPUT_SIZES = {\n sm: `${FIELD_HEIGHTS.sm} px-2 text-xs`,\n default: `${FIELD_HEIGHTS.default} px-3 text-sm`,\n lg: `${FIELD_HEIGHTS.lg} px-4 text-base`,\n} as const;\n\n/**\n * Layer 1: Invisible touch target wrapper for form fields.\n * Apply to a <label> (or wrapper div) around the input element.\n * The <label> natively routes clicks/taps to the contained input\n * without JavaScript — achieving a 44px touch target while the\n * input stays at its visual height (h-9/h-10/h-11).\n */\nexport const FIELD_TOUCH_TARGET = 'min-h-[44px] flex items-center' as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive-background)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success-background)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Modal content enter animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal content exit animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal slide enter animation (fade + slide up)\n */\nexport const MODAL_SLIDE_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:slide-in-from-bottom-4',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal slide exit animation (fade + slide down)\n */\nexport const MODAL_SLIDE_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:slide-out-to-bottom-4',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal overlay enter/exit animation (fade only)\n */\nexport const MODAL_OVERLAY_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:duration-200',\n] as const;\n\nexport const MODAL_OVERLAY_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:duration-150',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n"]}
1
+ {"version":3,"sources":["../../src/styles/interaction-states.ts","../../src/styles/shared-variants.ts"],"names":["FOCUS_STYLES","PRESSED_STYLES","PRESSED_STYLES_BASE","HOVER_STYLES","HOVER_STYLES_BASE","HIGH_CONTRAST_FOCUS","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","HIGH_CONTRAST_INTERACTIONS","DISABLED_STYLES","DEFAULT_INTERACTIONS","SUBTLE_INTERACTIONS","NON_INTERACTIVE","FOCUS_WITHIN_RING","FOCUS_VISIBLE_RING","FOCUS_RING","FOCUS_HIGHLIGHT","DISABLED_STANDARD","DISABLED_DATA_ATTR","TEXT_SIZE_SMALL_SCALE","TEXT_SIZE_MEDIUM_SCALE","TOUCH_TARGET_MIN","INTERACTIVE_SIZES","FIELD_HEIGHTS","FIELD_INPUT_SIZES","FIELD_TOUCH_TARGET","ERROR_MESSAGE_BASE","SUCCESS_MESSAGE_BASE","DESCRIPTION_BASE","LABEL_BASE","REQUIRED_INDICATOR","POPOVER_ANIMATION_IN","POPOVER_ANIMATION_OUT","REDUCED_MOTION","TRANSITION_COLORS","TRANSITION_FAST","HOVER_ACCENT","combineStyles","styles","s"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-10', // 40px\n lg: 'h-11', // 44px\n} as const;\n\n/**\n * Layer 2: Visual sizing for form field inputs (height + padding + font).\n * Use on the <input>, <select>, or trigger element itself.\n *\n * Components may append additional classes (e.g. gap-* for segmented fields, py-* for text inputs).\n */\nexport const FIELD_INPUT_SIZES = {\n sm: `${FIELD_HEIGHTS.sm} px-2 text-xs`,\n default: `${FIELD_HEIGHTS.default} px-3 text-sm`,\n lg: `${FIELD_HEIGHTS.lg} px-4 text-base`,\n} as const;\n\n/**\n * Layer 1: Invisible touch target wrapper for form fields.\n * Apply to a <label> (or wrapper div) around the input element.\n * The <label> natively routes clicks/taps to the contained input\n * without JavaScript — achieving a 44px touch target while the\n * input stays at its visual height (h-9/h-10/h-11).\n */\nexport const FIELD_TOUCH_TARGET = 'min-h-[44px] flex items-center' as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive-background)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success-background)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Modal content enter animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal content exit animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal slide enter animation (fade + slide up)\n */\nexport const MODAL_SLIDE_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:slide-in-from-bottom-4',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal slide exit animation (fade + slide down)\n */\nexport const MODAL_SLIDE_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:slide-out-to-bottom-4',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal overlay enter/exit animation (fade only)\n */\nexport const MODAL_OVERLAY_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:duration-200',\n] as const;\n\nexport const MODAL_OVERLAY_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:duration-150',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n"]}
@@ -1,2 +1,2 @@
1
- var n="data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2",i="data-[pressed]:scale-[0.97]",E="data-[pressed]:transition-transform data-[pressed]:duration-100",r="data-[hovered]:shadow-md",S="data-[hovered]:transition-shadow data-[hovered]:duration-200",t="hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground",a="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",s="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground",d=`${t} ${a} ${s}`,_="disabled:pointer-events-none disabled:opacity-50",T=`${n} ${i} ${r} ${t} ${a} ${s}`,I=`${n} ${t}`,A="cursor-default select-none";var x=["focus-within:outline-none","focus-within:ring-2","focus-within:ring-[var(--ring)]","focus-within:ring-offset-2"],u=["focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2"],O=["focus:outline-none","focus:ring-2","focus:ring-[var(--ring)]"],N=["focus:outline-none","focus:bg-[var(--accent)]","focus:text-[var(--accent-foreground)]"],R=["disabled:pointer-events-none","disabled:opacity-50"],g=["data-[disabled]:pointer-events-none","data-[disabled]:opacity-50","data-[disabled]:cursor-not-allowed"],p={sm:"text-xs",default:"text-sm",lg:"text-base"},f={sm:"text-sm",default:"text-base",lg:"text-lg"},l=["min-h-[44px]","min-w-[44px]"],L={sm:"h-9 w-9",default:"h-11 w-11",lg:"h-14 w-14"},e={sm:"h-9",default:"h-10",lg:"h-11"},C={sm:`${e.sm} px-2 text-xs`,default:`${e.default} px-3 text-sm`,lg:`${e.lg} px-4 text-base`},D="min-h-[44px] flex items-center",m=["flex","items-center","gap-1.5","text-[var(--destructive-background)]"],H=["flex","items-center","gap-1.5","text-[var(--success-background)]"],v=["text-[var(--menu-muted)]"],U=["font-medium","text-[var(--content-foreground)]"],h="after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]",b=["data-[entering]:animate-in","data-[entering]:fade-in-0","data-[entering]:zoom-in-95"],G=["data-[exiting]:animate-out","data-[exiting]:fade-out-0","data-[exiting]:zoom-out-95"];var M=["motion-reduce:transition-none","motion-reduce:animate-none"],B=["transition-colors","duration-200"],F=["transition-colors","duration-150"],V=["hover:bg-[var(--accent)]","hover:text-[var(--accent-foreground)]"];function P(...c){return c.flatMap(o=>Array.isArray(o)?[...o]:[o])}export{T as DEFAULT_INTERACTIONS,v as DESCRIPTION_BASE,g as DISABLED_DATA_ATTR,R as DISABLED_STANDARD,_ as DISABLED_STYLES,m as ERROR_MESSAGE_BASE,e as FIELD_HEIGHTS,C as FIELD_INPUT_SIZES,D as FIELD_TOUCH_TARGET,N as FOCUS_HIGHLIGHT,O as FOCUS_RING,n as FOCUS_STYLES,u as FOCUS_VISIBLE_RING,x as FOCUS_WITHIN_RING,t as HIGH_CONTRAST_FOCUS,a as HIGH_CONTRAST_HOVER,d as HIGH_CONTRAST_INTERACTIONS,s as HIGH_CONTRAST_PRESSED,V as HOVER_ACCENT,r as HOVER_STYLES,S as HOVER_STYLES_BASE,L as INTERACTIVE_SIZES,U as LABEL_BASE,A as NON_INTERACTIVE,b as POPOVER_ANIMATION_IN,G as POPOVER_ANIMATION_OUT,i as PRESSED_STYLES,E as PRESSED_STYLES_BASE,M as REDUCED_MOTION,h as REQUIRED_INDICATOR,I as SUBTLE_INTERACTIONS,H as SUCCESS_MESSAGE_BASE,f as TEXT_SIZE_MEDIUM_SCALE,p as TEXT_SIZE_SMALL_SCALE,l as TOUCH_TARGET_MIN,B as TRANSITION_COLORS,F as TRANSITION_FAST,P as combineStyles};//# sourceMappingURL=index.mjs.map
1
+ var n="data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2",i="data-[pressed]:scale-[0.97]",c="data-[pressed]:transition-transform data-[pressed]:duration-100",E="",S="data-[hovered]:transition-shadow data-[hovered]:duration-200",t="hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground",a="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",s="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground",_=`${t} ${a} ${s}`,d="disabled:pointer-events-none disabled:opacity-50",T=`${n} ${i} ${t} ${a} ${s}`,I=`${n} ${t}`,A="cursor-default select-none";var x=["focus-within:outline-none","focus-within:ring-2","focus-within:ring-[var(--ring)]","focus-within:ring-offset-2"],u=["focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2"],O=["focus:outline-none","focus:ring-2","focus:ring-[var(--ring)]"],N=["focus:outline-none","focus:bg-[var(--accent)]","focus:text-[var(--accent-foreground)]"],R=["disabled:pointer-events-none","disabled:opacity-50"],g=["data-[disabled]:pointer-events-none","data-[disabled]:opacity-50","data-[disabled]:cursor-not-allowed"],p={sm:"text-xs",default:"text-sm",lg:"text-base"},f={sm:"text-sm",default:"text-base",lg:"text-lg"},l=["min-h-[44px]","min-w-[44px]"],L={sm:"h-9 w-9",default:"h-11 w-11",lg:"h-14 w-14"},e={sm:"h-9",default:"h-10",lg:"h-11"},C={sm:`${e.sm} px-2 text-xs`,default:`${e.default} px-3 text-sm`,lg:`${e.lg} px-4 text-base`},D="min-h-[44px] flex items-center",m=["flex","items-center","gap-1.5","text-[var(--destructive-background)]"],H=["flex","items-center","gap-1.5","text-[var(--success-background)]"],v=["text-[var(--menu-muted)]"],U=["font-medium","text-[var(--content-foreground)]"],h="after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]",b=["data-[entering]:animate-in","data-[entering]:fade-in-0","data-[entering]:zoom-in-95"],G=["data-[exiting]:animate-out","data-[exiting]:fade-out-0","data-[exiting]:zoom-out-95"];var M=["motion-reduce:transition-none","motion-reduce:animate-none"],B=["transition-colors","duration-200"],F=["transition-colors","duration-150"],V=["hover:bg-[var(--accent)]","hover:text-[var(--accent-foreground)]"];function P(...r){return r.flatMap(o=>Array.isArray(o)?[...o]:[o])}export{T as DEFAULT_INTERACTIONS,v as DESCRIPTION_BASE,g as DISABLED_DATA_ATTR,R as DISABLED_STANDARD,d as DISABLED_STYLES,m as ERROR_MESSAGE_BASE,e as FIELD_HEIGHTS,C as FIELD_INPUT_SIZES,D as FIELD_TOUCH_TARGET,N as FOCUS_HIGHLIGHT,O as FOCUS_RING,n as FOCUS_STYLES,u as FOCUS_VISIBLE_RING,x as FOCUS_WITHIN_RING,t as HIGH_CONTRAST_FOCUS,a as HIGH_CONTRAST_HOVER,_ as HIGH_CONTRAST_INTERACTIONS,s as HIGH_CONTRAST_PRESSED,V as HOVER_ACCENT,E as HOVER_STYLES,S as HOVER_STYLES_BASE,L as INTERACTIVE_SIZES,U as LABEL_BASE,A as NON_INTERACTIVE,b as POPOVER_ANIMATION_IN,G as POPOVER_ANIMATION_OUT,i as PRESSED_STYLES,c as PRESSED_STYLES_BASE,M as REDUCED_MOTION,h as REQUIRED_INDICATOR,I as SUBTLE_INTERACTIONS,H as SUCCESS_MESSAGE_BASE,f as TEXT_SIZE_MEDIUM_SCALE,p as TEXT_SIZE_SMALL_SCALE,l as TOUCH_TARGET_MIN,B as TRANSITION_COLORS,F as TRANSITION_FAST,P as combineStyles};//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/styles/interaction-states.ts","../../src/styles/shared-variants.ts"],"names":["FOCUS_STYLES","PRESSED_STYLES","PRESSED_STYLES_BASE","HOVER_STYLES","HOVER_STYLES_BASE","HIGH_CONTRAST_FOCUS","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","HIGH_CONTRAST_INTERACTIONS","DISABLED_STYLES","DEFAULT_INTERACTIONS","SUBTLE_INTERACTIONS","NON_INTERACTIVE","FOCUS_WITHIN_RING","FOCUS_VISIBLE_RING","FOCUS_RING","FOCUS_HIGHLIGHT","DISABLED_STANDARD","DISABLED_DATA_ATTR","TEXT_SIZE_SMALL_SCALE","TEXT_SIZE_MEDIUM_SCALE","TOUCH_TARGET_MIN","INTERACTIVE_SIZES","FIELD_HEIGHTS","FIELD_INPUT_SIZES","FIELD_TOUCH_TARGET","ERROR_MESSAGE_BASE","SUCCESS_MESSAGE_BASE","DESCRIPTION_BASE","LABEL_BASE","REQUIRED_INDICATOR","POPOVER_ANIMATION_IN","POPOVER_ANIMATION_OUT","REDUCED_MOTION","TRANSITION_COLORS","TRANSITION_FAST","HOVER_ACCENT","combineStyles","styles","s"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"data-[hovered]:shadow-md\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-10', // 40px\n lg: 'h-11', // 44px\n} as const;\n\n/**\n * Layer 2: Visual sizing for form field inputs (height + padding + font).\n * Use on the <input>, <select>, or trigger element itself.\n *\n * Components may append additional classes (e.g. gap-* for segmented fields, py-* for text inputs).\n */\nexport const FIELD_INPUT_SIZES = {\n sm: `${FIELD_HEIGHTS.sm} px-2 text-xs`,\n default: `${FIELD_HEIGHTS.default} px-3 text-sm`,\n lg: `${FIELD_HEIGHTS.lg} px-4 text-base`,\n} as const;\n\n/**\n * Layer 1: Invisible touch target wrapper for form fields.\n * Apply to a <label> (or wrapper div) around the input element.\n * The <label> natively routes clicks/taps to the contained input\n * without JavaScript — achieving a 44px touch target while the\n * input stays at its visual height (h-9/h-10/h-11).\n */\nexport const FIELD_TOUCH_TARGET = 'min-h-[44px] flex items-center' as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive-background)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success-background)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Modal content enter animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal content exit animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal slide enter animation (fade + slide up)\n */\nexport const MODAL_SLIDE_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:slide-in-from-bottom-4',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal slide exit animation (fade + slide down)\n */\nexport const MODAL_SLIDE_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:slide-out-to-bottom-4',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal overlay enter/exit animation (fade only)\n */\nexport const MODAL_OVERLAY_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:duration-200',\n] as const;\n\nexport const MODAL_OVERLAY_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:duration-150',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n"]}
1
+ {"version":3,"sources":["../../src/styles/interaction-states.ts","../../src/styles/shared-variants.ts"],"names":["FOCUS_STYLES","PRESSED_STYLES","PRESSED_STYLES_BASE","HOVER_STYLES","HOVER_STYLES_BASE","HIGH_CONTRAST_FOCUS","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","HIGH_CONTRAST_INTERACTIONS","DISABLED_STYLES","DEFAULT_INTERACTIONS","SUBTLE_INTERACTIONS","NON_INTERACTIVE","FOCUS_WITHIN_RING","FOCUS_VISIBLE_RING","FOCUS_RING","FOCUS_HIGHLIGHT","DISABLED_STANDARD","DISABLED_DATA_ATTR","TEXT_SIZE_SMALL_SCALE","TEXT_SIZE_MEDIUM_SCALE","TOUCH_TARGET_MIN","INTERACTIVE_SIZES","FIELD_HEIGHTS","FIELD_INPUT_SIZES","FIELD_TOUCH_TARGET","ERROR_MESSAGE_BASE","SUCCESS_MESSAGE_BASE","DESCRIPTION_BASE","LABEL_BASE","REQUIRED_INDICATOR","POPOVER_ANIMATION_IN","POPOVER_ANIMATION_OUT","REDUCED_MOTION","TRANSITION_COLORS","TRANSITION_FAST","HOVER_ACCENT","combineStyles","styles","s"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-10', // 40px\n lg: 'h-11', // 44px\n} as const;\n\n/**\n * Layer 2: Visual sizing for form field inputs (height + padding + font).\n * Use on the <input>, <select>, or trigger element itself.\n *\n * Components may append additional classes (e.g. gap-* for segmented fields, py-* for text inputs).\n */\nexport const FIELD_INPUT_SIZES = {\n sm: `${FIELD_HEIGHTS.sm} px-2 text-xs`,\n default: `${FIELD_HEIGHTS.default} px-3 text-sm`,\n lg: `${FIELD_HEIGHTS.lg} px-4 text-base`,\n} as const;\n\n/**\n * Layer 1: Invisible touch target wrapper for form fields.\n * Apply to a <label> (or wrapper div) around the input element.\n * The <label> natively routes clicks/taps to the contained input\n * without JavaScript — achieving a 44px touch target while the\n * input stays at its visual height (h-9/h-10/h-11).\n */\nexport const FIELD_TOUCH_TARGET = 'min-h-[44px] flex items-center' as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive-background)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success-background)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Modal content enter animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal content exit animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal slide enter animation (fade + slide up)\n */\nexport const MODAL_SLIDE_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:slide-in-from-bottom-4',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal slide exit animation (fade + slide down)\n */\nexport const MODAL_SLIDE_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:slide-out-to-bottom-4',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal overlay enter/exit animation (fade only)\n */\nexport const MODAL_OVERLAY_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:duration-200',\n] as const;\n\nexport const MODAL_OVERLAY_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:duration-150',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n"]}
@@ -39,7 +39,7 @@ export declare const PRESSED_STYLES_BASE = "data-[pressed]:transition-transform
39
39
  * @example
40
40
  * cn(HOVER_STYLES_BASE, "data-[hovered]:shadow-lg") // Larger shadow
41
41
  */
42
- export declare const HOVER_STYLES = "data-[hovered]:shadow-md";
42
+ export declare const HOVER_STYLES = "";
43
43
  /**
44
44
  * Base hover styles without shadow (for components that use different hover effects)
45
45
  */
@@ -80,7 +80,7 @@ export declare const DISABLED_STYLES = "disabled:pointer-events-none disabled:op
80
80
  * @example
81
81
  * <button className={cn(DEFAULT_INTERACTIONS, "bg-primary")}>Click</button>
82
82
  */
83
- export declare const DEFAULT_INTERACTIONS = "data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2 data-[pressed]:scale-[0.97] data-[hovered]:shadow-md hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground";
83
+ export declare const DEFAULT_INTERACTIONS = "data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2 data-[pressed]:scale-[0.97] hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground";
84
84
  /**
85
85
  * Subtle interaction bundle
86
86
  * For components that need less pronounced feedback
@@ -1 +1 @@
1
- {"version":3,"file":"interaction-states.d.ts","sourceRoot":"","sources":["../../src/styles/interaction-states.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,kHAAkH,CAAC;AAE5I;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,gCAAgC,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,mBAAmB,oEAAoE,CAAC;AAErG;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,6BAA6B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,iBAAiB,iEAAiE,CAAC;AAEhG;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,0JAA0J,CAAC;AAE3L;;;GAGG;AACH,eAAO,MAAM,mBAAmB,+FAA+F,CAAC;AAEhI;;;GAGG;AACH,eAAO,MAAM,qBAAqB,kIAAkI,CAAC;AAErK;;;GAGG;AACH,eAAO,MAAM,0BAA0B,mXAA2E,CAAC;AAEnH;;;GAGG;AACH,eAAO,MAAM,eAAe,qDAAqD,CAAC;AAElF;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,shBAA6H,CAAC;AAE/J;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,wQAA2C,CAAC;AAE5E;;;GAGG;AACH,eAAO,MAAM,eAAe,+BAA+B,CAAC"}
1
+ {"version":3,"file":"interaction-states.d.ts","sourceRoot":"","sources":["../../src/styles/interaction-states.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,kHAAkH,CAAC;AAE5I;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,gCAAgC,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,mBAAmB,oEAAoE,CAAC;AAErG;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,iBAAiB,iEAAiE,CAAC;AAEhG;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,0JAA0J,CAAC;AAE3L;;;GAGG;AACH,eAAO,MAAM,mBAAmB,+FAA+F,CAAC;AAEhI;;;GAGG;AACH,eAAO,MAAM,qBAAqB,kIAAkI,CAAC;AAErK;;;GAGG;AACH,eAAO,MAAM,0BAA0B,mXAA2E,CAAC;AAEnH;;;GAGG;AACH,eAAO,MAAM,eAAe,qDAAqD,CAAC;AAElF;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,8fAA6H,CAAC;AAE/J;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,wQAA2C,CAAC;AAE5E;;;GAGG;AACH,eAAO,MAAM,eAAe,+BAA+B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tribepad/themis",
3
- "version": "1.5.8",
3
+ "version": "1.6.0",
4
4
  "description": "Accessible React component library built on React Aria primitives",
5
5
  "author": "Tribepad <mbasford@tribepad.com>",
6
6
  "license": "MIT",
@@ -263,6 +263,11 @@
263
263
  "name": "ChatInterface only",
264
264
  "path": "dist/elements/ChatInterface/index.mjs",
265
265
  "limit": "28 KB"
266
+ },
267
+ {
268
+ "name": "Filters (full barrel)",
269
+ "path": "dist/elements/Filters/index.mjs",
270
+ "limit": "80 KB"
266
271
  }
267
272
  ],
268
273
  "keywords": [
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Filters — Storybook stories (compositional API)
3
+ *
4
+ * `<Filters values onChange labels>` owns one values map; controls are composed
5
+ * as children (`<FilterSearch>`, `<FilterSelect>`, `<FilterCombobox>` …) and
6
+ * `<FilterChips>` renders removable chips. Import only the controls you use.
7
+ */
8
+
9
+ import { useState, type ReactElement } from 'react';
10
+ import type { Meta, StoryObj } from '@storybook/react-vite';
11
+ import {
12
+ Filters,
13
+ FilterSearch,
14
+ FilterSelect,
15
+ FilterMulti,
16
+ FilterToggle,
17
+ FilterWithin,
18
+ FilterCombobox,
19
+ FilterChips,
20
+ } from './Filters';
21
+ import type { FilterOption, FilterValues } from './Filters.types';
22
+
23
+ const statusOptions: FilterOption[] = [
24
+ { value: 'open', label: 'Open' },
25
+ { value: 'draft', label: 'Draft' },
26
+ { value: 'closed', label: 'Closed' },
27
+ ];
28
+ const teamOptions: FilterOption[] = [
29
+ { value: 'eng', label: 'Engineering' },
30
+ { value: 'design', label: 'Design' },
31
+ { value: 'ops', label: 'Operations' },
32
+ ];
33
+ const postedPresets: FilterOption[] = [
34
+ { value: 'any', label: 'Any time' },
35
+ { value: '24h', label: 'Last 24 hours' },
36
+ { value: '7d', label: 'Last 7 days' },
37
+ { value: '30d', label: 'Last 30 days' },
38
+ ];
39
+
40
+ const meta = {
41
+ title: 'Elements/Filters',
42
+ component: Filters,
43
+ tags: ['autodocs'],
44
+ parameters: {
45
+ layout: 'padded',
46
+ docs: {
47
+ description: {
48
+ component:
49
+ 'A compositional filter bar. `<Filters values onChange labels>` owns one controlled values map; controls are composed as children and `<FilterChips>` renders removable chips. Domain-free (labels-as-props), non-modal popovers, WCAG 2.2 AAA.',
50
+ },
51
+ },
52
+ },
53
+ } satisfies Meta<typeof Filters>;
54
+
55
+ export default meta;
56
+ type Story = StoryObj<typeof meta>;
57
+
58
+ /** A full bar with every control kind plus removable chips. */
59
+ export const Default: Story = {
60
+ render: function FiltersStory(): ReactElement {
61
+ const [values, setValues] = useState<FilterValues>({ status: 'open', team: ['eng'] });
62
+ return (
63
+ <Filters
64
+ values={values}
65
+ onChange={setValues}
66
+ labels={{ done: 'Done', clear: 'Clear' }}
67
+ aria-label="Filter positions"
68
+ >
69
+ <FilterSearch name="q" label="Search positions" placeholder="Search name or title…" />
70
+ <FilterSelect name="status" label="Status" options={statusOptions} />
71
+ <FilterMulti name="team" label="Team" options={teamOptions} />
72
+ <FilterWithin name="posted" label="Posted" presets={postedPresets} />
73
+ <FilterToggle name="remote" label="Remote only" />
74
+ <FilterChips clearAllLabel="Clear all" removeChipLabel={(label) => `Remove ${label}`} />
75
+ </Filters>
76
+ );
77
+ },
78
+ };
79
+
80
+ /**
81
+ * API-backed type-ahead with `FilterCombobox` — the consumer fetches options in
82
+ * response to `onSearch` (debounce in real apps); the selected label persists in
83
+ * the chip even as the option list changes.
84
+ */
85
+ export const AsyncCombobox: Story = {
86
+ render: function AsyncStory(): ReactElement {
87
+ const [values, setValues] = useState<FilterValues>({});
88
+ const [options, setOptions] = useState<FilterOption[]>([]);
89
+ const directory: FilterOption[] = [
90
+ { value: 'u1', label: 'Ada Lovelace' },
91
+ { value: 'u2', label: 'Alan Turing' },
92
+ { value: 'u3', label: 'Grace Hopper' },
93
+ ];
94
+ return (
95
+ <Filters values={values} onChange={setValues} labels={{ done: 'Done', clear: 'Clear' }}>
96
+ <FilterCombobox
97
+ name="assignee"
98
+ label="Assignee"
99
+ placeholder="Search people…"
100
+ options={options}
101
+ onSearch={(query) =>
102
+ setOptions(
103
+ query
104
+ ? directory.filter((o) => o.label.toLowerCase().includes(query.toLowerCase()))
105
+ : []
106
+ )
107
+ }
108
+ />
109
+ <FilterChips clearAllLabel="Clear all" removeChipLabel={(label) => `Remove ${label}`} />
110
+ </Filters>
111
+ );
112
+ },
113
+ };
114
+
115
+ /**
116
+ * Mobile (narrow) — the bar collapses to a "Filters" button that opens a
117
+ * bottom-sheet of stacked controls; chips scroll horizontally. Pass `narrow`
118
+ * (measure once with `useContainerNarrow` and share it with your table switch).
119
+ */
120
+ export const Mobile: Story = {
121
+ render: function MobileStory(): ReactElement {
122
+ const [values, setValues] = useState<FilterValues>({ status: 'open', team: ['eng'] });
123
+ return (
124
+ <div style={{ maxWidth: 380 }}>
125
+ <Filters
126
+ values={values}
127
+ onChange={setValues}
128
+ narrow
129
+ aria-label="Filter positions"
130
+ labels={{
131
+ done: 'Done',
132
+ clear: 'Clear',
133
+ clearAll: 'Clear all',
134
+ close: 'Close',
135
+ filtersButton: 'Filters',
136
+ }}
137
+ >
138
+ <FilterSearch name="q" label="Search positions" placeholder="Search…" />
139
+ <FilterSelect name="status" label="Status" options={statusOptions} />
140
+ <FilterMulti name="team" label="Team" options={teamOptions} />
141
+ <FilterWithin name="posted" label="Posted" presets={postedPresets} />
142
+ <FilterToggle name="remote" label="Remote only" />
143
+ <FilterChips clearAllLabel="Clear all" removeChipLabel={(label) => `Remove ${label}`} />
144
+ </Filters>
145
+ </div>
146
+ );
147
+ },
148
+ };
@@ -1,6 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { Plus } from 'lucide-react';
3
3
  import { Button } from '../Button';
4
+ import { Tabs, TabList, Tab } from '../Tabs';
4
5
  import { PageTitle } from './PageTitle';
5
6
 
6
7
  const BREADCRUMB_ITEMS = [
@@ -103,17 +104,13 @@ export const DefaultWithTabs: Story = {
103
104
  Manage the public careers site pages and branding.
104
105
  </PageTitle.Description>
105
106
  <PageTitle.Tabs>
106
- <nav aria-label="Site sections" className="flex gap-4 border-b border-[var(--border)]">
107
- <a href="/pages" className="px-3 py-2 border-b-2 border-[var(--primary)]">
108
- Page Builder
109
- </a>
110
- <a href="/pages/theme" className="px-3 py-2">
111
- Theme
112
- </a>
113
- <a href="/pages/domain" className="px-3 py-2">
114
- Domain
115
- </a>
116
- </nav>
107
+ <Tabs defaultSelectedKey="pages">
108
+ <TabList aria-label="Site sections">
109
+ <Tab id="pages">Page Builder</Tab>
110
+ <Tab id="theme">Theme</Tab>
111
+ <Tab id="domain">Domain</Tab>
112
+ </TabList>
113
+ </Tabs>
117
114
  </PageTitle.Tabs>
118
115
  </PageTitle>
119
116
  ),
@@ -164,14 +161,13 @@ export const FeatureWithTabs: Story = {
164
161
  </Button>
165
162
  </PageTitle.Actions>
166
163
  <PageTitle.Tabs>
167
- <nav
168
- aria-label="Library sections"
169
- className="flex gap-4 bg-[var(--content-background)] px-4 py-2"
170
- >
171
- <a href="/fields">All fields</a>
172
- <a href="/fields/groups">Groups</a>
173
- <a href="/fields/categories">Categories</a>
174
- </nav>
164
+ <Tabs defaultSelectedKey="all">
165
+ <TabList aria-label="Library sections">
166
+ <Tab id="all">All fields</Tab>
167
+ <Tab id="groups">Groups</Tab>
168
+ <Tab id="categories">Categories</Tab>
169
+ </TabList>
170
+ </Tabs>
175
171
  </PageTitle.Tabs>
176
172
  </PageTitle>
177
173
  ),
@@ -71,7 +71,7 @@ function PanelSkeletonForWidth({
71
71
  const widthPx = { sm: 220, md: 280, lg: 340, xl: 420 }[width];
72
72
  return (
73
73
  <div aria-hidden="true" style={{ width: `${widthPx}px` }} className="shrink-0">
74
- <div className="flex items-center px-3 py-2 border-b border-[var(--border)] h-[40px]">
74
+ <div className="flex items-center px-3 py-2 h-[40px]">
75
75
  <Skeleton variant="text" className="h-4 w-[100px]" />
76
76
  </div>
77
77
  <div className="flex flex-col gap-2 p-3">
@@ -105,6 +105,7 @@ function SidebarDemo({
105
105
  showBadges = false,
106
106
  withSkeleton = true,
107
107
  railVariant = 'default' as SidebarRailVariant,
108
+ showActiveIndicator = true,
108
109
  }: {
109
110
  defaultCollapsed?: boolean;
110
111
  showPanel?: boolean;
@@ -112,13 +113,14 @@ function SidebarDemo({
112
113
  showBadges?: boolean;
113
114
  withSkeleton?: boolean;
114
115
  railVariant?: SidebarRailVariant;
116
+ showActiveIndicator?: boolean;
115
117
  }): ReactElement {
116
118
  const [activeId, setActiveId] = useState('home');
117
119
 
118
120
  return (
119
121
  <div className="flex h-screen bg-[var(--page-background)]">
120
122
  <Sidebar defaultCollapsed={defaultCollapsed}>
121
- <Sidebar.Rail aria-label="Main navigation" variant={railVariant}>
123
+ <Sidebar.Rail aria-label="Main navigation" variant={railVariant} showActiveIndicator={showActiveIndicator}>
122
124
  {showPanel && <Sidebar.CollapseButton />}
123
125
  {NAV_ITEMS.map((item) => (
124
126
  <Sidebar.RailItem
@@ -172,6 +174,15 @@ export const RailOnly: Story = {
172
174
  render: () => <SidebarDemo showPanel={false} />,
173
175
  };
174
176
 
177
+ /**
178
+ * Active-item indicator switched off via `showActiveIndicator={false}` on
179
+ * `Sidebar.Rail`. The active item is still distinguished by its filled chip and
180
+ * coloured label, but the divider notch pointing at it is omitted.
181
+ */
182
+ export const ActiveIndicatorOff: Story = {
183
+ render: () => <SidebarDemo showActiveIndicator={false} />,
184
+ };
185
+
175
186
  /** Panel starts in collapsed state */
176
187
  export const CollapsedPanel: Story = {
177
188
  render: () => <SidebarDemo defaultCollapsed />,