@3fn/core 13.0.0 → 14.0.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 (236) hide show
  1. package/.kiro/agents/ada-prompt.md +80 -132
  2. package/.kiro/agents/ada-prompt.md.attribution.json +45 -0
  3. package/.kiro/agents/ada.json +44 -59
  4. package/.kiro/agents/ada.json.attribution.json +13 -0
  5. package/.kiro/agents/data-prompt.md +83 -74
  6. package/.kiro/agents/data-prompt.md.attribution.json +53 -0
  7. package/.kiro/agents/data.json +31 -38
  8. package/.kiro/agents/data.json.attribution.json +13 -0
  9. package/.kiro/agents/kenya-prompt.md +83 -72
  10. package/.kiro/agents/kenya-prompt.md.attribution.json +53 -0
  11. package/.kiro/agents/kenya.json +27 -35
  12. package/.kiro/agents/kenya.json.attribution.json +13 -0
  13. package/.kiro/agents/leonardo-prompt.md +176 -234
  14. package/.kiro/agents/leonardo-prompt.md.attribution.json +45 -0
  15. package/.kiro/agents/leonardo.json +28 -36
  16. package/.kiro/agents/leonardo.json.attribution.json +13 -0
  17. package/.kiro/agents/lina-prompt.md +110 -151
  18. package/.kiro/agents/lina-prompt.md.attribution.json +53 -0
  19. package/.kiro/agents/lina.json +46 -59
  20. package/.kiro/agents/lina.json.attribution.json +13 -0
  21. package/.kiro/agents/sparky-prompt.md +89 -72
  22. package/.kiro/agents/sparky-prompt.md.attribution.json +53 -0
  23. package/.kiro/agents/sparky.json +37 -37
  24. package/.kiro/agents/sparky.json.attribution.json +13 -0
  25. package/.kiro/agents/stacy-prompt.md +74 -48
  26. package/.kiro/agents/stacy-prompt.md.attribution.json +45 -0
  27. package/.kiro/agents/stacy.json +28 -30
  28. package/.kiro/agents/stacy.json.attribution.json +13 -0
  29. package/.kiro/agents/thurgood-prompt.md +94 -138
  30. package/.kiro/agents/thurgood-prompt.md.attribution.json +45 -0
  31. package/.kiro/agents/thurgood.json +31 -35
  32. package/.kiro/agents/thurgood.json.attribution.json +13 -0
  33. package/.kiro/steering/AI-Collaboration-Principles.md +3 -3
  34. package/.kiro/steering/Civitas-System-Overview.md +5 -5
  35. package/.kiro/steering/DesignerPunk-Systems-Overview.md +6 -6
  36. package/.kiro/steering/Task-Completion-Protocol.md +98 -17
  37. package/.kiro/steering/core-goals.md +3 -3
  38. package/.kiro/steering/personal-note.md +1 -1
  39. package/.kiro/steering/start-up-tasks.md +14 -3
  40. package/application-mcp-server/src/index.ts +26 -0
  41. package/dist/ComponentTokens.android.kt +1 -1
  42. package/dist/ComponentTokens.ios.swift +1 -1
  43. package/dist/ComponentTokens.web.css +1 -1
  44. package/dist/DesignTokens.android.kt +1 -1
  45. package/dist/DesignTokens.dtcg.json +8 -5
  46. package/dist/DesignTokens.figma.json +2 -2
  47. package/dist/DesignTokens.ios.swift +1 -1
  48. package/dist/DesignTokens.web.css +1 -1
  49. package/dist/android/DesignTokens.android.kt +1 -1
  50. package/dist/blend/OklchBlendCalculator.js +1 -0
  51. package/dist/blend/ThemeAwareBlendUtilities.web.d.ts +13 -2
  52. package/dist/blend/ThemeAwareBlendUtilities.web.js +6 -1
  53. package/dist/browser/designerpunk.esm.js +22 -81
  54. package/dist/browser/designerpunk.esm.min.js +29 -32
  55. package/dist/browser/designerpunk.umd.js +22 -81
  56. package/dist/browser/designerpunk.umd.min.js +42 -45
  57. package/dist/browser/tokens.css +1 -1
  58. package/dist/components/core/Avatar-Base/platforms/web/Avatar.web.js +24 -5
  59. package/dist/components/core/Button-CTA/examples/BasicUsage.d.ts +16 -28
  60. package/dist/components/core/Button-CTA/examples/BasicUsage.js +18 -43
  61. package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.d.ts +3 -15
  62. package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.js +9 -58
  63. package/dist/components/core/Button-CTA/types.d.ts +0 -24
  64. package/dist/components/core/Button-CTA/types.js +6 -0
  65. package/dist/components/core/Input-Text-Base/types.d.ts +13 -1
  66. package/dist/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.js +11 -2
  67. package/dist/generators/DTCGFormatGenerator.js +8 -0
  68. package/dist/integration/BuildErrorHandler.js +2 -2
  69. package/dist/ios/DesignTokens.ios.swift +1 -1
  70. package/dist/mcp/application-mcp.js +24 -0
  71. package/dist/mcp/docs-mcp.js +130 -15
  72. package/dist/mcp/product-mcp.js +25 -0
  73. package/dist/tokens/OpacityTokens.js +1 -1
  74. package/dist/tokens/semantic/BlendTokens.d.ts +10 -3
  75. package/dist/tokens/semantic/BlendTokens.js +17 -5
  76. package/dist/tokens/semantic/OpacityTokens.d.ts +4 -4
  77. package/dist/tokens/semantic/OpacityTokens.js +4 -4
  78. package/dist/types/ComponentTypes.d.ts +1 -1
  79. package/dist/types/generated/TokenTypes.d.ts +1 -1
  80. package/dist/types/generated/TokenTypes.js +1 -1
  81. package/dist/validators/StemmaTokenUsageValidator.js +3 -2
  82. package/dist/web/DesignTokens.web.css +1 -1
  83. package/governance/Component-Development-Guide.md +22 -12
  84. package/governance/Component-Development-Standards.md +2 -2
  85. package/governance/Component-Family-Avatar.md +0 -1
  86. package/governance/Component-Family-Badge.md +0 -1
  87. package/governance/Component-Family-Button.md +4 -17
  88. package/governance/Component-Family-Chip.md +0 -1
  89. package/governance/Component-Family-Container.md +0 -1
  90. package/governance/Component-Family-Data-Display.md +1 -2
  91. package/governance/Component-Family-Divider.md +1 -2
  92. package/governance/Component-Family-Form-Inputs.md +5 -5
  93. package/governance/Component-Family-Icon.md +1 -2
  94. package/governance/Component-Family-Loading.md +1 -2
  95. package/governance/Component-Family-Modal.md +1 -2
  96. package/governance/Component-Family-Navigation.md +0 -1
  97. package/governance/Component-Family-Progress.md +0 -1
  98. package/governance/Component-Inheritance-Structures.md +195 -76
  99. package/governance/Component-MCP-Document-Template.md +6 -5
  100. package/governance/Component-Primitive-vs-Semantic-Philosophy.md +1 -1
  101. package/governance/Component-Quick-Reference.md +33 -33
  102. package/governance/Component-Readiness-Status.md +54 -38
  103. package/governance/Component-Templates.md +32 -36
  104. package/governance/Contract-System-Reference.md +6 -6
  105. package/governance/MCP-Integration-Guide.md +1 -1
  106. package/governance/Process-Cross-Reference-Standards.md +31 -13
  107. package/governance/Process-Development-Workflow.md +49 -59
  108. package/governance/Process-File-Organization.md +24 -24
  109. package/governance/Process-Hook-Operations.md +19 -7
  110. package/governance/Process-Orchestration-Model-Selection.md +92 -0
  111. package/governance/Process-Spec-Planning.md +91 -39
  112. package/governance/Process-Task-Type-Definitions.md +80 -4
  113. package/governance/Product-Handoff-Protocol.md +2 -0
  114. package/governance/Rosetta-System-Architecture.md +6 -6
  115. package/governance/Test-Behavioral-Contract-Validation.md +38 -31
  116. package/governance/Test-Failure-Audit-Methodology.md +1 -1
  117. package/governance/Token-Family-Accessibility.md +1 -2
  118. package/governance/Token-Family-Blend.md +18 -16
  119. package/governance/Token-Family-Blur.md +0 -1
  120. package/governance/Token-Family-Border.md +1 -2
  121. package/governance/Token-Family-Color.md +0 -1
  122. package/governance/Token-Family-Glow.md +1 -2
  123. package/governance/Token-Family-Layering.md +0 -1
  124. package/governance/Token-Family-Motion.md +1 -2
  125. package/governance/Token-Family-Opacity.md +0 -1
  126. package/governance/Token-Family-Radius.md +1 -2
  127. package/governance/Token-Family-Responsive.md +1 -2
  128. package/governance/Token-Family-Shadow.md +1 -2
  129. package/governance/Token-Family-Sizing.md +0 -1
  130. package/governance/Token-Family-Spacing.md +1 -2
  131. package/governance/Token-Family-Typography.md +1 -2
  132. package/governance/Token-Governance.md +8 -8
  133. package/governance/Token-Quick-Reference.md +21 -21
  134. package/governance/Token-Resolution-Patterns.md +1 -1
  135. package/governance/Token-Semantic-Structure.md +1 -1
  136. package/governance/Web-Authoring-Standards.md +5 -5
  137. package/governance/browser-distribution-guide.md +1 -4
  138. package/governance/classification-map.md +368 -0
  139. package/governance/completion-documentation-guide.md +11 -8
  140. package/governance/component-meta-authoring-guide.md +1 -1
  141. package/governance/cross-platform-vs-platform-specific-decision-framework.md +1 -1
  142. package/governance/platform-implementation-guidelines.md +1 -1
  143. package/governance/release-management-system.md +2 -2
  144. package/governance/rosetta-system-principles.md +8 -6
  145. package/governance/stemma-system-principles.md +18 -17
  146. package/mcp-server/src/index.ts +24 -6
  147. package/mcp-server/src/indexer/DocumentIndexer.ts +119 -9
  148. package/mcp-server/src/indexer/__tests__/bare-id-crossrefs.test.ts +250 -0
  149. package/mcp-server/src/indexer/cross-ref-parser.ts +29 -1
  150. package/mcp-server/src/indexer/index-health.ts +27 -2
  151. package/mcp-server/src/query/__tests__/find-docs-calibration.test.ts +11 -26
  152. package/mcp-server/src/relocation-integrity-gate/__tests__/relocation-integrity-gate.test.ts +72 -5
  153. package/mcp-server/src/relocation-integrity-gate/relocation-integrity-gate.ts +81 -24
  154. package/mcp-server/src/tools/list-cross-references.ts +2 -2
  155. package/package.json +23 -21
  156. package/src/__tests__/browser-distribution/css-bundling.test.ts +6 -4
  157. package/src/__tests__/console-allowlist.json +14 -0
  158. package/src/__tests__/console-fail-setup.ts +169 -0
  159. package/src/__tests__/integration/Spec107-DesignLanguageContext.test.ts +16 -0
  160. package/src/__tests__/stemma-system/behavioral-contract-validation.test.ts +70 -17
  161. package/src/__tests__/stemma-system/contract-catalog-name-validation.test.ts +28 -0
  162. package/src/__tests__/stemma-system/form-inputs-contracts.test.ts +223 -16
  163. package/src/__tests__/stemma-system/input-text-native-base-call-alignment.test.ts +298 -0
  164. package/src/blend/OklchBlendCalculator.ts +3 -0
  165. package/src/blend/ThemeAwareBlendUtilities.android.kt +3 -0
  166. package/src/blend/ThemeAwareBlendUtilities.ios.swift +3 -0
  167. package/src/blend/ThemeAwareBlendUtilities.web.ts +9 -1
  168. package/src/blend/__tests__/InteractionStateAudit.test.ts +12 -9
  169. package/src/build/errors/__tests__/ErrorHandler.integration.test.ts +8 -0
  170. package/src/build/errors/__tests__/ErrorHandler.test.ts +5 -0
  171. package/src/build/workflow/__tests__/CICDIntegration.test.ts +12 -1
  172. package/src/cli/__tests__/init.test.ts +45 -11
  173. package/src/components/core/Avatar-Base/Avatar-Base.schema.yaml +1 -1
  174. package/src/components/core/Avatar-Base/__tests__/Avatar.accessibility.test.ts +121 -7
  175. package/src/components/core/Avatar-Base/__tests__/Avatar.image.test.ts +3 -0
  176. package/src/components/core/Avatar-Base/__tests__/Avatar.test.ts +15 -6
  177. package/src/components/core/Avatar-Base/contracts.yaml +11 -1
  178. package/src/components/core/Avatar-Base/platforms/web/Avatar.web.ts +24 -5
  179. package/src/components/core/Badge-Count-Base/contracts.yaml +1 -1
  180. package/src/components/core/Badge-Label-Base/contracts.yaml +1 -1
  181. package/src/components/core/Button-CTA/Button-CTA.schema.yaml +2 -12
  182. package/src/components/core/Button-CTA/README.md +3 -6
  183. package/src/components/core/Button-CTA/__tests__/ButtonCTA.test.ts +35 -89
  184. package/src/components/core/Button-CTA/__tests__/setup.test.ts +0 -2
  185. package/src/components/core/Button-CTA/__tests__/test-utils.ts +0 -2
  186. package/src/components/core/Button-CTA/contracts.yaml +6 -29
  187. package/src/components/core/Button-CTA/examples/BasicUsage.html +2 -14
  188. package/src/components/core/Button-CTA/examples/BasicUsage.tsx +17 -44
  189. package/src/components/core/Button-CTA/platforms/android/ButtonCTA.android.kt +12 -20
  190. package/src/components/core/Button-CTA/platforms/ios/ButtonCTA.ios.swift +12 -51
  191. package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.css +2 -26
  192. package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.ts +18 -71
  193. package/src/components/core/Button-CTA/types.ts +10 -28
  194. package/src/components/core/Chip-Base/__tests__/ChipBase.test.ts +13 -0
  195. package/src/components/core/Chip-Filter/__tests__/ChipFilter.test.ts +13 -0
  196. package/src/components/core/Chip-Input/__tests__/ChipInput.test.ts +13 -0
  197. package/src/components/core/Input-Text-Base/Input-Text-Base.schema.yaml +30 -2
  198. package/src/components/core/Input-Text-Base/README.md +25 -2
  199. package/src/components/core/Input-Text-Base/__tests__/focusIndicators.test.ts +16 -15
  200. package/src/components/core/Input-Text-Base/contracts.yaml +90 -0
  201. package/src/components/core/Input-Text-Base/platforms/android/InputTextBase.android.kt +26 -12
  202. package/src/components/core/Input-Text-Base/platforms/ios/InputTextBase.ios.swift +195 -59
  203. package/src/components/core/Input-Text-Base/types.ts +13 -1
  204. package/src/components/core/Input-Text-Email/Input-Text-Email.schema.yaml +5 -1
  205. package/src/components/core/Input-Text-Email/README.md +8 -7
  206. package/src/components/core/Input-Text-Email/platforms/android/InputTextEmail.android.kt +1 -4
  207. package/src/components/core/Input-Text-Email/platforms/ios/InputTextEmail.ios.swift +2 -16
  208. package/src/components/core/Input-Text-Password/Input-Text-Password.schema.yaml +10 -3
  209. package/src/components/core/Input-Text-Password/README.md +9 -8
  210. package/src/components/core/Input-Text-Password/contracts.yaml +5 -0
  211. package/src/components/core/Input-Text-Password/platforms/android/InputTextPassword.android.kt +17 -7
  212. package/src/components/core/Input-Text-Password/platforms/ios/InputTextPassword.ios.swift +22 -20
  213. package/src/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.ts +11 -2
  214. package/src/components/core/Input-Text-PhoneNumber/Input-Text-PhoneNumber.schema.yaml +5 -1
  215. package/src/components/core/Input-Text-PhoneNumber/README.md +9 -8
  216. package/src/components/core/Input-Text-PhoneNumber/platforms/android/InputTextPhoneNumber.android.kt +2 -5
  217. package/src/components/core/Input-Text-PhoneNumber/platforms/ios/InputTextPhoneNumber.ios.swift +3 -17
  218. package/src/components/core/Nav-Header-App/contracts.yaml +1 -1
  219. package/src/components/core/Nav-SegmentedChoice-Base/contracts.yaml +1 -1
  220. package/src/components/core/Progress-Indicator-Connector-Base/contracts.yaml +1 -1
  221. package/src/components/core/Progress-Indicator-Label-Base/contracts.yaml +1 -1
  222. package/src/components/core/Progress-Indicator-Node-Base/contracts.yaml +1 -1
  223. package/src/components/core/Progress-Stepper-Base/__tests__/StepperBase.test.ts +5 -2
  224. package/src/components/core/Progress-Stepper-Detailed/__tests__/StepperDetailed.test.ts +5 -2
  225. package/src/generators/DTCGFormatGenerator.ts +6 -0
  226. package/src/generators/__tests__/DTCGConfigOptions.test.ts +14 -5
  227. package/src/integration/BuildErrorHandler.ts +2 -2
  228. package/src/tokens/OpacityTokens.ts +1 -1
  229. package/src/tokens/__tests__/OpacityTokens.test.ts +3 -1
  230. package/src/tokens/semantic/BlendTokens.ts +26 -5
  231. package/src/tokens/semantic/OpacityTokens.ts +4 -4
  232. package/src/tools/release/__tests__/ReleasePipeline.test.ts +1 -1
  233. package/src/types/ComponentTypes.ts +1 -1
  234. package/src/types/generated/TokenTypes.ts +1 -1
  235. package/src/validators/StemmaTokenUsageValidator.ts +3 -2
  236. package/token-index/semantics.yaml +1 -2
@@ -9,17 +9,14 @@ contracts:
9
9
  behavior: |
10
10
  Component can receive focus via Tab key navigation.
11
11
  Focus state is visually indicated with a focus ring.
12
- Focus is managed appropriately when disabled state changes.
13
12
  wcag: "2.1.1 Keyboard"
14
13
  platforms: [web, ios, android]
15
14
  validation:
16
15
  - Tab key moves focus to button
17
16
  - Focus state is visually distinct with focus ring
18
17
  - Focus ring meets 3:1 contrast ratio
19
- - Disabled buttons are not focusable
20
18
  test_approach: |
21
19
  - Render button, press Tab, verify focus
22
- - Set disabled=true, verify not focusable
23
20
  required: true
24
21
 
25
22
  interaction_pressable:
@@ -27,7 +24,7 @@ contracts:
27
24
  description: Responds to press/click events
28
25
  behavior: |
29
26
  Component responds to click, tap, Enter key, and Space key.
30
- Press triggers the onPress callback when not disabled.
27
+ Press triggers the onPress callback.
31
28
  Platform-appropriate feedback is provided during press.
32
29
  wcag: "2.1.1 Keyboard"
33
30
  platforms: [web, ios, android]
@@ -35,11 +32,9 @@ contracts:
35
32
  - Click/tap triggers onPress callback
36
33
  - Enter key triggers onPress callback
37
34
  - Space key triggers onPress callback
38
- - onPress not called when disabled
39
35
  test_approach: |
40
36
  - Click button, verify onPress called
41
37
  - Focus and press Enter, verify onPress called
42
- - Set disabled, click, verify onPress not called
43
38
  required: true
44
39
 
45
40
  interaction_hover:
@@ -56,10 +51,8 @@ contracts:
56
51
  - Background color darkens on mouse enter (ΔL 0.02–0.05)
57
52
  - Background color reverts on mouse leave
58
53
  - Chroma unchanged between rest and hover states
59
- - Hover state not shown when disabled
60
54
  test_approach: |
61
55
  - Simulate hover, verify background change
62
- - Set disabled, simulate hover, verify no change
63
56
  required: true
64
57
 
65
58
  interaction_pressed:
@@ -76,31 +69,10 @@ contracts:
76
69
  - Visual feedback shown during press (ΔL 0.05–0.10)
77
70
  - Pressed state is perceptibly stronger than hover
78
71
  - Platform-appropriate animation/effect applied
79
- - Pressed state not shown when disabled
80
72
  test_approach: |
81
73
  - Simulate press, verify visual feedback
82
74
  required: true
83
75
 
84
- state_disabled:
85
- category: state
86
- description: Prevents interaction when disabled
87
- behavior: |
88
- When disabled, component cannot receive focus, cannot be clicked/tapped,
89
- appears visually muted via chroma reduction (OKLCH ΔC ≥0.03 desaturation),
90
- shows cursor: not-allowed (web), and communicates disabled state to
91
- assistive technology.
92
- wcag: "4.1.2 Name, Role, Value"
93
- platforms: [web, ios, android]
94
- validation:
95
- - Button cannot receive focus when disabled
96
- - onPress not called when disabled
97
- - Visual styling indicates disabled state (chroma reduced ≥0.03)
98
- - aria-disabled="true" set (web)
99
- test_approach: |
100
- - Set disabled=true, verify not focusable
101
- - Verify aria-disabled attribute (web)
102
- required: true
103
-
104
76
  state_loading:
105
77
  category: state
106
78
  description: Shows loading indicator during async operations
@@ -138,3 +110,8 @@ contracts:
138
110
  - Tab to button, verify focus ring visible
139
111
  - Test in each variant
140
112
  required: true
113
+
114
+ excludes:
115
+ state_disabled:
116
+ reason: "DesignerPunk does not support disabled states for usability and accessibility reasons. If an action is unavailable, the component should not be rendered."
117
+ category: state
@@ -99,12 +99,8 @@
99
99
  </div>
100
100
 
101
101
  <div class="example-section">
102
- <h2>Example 4: Disabled Button</h2>
103
- <p>Button in disabled state that cannot be interacted with.</p>
104
- <div class="button-container">
105
- <button-cta id="disabled-btn" label="Submit" disabled></button-cta>
106
- </div>
107
- <div class="output" id="disabled-output">This button is disabled and won't respond to clicks.</div>
102
+ <h2>Example 4: Unavailable Actions</h2>
103
+ <p>DesignerPunk does not support disabled states. If an action is unavailable, the button should not be rendered. For in-flight async operations, use the loading state instead.</p>
108
104
  </div>
109
105
 
110
106
  <script type="module">
@@ -132,14 +128,6 @@
132
128
  handlerOutput.textContent = `Form submitted at ${new Date().toLocaleTimeString()}`;
133
129
  // In a real app, you would validate and submit form data here
134
130
  });
135
-
136
- // Example 4: Disabled button
137
- const disabledBtn = document.getElementById('disabled-btn');
138
- const disabledOutput = document.getElementById('disabled-output');
139
- disabledBtn.addEventListener('press', () => {
140
- // This will never be called because button is disabled
141
- disabledOutput.textContent = 'This should never appear!';
142
- });
143
131
  </script>
144
132
  </body>
145
133
  </html>
@@ -22,7 +22,6 @@ import { ButtonCTA } from '../platforms/web/ButtonCTA.web';
22
22
  * - size: 'medium' (48px height)
23
23
  * - variant: 'primary' (filled background with primary color)
24
24
  * - noWrap: false (text wraps if needed)
25
- * - disabled: false (interactive)
26
25
  *
27
26
  * @example
28
27
  * ```html
@@ -79,7 +78,6 @@ export function customLabelButton(): void {
79
78
  *
80
79
  * The 'press' event:
81
80
  * - Bubbles up through the DOM
82
- * - Is not called when button is disabled
83
81
  * - Works with click, tap, Enter key, and Space key
84
82
  * - Provides originalEvent in event.detail for advanced use cases
85
83
  *
@@ -111,55 +109,37 @@ export function buttonWithHandler(): void {
111
109
  }
112
110
 
113
111
  /**
114
- * Example 4: Disabled Button
112
+ * Example 4: Unavailable Actions (no disabled state)
115
113
  *
116
- * Demonstrates how to disable a button to prevent user interaction.
117
- * Disabled buttons are commonly used during form submission, when prerequisites
118
- * aren't met, or when an action is temporarily unavailable.
114
+ * DesignerPunk does not support disabled states for usability and
115
+ * accessibility reasons. If an action is unavailable, the component
116
+ * should not be rendered.
119
117
  *
120
- * Disabled button behavior:
121
- * - Not keyboard focusable (skipped in Tab order)
122
- * - Does not respond to clicks or keyboard activation
123
- * - Visual styling indicates non-interactive state
124
- * - Screen readers announce disabled state
125
- * - onPress handler is not called
126
- *
127
- * Common use cases:
128
- * - Form submission in progress
129
- * - Required fields not filled
130
- * - User lacks permissions
131
- * - Action temporarily unavailable
132
- *
133
- * @example
134
- * ```html
135
- * <button-cta label="Submit" disabled></button-cta>
136
- * ```
118
+ * For in-flight async operations (e.g. form submission), use the loading
119
+ * state instead of disabling the button. For actions the user cannot take
120
+ * yet, keep the button interactive and validate on press, or do not render
121
+ * the button at all.
137
122
  *
138
123
  * @example
139
124
  * ```typescript
140
- * // Conditional disable based on form state
141
- * const button = document.createElement('button-cta') as ButtonCTA;
142
- * button.label = 'Submit';
143
- * button.disabled = isSubmitting || !isFormValid;
125
+ * // Conditionally render instead of disabling
126
+ * if (userCanSubmit) {
127
+ * const button = document.createElement('button-cta') as ButtonCTA;
128
+ * button.label = 'Submit';
129
+ * button.addEventListener('press', handleSubmit);
130
+ * document.body.appendChild(button);
131
+ * }
144
132
  * ```
145
133
  */
146
- export function disabledButton(): void {
134
+ export function conditionallyRenderedButton(): void {
147
135
  const button = document.createElement('button-cta') as ButtonCTA;
148
136
  button.label = 'Submit';
149
- button.disabled = true; // Button is non-interactive
150
137
 
151
- // This handler will NOT be called when button is disabled
152
138
  button.addEventListener('press', () => {
153
- console.log('This will not be logged when button is disabled');
139
+ console.log('Submitted');
154
140
  });
155
141
 
156
142
  document.body.appendChild(button);
157
-
158
- // Example: Enable button after 3 seconds (simulating async operation)
159
- setTimeout(() => {
160
- button.disabled = false;
161
- console.log('Button is now enabled');
162
- }, 3000);
163
143
  }
164
144
 
165
145
  /**
@@ -202,13 +182,6 @@ export function renderAllBasicExamples(): void {
202
182
  });
203
183
  container.appendChild(handlerBtn);
204
184
 
205
- // Example 4: Disabled
206
- const disabledBtn = document.createElement('button-cta') as ButtonCTA;
207
- disabledBtn.label = 'Disabled Button';
208
- disabledBtn.disabled = true;
209
- disabledBtn.addEventListener('press', () => console.log('This will not log'));
210
- container.appendChild(disabledBtn);
211
-
212
185
  // Add container to document
213
186
  document.body.appendChild(container);
214
187
  }
@@ -11,7 +11,7 @@
11
11
  * while maintaining API consistency with web and iOS platforms.
12
12
  *
13
13
  * Uses theme-aware blend utilities (Color extensions with Compose MaterialTheme) for
14
- * state colors (hover, pressed, disabled, icon) instead of opacity or Material ripple
14
+ * state colors (hover, pressed, icon) instead of opacity or Material ripple
15
15
  * workarounds. This ensures cross-platform consistency with Web and iOS implementations.
16
16
  *
17
17
  * Part of the DesignerPunk CTA Button Component system.
@@ -42,11 +42,10 @@ import androidx.compose.ui.unit.dp
42
42
  import androidx.compose.ui.unit.sp
43
43
  import com.designerpunk.tokens.DesignTokens
44
44
  // Import theme-aware blend utilities (Color extension functions from ThemeAwareBlendUtilities.android.kt)
45
- // These provide semantic blend methods: hoverBlend(), pressedBlend(), disabledBlend(), iconBlend()
45
+ // These provide semantic blend methods: hoverBlend(), pressedBlend(), iconBlend()
46
46
  // @see Requirements: 11.1, 11.2, 11.3 - Theme-aware utilities
47
47
  import com.designerpunk.tokens.hoverBlend
48
48
  import com.designerpunk.tokens.pressedBlend
49
- import com.designerpunk.tokens.disabledBlend
50
49
  import com.designerpunk.tokens.iconBlend
51
50
 
52
51
  /**
@@ -88,8 +87,8 @@ enum class ButtonCTAStyle {
88
87
  * three size variants, three visual styles, optional leading icons, and
89
88
  * theme-aware blend utilities for state colors.
90
89
  *
91
- * Uses theme-aware Color extensions (hoverBlend(), pressedBlend(), disabledBlend(),
92
- * iconBlend()) with Compose MaterialTheme for automatic theme color updates.
90
+ * Uses theme-aware Color extensions (hoverBlend(), pressedBlend(), iconBlend())
91
+ * with Compose MaterialTheme for automatic theme color updates.
93
92
  *
94
93
  * Usage:
95
94
  * ```kotlin
@@ -120,7 +119,7 @@ enum class ButtonCTAStyle {
120
119
  * Requirements:
121
120
  * - 1.1-1.7: Size variants (small: 40dp, medium: 48dp, large: 56dp)
122
121
  * - 2.1-2.4: Visual styles (primary, secondary, tertiary)
123
- * - 7.1-7.4: Blend utility state colors (hover, pressed, disabled, icon)
122
+ * - 7.1-7.4: Blend utility state colors (hover, pressed, icon)
124
123
  * - 8.1-8.6: Icon support with leading position
125
124
  * - 11.1-11.3: Theme-aware blend utilities with Compose MaterialTheme
126
125
  * - 13.1-13.4: Touch target accessibility (44dp minimum)
@@ -132,7 +131,6 @@ enum class ButtonCTAStyle {
132
131
  * @param noWrap Prevent text wrapping (default: false)
133
132
  * @param onPress Click/tap handler (required)
134
133
  * @param testID Optional test identifier
135
- * @param disabled Optional disabled state (default: false)
136
134
  */
137
135
  @Composable
138
136
  fun ButtonCTA(
@@ -142,8 +140,7 @@ fun ButtonCTA(
142
140
  icon: String? = null,
143
141
  noWrap: Boolean = false,
144
142
  onPress: () -> Unit,
145
- testID: String? = null,
146
- disabled: Boolean = false
143
+ testID: String? = null
147
144
  ) {
148
145
  val theme = LocalDPTheme.current
149
146
  // Remember interaction source for tracking pressed state
@@ -154,7 +151,7 @@ fun ButtonCTA(
154
151
  val sizeConfig = getButtonCTASizeConfig(size)
155
152
 
156
153
  // Get style-based configuration with blend utilities
157
- val styleConfig = getButtonCTAStyleConfig(style, isPressed, disabled)
154
+ val styleConfig = getButtonCTAStyleConfig(style, isPressed)
158
155
 
159
156
  // Use Surface with clickable modifier (no ripple indication for cross-platform consistency)
160
157
  Surface(
@@ -169,7 +166,6 @@ fun ButtonCTA(
169
166
  // Apply clickable without ripple indication (blend colors handle state feedback)
170
167
  .clickable(
171
168
  onClick = onPress,
172
- enabled = !disabled,
173
169
  interactionSource = interactionSource,
174
170
  indication = null // No ripple - using blend colors for state feedback
175
171
  ),
@@ -316,7 +312,7 @@ private fun getButtonCTASizeConfig(size: ButtonCTASize): ButtonCTASizeConfig {
316
312
  * Style configuration data class
317
313
  *
318
314
  * Encapsulates all style-related properties for a button visual style.
319
- * Uses blend utilities for state colors (pressed, disabled, icon optical balance).
315
+ * Uses blend utilities for state colors (pressed, icon optical balance).
320
316
  *
321
317
  * @property backgroundColor Background color (includes state-based blend)
322
318
  * @property textColor Text color
@@ -338,36 +334,32 @@ private data class ButtonCTAStyleConfig(
338
334
  * Returns configuration object with all style-related properties based on
339
335
  * semantic color tokens and theme-aware blend utilities for state colors.
340
336
  *
341
- * Uses theme-aware Color extensions (hoverBlend(), pressedBlend(), disabledBlend(),
342
- * iconBlend()) instead of direct blend calculations for cross-platform consistency
337
+ * Uses theme-aware Color extensions (hoverBlend(), pressedBlend(), iconBlend())
338
+ * instead of direct blend calculations for cross-platform consistency
343
339
  * with Web and iOS implementations.
344
340
  *
345
341
  * Requirements:
346
342
  * - 2.1-2.4: Visual styles (primary, secondary, tertiary)
347
- * - 7.1-7.4: Blend utility state colors (hover, pressed, disabled, icon)
343
+ * - 7.1-7.4: Blend utility state colors (hover, pressed, icon)
348
344
  * - 9.1-9.3: Icon color with optical balance using blend utility
349
345
  * - 11.1-11.3: Theme-aware blend utilities with Compose MaterialTheme
350
346
  *
351
347
  * @param style Button visual style
352
348
  * @param isPressed Whether button is currently pressed
353
- * @param disabled Whether button is disabled
354
349
  * @return Style configuration object with blend-calculated colors
355
350
  */
356
- private fun getButtonCTAStyleConfig(style: ButtonCTAStyle, isPressed: Boolean, disabled: Boolean): ButtonCTAStyleConfig {
351
+ private fun getButtonCTAStyleConfig(style: ButtonCTAStyle, isPressed: Boolean): ButtonCTAStyleConfig {
357
352
  // Import semantic color tokens from generated constants
358
353
 
359
354
  // Calculate state-based background colors using theme-aware blend utilities
360
355
  // @see Requirements: 7.1, 7.2, 7.3, 11.1, 11.2, 11.3
361
356
  val primaryBgColor = when {
362
- // @see Requirements: 7.3 - Disabled uses desaturate(color.action.primary, blend.disabledDesaturate)
363
- disabled -> colorActionPrimary.disabledBlend()
364
357
  // @see Requirements: 7.2 - Pressed uses darkerBlend(color.action.primary, blend.pressedDarker)
365
358
  isPressed -> colorActionPrimary.pressedBlend()
366
359
  else -> colorActionPrimary
367
360
  }
368
361
 
369
362
  val secondaryBgColor = when {
370
- disabled -> colorBackground
371
363
  // @see Requirements: 7.2 - Pressed uses darkerBlend for secondary background
372
364
  isPressed -> colorBackground.pressedBlend()
373
365
  else -> colorBackground
@@ -11,7 +11,7 @@
11
11
  * while maintaining API consistency with web and Android platforms.
12
12
  *
13
13
  * Uses theme-aware blend utilities (Color extensions with SwiftUI environment) for
14
- * state colors (hover, pressed, disabled, icon) instead of opacity or scale workarounds.
14
+ * state colors (hover, pressed, icon) instead of opacity or scale workarounds.
15
15
  * This ensures cross-platform consistency with Web and Android implementations.
16
16
  *
17
17
  * Part of the DesignerPunk CTA Button Component system.
@@ -23,7 +23,7 @@
23
23
  import SwiftUI
24
24
 
25
25
  // Import theme-aware blend utilities (Color extensions from ThemeAwareBlendUtilities.ios.swift)
26
- // These provide semantic blend methods: hoverBlend(), pressedBlend(), disabledBlend(), iconBlend()
26
+ // These provide semantic blend methods: hoverBlend(), pressedBlend(), iconBlend()
27
27
  // @see Requirements: 11.1, 11.2, 11.3 - Theme-aware utilities
28
28
 
29
29
  /**
@@ -65,8 +65,8 @@ enum ButtonCTAStyle {
65
65
  * three size variants, three visual styles, optional leading icons, and
66
66
  * theme-aware blend utilities for state colors.
67
67
  *
68
- * Uses theme-aware Color extensions (hoverBlend(), pressedBlend(), disabledBlend(),
69
- * iconBlend()) with SwiftUI environment for automatic theme color updates.
68
+ * Uses theme-aware Color extensions (hoverBlend(), pressedBlend(), iconBlend())
69
+ * with SwiftUI environment for automatic theme color updates.
70
70
  *
71
71
  * Usage:
72
72
  * ```swift
@@ -97,7 +97,7 @@ enum ButtonCTAStyle {
97
97
  * Requirements:
98
98
  * - 1.1-1.7: Size variants (small: 40px, medium: 48px, large: 56px)
99
99
  * - 2.1-2.4: Visual styles (primary, secondary, tertiary)
100
- * - 7.1-7.4: Blend utility state colors (hover, pressed, disabled, icon)
100
+ * - 7.1-7.4: Blend utility state colors (hover, pressed, icon)
101
101
  * - 8.1-8.6: Icon support with leading position
102
102
  * - 11.1-11.3: Theme-aware blend utilities with SwiftUI environment
103
103
  * - 13.1-13.4: Touch target accessibility (44px minimum)
@@ -125,10 +125,7 @@ struct ButtonCTA: View {
125
125
 
126
126
  /// Optional test ID for automated testing
127
127
  let testID: String?
128
-
129
- /// Optional disabled state (default: false)
130
- let disabled: Bool
131
-
128
+
132
129
  // MARK: - State
133
130
 
134
131
  /// Tracks pressed state for scale transform animation
@@ -149,7 +146,6 @@ struct ButtonCTA: View {
149
146
  * - noWrap: Prevent text wrapping (default: false)
150
147
  * - onPress: Click/tap handler (required)
151
148
  * - testID: Optional test identifier
152
- * - disabled: Optional disabled state (default: false)
153
149
  */
154
150
  init(
155
151
  label: String,
@@ -158,8 +154,7 @@ struct ButtonCTA: View {
158
154
  icon: String? = nil,
159
155
  noWrap: Bool = false,
160
156
  onPress: @escaping () -> Void,
161
- testID: String? = nil,
162
- disabled: Bool = false
157
+ testID: String? = nil
163
158
  ) {
164
159
  self.label = label
165
160
  self.size = size
@@ -168,7 +163,6 @@ struct ButtonCTA: View {
168
163
  self.noWrap = noWrap
169
164
  self.onPress = onPress
170
165
  self.testID = testID
171
- self.disabled = disabled
172
166
  }
173
167
 
174
168
  // MARK: - Body
@@ -213,15 +207,12 @@ struct ButtonCTA: View {
213
207
  .simultaneousGesture(
214
208
  DragGesture(minimumDistance: 0)
215
209
  .onChanged { _ in
216
- if !disabled {
217
- isPressed = true
218
- }
210
+ isPressed = true
219
211
  }
220
212
  .onEnded { _ in
221
213
  isPressed = false
222
214
  }
223
215
  )
224
- .disabled(disabled)
225
216
  // Requirement 13.1-13.4, 16.4: Accessibility identifier for testing
226
217
  .accessibilityIdentifier(testID ?? "")
227
218
  // Requirement 17.4: Respect safe area insets for full-width buttons
@@ -230,14 +221,11 @@ struct ButtonCTA: View {
230
221
 
231
222
  // MARK: - Blend Color Computed Properties
232
223
 
233
- /// Current background color based on state (normal, hover, pressed, disabled)
224
+ /// Current background color based on state (normal, pressed)
234
225
  /// Uses theme-aware blend utilities (Color extensions) for cross-platform consistency
235
- /// @see Requirements: 7.1, 7.2, 7.3, 11.1, 11.2, 11.3
226
+ /// @see Requirements: 7.1, 7.2, 11.1, 11.2, 11.3
236
227
  private var currentBackgroundColor: Color {
237
- if disabled {
238
- // @see Requirements: 7.3 - Disabled uses desaturate(color.primary, blend.disabledDesaturate)
239
- return disabledBackgroundColor
240
- } else if isPressed {
228
+ if isPressed {
241
229
  // @see Requirements: 7.2 - Pressed uses darkerBlend(color.primary, blend.pressedDarker)
242
230
  return pressedBackgroundColor
243
231
  } else {
@@ -260,20 +248,6 @@ struct ButtonCTA: View {
260
248
  }
261
249
  }
262
250
 
263
- /// Disabled state background color using theme-aware blend utility
264
- /// Uses disabledBlend() which applies desaturate with blend.disabledDesaturate (12%)
265
- /// @see Requirements: 7.3, 11.1, 11.2, 11.3
266
- private var disabledBackgroundColor: Color {
267
- switch style {
268
- case .primary:
269
- return theme.colorActionPrimary.disabledBlend()
270
- case .secondary:
271
- return theme.colorStructureCanvas
272
- case .tertiary:
273
- return Color.clear
274
- }
275
- }
276
-
277
251
  // MARK: - Size-Based Computed Properties
278
252
 
279
253
  /// Typography token based on button size
@@ -532,20 +506,7 @@ struct ButtonCTA_Previews: PreviewProvider {
532
506
  onPress: { print("Confirm pressed") }
533
507
  )
534
508
  }
535
-
536
- Divider()
537
-
538
- // Disabled state
539
- Text("Disabled State")
540
- .font(.headline)
541
-
542
- VStack(spacing: 12) {
543
- ButtonCTA(
544
- label: "Disabled Button",
545
- disabled: true,
546
- onPress: { print("Should not print") }
547
- )
548
- }
509
+
549
510
  }
550
511
  .padding()
551
512
  }
@@ -275,7 +275,7 @@
275
275
  * The --_cta-hover-bg custom property is set by the component
276
276
  * using darkerBlend(color.primary, blend.hoverDarker) = 8% darker.
277
277
  */
278
- .button-cta--primary:hover:not(:disabled) {
278
+ .button-cta--primary:hover {
279
279
  background-color: var(--_cta-hover-bg);
280
280
  }
281
281
 
@@ -288,7 +288,7 @@
288
288
  * The --_cta-pressed-bg custom property is set by the component
289
289
  * using darkerBlend(color.primary, blend.pressedDarker) = 12% darker.
290
290
  */
291
- .button-cta--primary:active:not(:disabled) {
291
+ .button-cta--primary:active {
292
292
  background-color: var(--_cta-pressed-bg);
293
293
  }
294
294
 
@@ -318,30 +318,6 @@
318
318
  outline: none;
319
319
  }
320
320
 
321
- /**
322
- * Disabled state.
323
- *
324
- * Uses blend utility calculated color (desaturate with blend.disabledDesaturate)
325
- * instead of opacity workaround for cross-platform consistency.
326
- *
327
- * The --button-disabled-color custom property is set by the component
328
- * using desaturate(color.primary, blend.disabledDesaturate) = 12% less saturated.
329
- *
330
- * - Cursor changes to not-allowed
331
- * - Prevents interaction
332
- * - Maintains color contrast for accessibility
333
- */
334
- .button-cta:disabled,
335
- .button-cta--disabled {
336
- cursor: not-allowed;
337
- pointer-events: none;
338
- }
339
-
340
- .button-cta--primary:disabled,
341
- .button-cta--primary.button-cta--disabled {
342
- background-color: var(--_cta-disabled-bg);
343
- }
344
-
345
321
  /* ==========================================================================
346
322
  Responsive Behavior
347
323
  ========================================================================== */