@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.
- package/.kiro/agents/ada-prompt.md +80 -132
- package/.kiro/agents/ada-prompt.md.attribution.json +45 -0
- package/.kiro/agents/ada.json +44 -59
- package/.kiro/agents/ada.json.attribution.json +13 -0
- package/.kiro/agents/data-prompt.md +83 -74
- package/.kiro/agents/data-prompt.md.attribution.json +53 -0
- package/.kiro/agents/data.json +31 -38
- package/.kiro/agents/data.json.attribution.json +13 -0
- package/.kiro/agents/kenya-prompt.md +83 -72
- package/.kiro/agents/kenya-prompt.md.attribution.json +53 -0
- package/.kiro/agents/kenya.json +27 -35
- package/.kiro/agents/kenya.json.attribution.json +13 -0
- package/.kiro/agents/leonardo-prompt.md +176 -234
- package/.kiro/agents/leonardo-prompt.md.attribution.json +45 -0
- package/.kiro/agents/leonardo.json +28 -36
- package/.kiro/agents/leonardo.json.attribution.json +13 -0
- package/.kiro/agents/lina-prompt.md +110 -151
- package/.kiro/agents/lina-prompt.md.attribution.json +53 -0
- package/.kiro/agents/lina.json +46 -59
- package/.kiro/agents/lina.json.attribution.json +13 -0
- package/.kiro/agents/sparky-prompt.md +89 -72
- package/.kiro/agents/sparky-prompt.md.attribution.json +53 -0
- package/.kiro/agents/sparky.json +37 -37
- package/.kiro/agents/sparky.json.attribution.json +13 -0
- package/.kiro/agents/stacy-prompt.md +74 -48
- package/.kiro/agents/stacy-prompt.md.attribution.json +45 -0
- package/.kiro/agents/stacy.json +28 -30
- package/.kiro/agents/stacy.json.attribution.json +13 -0
- package/.kiro/agents/thurgood-prompt.md +94 -138
- package/.kiro/agents/thurgood-prompt.md.attribution.json +45 -0
- package/.kiro/agents/thurgood.json +31 -35
- package/.kiro/agents/thurgood.json.attribution.json +13 -0
- package/.kiro/steering/AI-Collaboration-Principles.md +3 -3
- package/.kiro/steering/Civitas-System-Overview.md +5 -5
- package/.kiro/steering/DesignerPunk-Systems-Overview.md +6 -6
- package/.kiro/steering/Task-Completion-Protocol.md +98 -17
- package/.kiro/steering/core-goals.md +3 -3
- package/.kiro/steering/personal-note.md +1 -1
- package/.kiro/steering/start-up-tasks.md +14 -3
- package/application-mcp-server/src/index.ts +26 -0
- package/dist/ComponentTokens.android.kt +1 -1
- package/dist/ComponentTokens.ios.swift +1 -1
- package/dist/ComponentTokens.web.css +1 -1
- package/dist/DesignTokens.android.kt +1 -1
- package/dist/DesignTokens.dtcg.json +8 -5
- package/dist/DesignTokens.figma.json +2 -2
- package/dist/DesignTokens.ios.swift +1 -1
- package/dist/DesignTokens.web.css +1 -1
- package/dist/android/DesignTokens.android.kt +1 -1
- package/dist/blend/OklchBlendCalculator.js +1 -0
- package/dist/blend/ThemeAwareBlendUtilities.web.d.ts +13 -2
- package/dist/blend/ThemeAwareBlendUtilities.web.js +6 -1
- package/dist/browser/designerpunk.esm.js +22 -81
- package/dist/browser/designerpunk.esm.min.js +29 -32
- package/dist/browser/designerpunk.umd.js +22 -81
- package/dist/browser/designerpunk.umd.min.js +42 -45
- package/dist/browser/tokens.css +1 -1
- package/dist/components/core/Avatar-Base/platforms/web/Avatar.web.js +24 -5
- package/dist/components/core/Button-CTA/examples/BasicUsage.d.ts +16 -28
- package/dist/components/core/Button-CTA/examples/BasicUsage.js +18 -43
- package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.d.ts +3 -15
- package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.js +9 -58
- package/dist/components/core/Button-CTA/types.d.ts +0 -24
- package/dist/components/core/Button-CTA/types.js +6 -0
- package/dist/components/core/Input-Text-Base/types.d.ts +13 -1
- package/dist/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.js +11 -2
- package/dist/generators/DTCGFormatGenerator.js +8 -0
- package/dist/integration/BuildErrorHandler.js +2 -2
- package/dist/ios/DesignTokens.ios.swift +1 -1
- package/dist/mcp/application-mcp.js +24 -0
- package/dist/mcp/docs-mcp.js +130 -15
- package/dist/mcp/product-mcp.js +25 -0
- package/dist/tokens/OpacityTokens.js +1 -1
- package/dist/tokens/semantic/BlendTokens.d.ts +10 -3
- package/dist/tokens/semantic/BlendTokens.js +17 -5
- package/dist/tokens/semantic/OpacityTokens.d.ts +4 -4
- package/dist/tokens/semantic/OpacityTokens.js +4 -4
- package/dist/types/ComponentTypes.d.ts +1 -1
- package/dist/types/generated/TokenTypes.d.ts +1 -1
- package/dist/types/generated/TokenTypes.js +1 -1
- package/dist/validators/StemmaTokenUsageValidator.js +3 -2
- package/dist/web/DesignTokens.web.css +1 -1
- package/governance/Component-Development-Guide.md +22 -12
- package/governance/Component-Development-Standards.md +2 -2
- package/governance/Component-Family-Avatar.md +0 -1
- package/governance/Component-Family-Badge.md +0 -1
- package/governance/Component-Family-Button.md +4 -17
- package/governance/Component-Family-Chip.md +0 -1
- package/governance/Component-Family-Container.md +0 -1
- package/governance/Component-Family-Data-Display.md +1 -2
- package/governance/Component-Family-Divider.md +1 -2
- package/governance/Component-Family-Form-Inputs.md +5 -5
- package/governance/Component-Family-Icon.md +1 -2
- package/governance/Component-Family-Loading.md +1 -2
- package/governance/Component-Family-Modal.md +1 -2
- package/governance/Component-Family-Navigation.md +0 -1
- package/governance/Component-Family-Progress.md +0 -1
- package/governance/Component-Inheritance-Structures.md +195 -76
- package/governance/Component-MCP-Document-Template.md +6 -5
- package/governance/Component-Primitive-vs-Semantic-Philosophy.md +1 -1
- package/governance/Component-Quick-Reference.md +33 -33
- package/governance/Component-Readiness-Status.md +54 -38
- package/governance/Component-Templates.md +32 -36
- package/governance/Contract-System-Reference.md +6 -6
- package/governance/MCP-Integration-Guide.md +1 -1
- package/governance/Process-Cross-Reference-Standards.md +31 -13
- package/governance/Process-Development-Workflow.md +49 -59
- package/governance/Process-File-Organization.md +24 -24
- package/governance/Process-Hook-Operations.md +19 -7
- package/governance/Process-Orchestration-Model-Selection.md +92 -0
- package/governance/Process-Spec-Planning.md +91 -39
- package/governance/Process-Task-Type-Definitions.md +80 -4
- package/governance/Product-Handoff-Protocol.md +2 -0
- package/governance/Rosetta-System-Architecture.md +6 -6
- package/governance/Test-Behavioral-Contract-Validation.md +38 -31
- package/governance/Test-Failure-Audit-Methodology.md +1 -1
- package/governance/Token-Family-Accessibility.md +1 -2
- package/governance/Token-Family-Blend.md +18 -16
- package/governance/Token-Family-Blur.md +0 -1
- package/governance/Token-Family-Border.md +1 -2
- package/governance/Token-Family-Color.md +0 -1
- package/governance/Token-Family-Glow.md +1 -2
- package/governance/Token-Family-Layering.md +0 -1
- package/governance/Token-Family-Motion.md +1 -2
- package/governance/Token-Family-Opacity.md +0 -1
- package/governance/Token-Family-Radius.md +1 -2
- package/governance/Token-Family-Responsive.md +1 -2
- package/governance/Token-Family-Shadow.md +1 -2
- package/governance/Token-Family-Sizing.md +0 -1
- package/governance/Token-Family-Spacing.md +1 -2
- package/governance/Token-Family-Typography.md +1 -2
- package/governance/Token-Governance.md +8 -8
- package/governance/Token-Quick-Reference.md +21 -21
- package/governance/Token-Resolution-Patterns.md +1 -1
- package/governance/Token-Semantic-Structure.md +1 -1
- package/governance/Web-Authoring-Standards.md +5 -5
- package/governance/browser-distribution-guide.md +1 -4
- package/governance/classification-map.md +368 -0
- package/governance/completion-documentation-guide.md +11 -8
- package/governance/component-meta-authoring-guide.md +1 -1
- package/governance/cross-platform-vs-platform-specific-decision-framework.md +1 -1
- package/governance/platform-implementation-guidelines.md +1 -1
- package/governance/release-management-system.md +2 -2
- package/governance/rosetta-system-principles.md +8 -6
- package/governance/stemma-system-principles.md +18 -17
- package/mcp-server/src/index.ts +24 -6
- package/mcp-server/src/indexer/DocumentIndexer.ts +119 -9
- package/mcp-server/src/indexer/__tests__/bare-id-crossrefs.test.ts +250 -0
- package/mcp-server/src/indexer/cross-ref-parser.ts +29 -1
- package/mcp-server/src/indexer/index-health.ts +27 -2
- package/mcp-server/src/query/__tests__/find-docs-calibration.test.ts +11 -26
- package/mcp-server/src/relocation-integrity-gate/__tests__/relocation-integrity-gate.test.ts +72 -5
- package/mcp-server/src/relocation-integrity-gate/relocation-integrity-gate.ts +81 -24
- package/mcp-server/src/tools/list-cross-references.ts +2 -2
- package/package.json +23 -21
- package/src/__tests__/browser-distribution/css-bundling.test.ts +6 -4
- package/src/__tests__/console-allowlist.json +14 -0
- package/src/__tests__/console-fail-setup.ts +169 -0
- package/src/__tests__/integration/Spec107-DesignLanguageContext.test.ts +16 -0
- package/src/__tests__/stemma-system/behavioral-contract-validation.test.ts +70 -17
- package/src/__tests__/stemma-system/contract-catalog-name-validation.test.ts +28 -0
- package/src/__tests__/stemma-system/form-inputs-contracts.test.ts +223 -16
- package/src/__tests__/stemma-system/input-text-native-base-call-alignment.test.ts +298 -0
- package/src/blend/OklchBlendCalculator.ts +3 -0
- package/src/blend/ThemeAwareBlendUtilities.android.kt +3 -0
- package/src/blend/ThemeAwareBlendUtilities.ios.swift +3 -0
- package/src/blend/ThemeAwareBlendUtilities.web.ts +9 -1
- package/src/blend/__tests__/InteractionStateAudit.test.ts +12 -9
- package/src/build/errors/__tests__/ErrorHandler.integration.test.ts +8 -0
- package/src/build/errors/__tests__/ErrorHandler.test.ts +5 -0
- package/src/build/workflow/__tests__/CICDIntegration.test.ts +12 -1
- package/src/cli/__tests__/init.test.ts +45 -11
- package/src/components/core/Avatar-Base/Avatar-Base.schema.yaml +1 -1
- package/src/components/core/Avatar-Base/__tests__/Avatar.accessibility.test.ts +121 -7
- package/src/components/core/Avatar-Base/__tests__/Avatar.image.test.ts +3 -0
- package/src/components/core/Avatar-Base/__tests__/Avatar.test.ts +15 -6
- package/src/components/core/Avatar-Base/contracts.yaml +11 -1
- package/src/components/core/Avatar-Base/platforms/web/Avatar.web.ts +24 -5
- package/src/components/core/Badge-Count-Base/contracts.yaml +1 -1
- package/src/components/core/Badge-Label-Base/contracts.yaml +1 -1
- package/src/components/core/Button-CTA/Button-CTA.schema.yaml +2 -12
- package/src/components/core/Button-CTA/README.md +3 -6
- package/src/components/core/Button-CTA/__tests__/ButtonCTA.test.ts +35 -89
- package/src/components/core/Button-CTA/__tests__/setup.test.ts +0 -2
- package/src/components/core/Button-CTA/__tests__/test-utils.ts +0 -2
- package/src/components/core/Button-CTA/contracts.yaml +6 -29
- package/src/components/core/Button-CTA/examples/BasicUsage.html +2 -14
- package/src/components/core/Button-CTA/examples/BasicUsage.tsx +17 -44
- package/src/components/core/Button-CTA/platforms/android/ButtonCTA.android.kt +12 -20
- package/src/components/core/Button-CTA/platforms/ios/ButtonCTA.ios.swift +12 -51
- package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.css +2 -26
- package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.ts +18 -71
- package/src/components/core/Button-CTA/types.ts +10 -28
- package/src/components/core/Chip-Base/__tests__/ChipBase.test.ts +13 -0
- package/src/components/core/Chip-Filter/__tests__/ChipFilter.test.ts +13 -0
- package/src/components/core/Chip-Input/__tests__/ChipInput.test.ts +13 -0
- package/src/components/core/Input-Text-Base/Input-Text-Base.schema.yaml +30 -2
- package/src/components/core/Input-Text-Base/README.md +25 -2
- package/src/components/core/Input-Text-Base/__tests__/focusIndicators.test.ts +16 -15
- package/src/components/core/Input-Text-Base/contracts.yaml +90 -0
- package/src/components/core/Input-Text-Base/platforms/android/InputTextBase.android.kt +26 -12
- package/src/components/core/Input-Text-Base/platforms/ios/InputTextBase.ios.swift +195 -59
- package/src/components/core/Input-Text-Base/types.ts +13 -1
- package/src/components/core/Input-Text-Email/Input-Text-Email.schema.yaml +5 -1
- package/src/components/core/Input-Text-Email/README.md +8 -7
- package/src/components/core/Input-Text-Email/platforms/android/InputTextEmail.android.kt +1 -4
- package/src/components/core/Input-Text-Email/platforms/ios/InputTextEmail.ios.swift +2 -16
- package/src/components/core/Input-Text-Password/Input-Text-Password.schema.yaml +10 -3
- package/src/components/core/Input-Text-Password/README.md +9 -8
- package/src/components/core/Input-Text-Password/contracts.yaml +5 -0
- package/src/components/core/Input-Text-Password/platforms/android/InputTextPassword.android.kt +17 -7
- package/src/components/core/Input-Text-Password/platforms/ios/InputTextPassword.ios.swift +22 -20
- package/src/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.ts +11 -2
- package/src/components/core/Input-Text-PhoneNumber/Input-Text-PhoneNumber.schema.yaml +5 -1
- package/src/components/core/Input-Text-PhoneNumber/README.md +9 -8
- package/src/components/core/Input-Text-PhoneNumber/platforms/android/InputTextPhoneNumber.android.kt +2 -5
- package/src/components/core/Input-Text-PhoneNumber/platforms/ios/InputTextPhoneNumber.ios.swift +3 -17
- package/src/components/core/Nav-Header-App/contracts.yaml +1 -1
- package/src/components/core/Nav-SegmentedChoice-Base/contracts.yaml +1 -1
- package/src/components/core/Progress-Indicator-Connector-Base/contracts.yaml +1 -1
- package/src/components/core/Progress-Indicator-Label-Base/contracts.yaml +1 -1
- package/src/components/core/Progress-Indicator-Node-Base/contracts.yaml +1 -1
- package/src/components/core/Progress-Stepper-Base/__tests__/StepperBase.test.ts +5 -2
- package/src/components/core/Progress-Stepper-Detailed/__tests__/StepperDetailed.test.ts +5 -2
- package/src/generators/DTCGFormatGenerator.ts +6 -0
- package/src/generators/__tests__/DTCGConfigOptions.test.ts +14 -5
- package/src/integration/BuildErrorHandler.ts +2 -2
- package/src/tokens/OpacityTokens.ts +1 -1
- package/src/tokens/__tests__/OpacityTokens.test.ts +3 -1
- package/src/tokens/semantic/BlendTokens.ts +26 -5
- package/src/tokens/semantic/OpacityTokens.ts +4 -4
- package/src/tools/release/__tests__/ReleasePipeline.test.ts +1 -1
- package/src/types/ComponentTypes.ts +1 -1
- package/src/types/generated/TokenTypes.ts +1 -1
- package/src/validators/StemmaTokenUsageValidator.ts +3 -2
- package/token-index/semantics.yaml +1 -2
package/dist/browser/tokens.css
CHANGED
|
@@ -643,11 +643,30 @@ class AvatarBaseElement extends HTMLElement {
|
|
|
643
643
|
// Generate aria-hidden attribute for decorative avatars
|
|
644
644
|
// @see Requirements: 9.2 - Apply aria-hidden="true" when decorative prop is true
|
|
645
645
|
const ariaHiddenAttr = decorative ? ' aria-hidden="true"' : '';
|
|
646
|
-
// Warn in development if
|
|
647
|
-
// @see Requirements: 5.4 -
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
646
|
+
// Warn in development if a human-type avatar is missing alt text for its image.
|
|
647
|
+
// @see Requirements: 5.4 - Human type + src SHALL require alt for accessibility
|
|
648
|
+
// @see Requirements: 5 AC 5 - Agent type SHALL ignore src entirely (src not
|
|
649
|
+
// rendered as an image), so agent-type avatars never warn regardless of alt.
|
|
650
|
+
//
|
|
651
|
+
// Settled edge semantics (Spec 126, O2, ratified 2026-07-09):
|
|
652
|
+
// - Scope is human-type only — Req 5.4 is human-type-scoped, and Req 5 AC 5
|
|
653
|
+
// affirmatively establishes that agent-type SHALL ignore src, so a src+no-alt
|
|
654
|
+
// agent avatar is not a violation of anything.
|
|
655
|
+
// - `alt == null` (loose equality — also excludes `undefined`), not `!alt`, is the
|
|
656
|
+
// test. The `alt` attribute getter returns `getAttribute('alt')`. Raw
|
|
657
|
+
// `setAttribute('alt', '')` yields `alt === ''`, which is the HTML-idiomatic
|
|
658
|
+
// explicit-empty-alt signal and must NOT warn. The `alt` *property setter*
|
|
659
|
+
// (see below) treats a falsy value as "remove the attribute," so
|
|
660
|
+
// `avatar.alt = ''` collapses to `alt === null` — indistinguishable from
|
|
661
|
+
// omitting alt entirely, and DOES warn under this condition.
|
|
662
|
+
// - `!decorative` is the operative fix for the confirmed false positive: a
|
|
663
|
+
// `decorative` avatar is the component's official signal that the image is
|
|
664
|
+
// non-informative (Req 9.2 applies `aria-hidden="true"`), so it must never warn
|
|
665
|
+
// regardless of alt.
|
|
666
|
+
if (type === 'human' && src && alt == null && !decorative && typeof console !== 'undefined') {
|
|
667
|
+
console.warn('AvatarBaseElement: "alt" is required when "src" is provided. ' +
|
|
668
|
+
'Add an alt description of the image; or, if this avatar is purely decorative ' +
|
|
669
|
+
'(non-informative), set the "decorative" prop to hide it from screen readers.');
|
|
651
670
|
}
|
|
652
671
|
// Render different structures based on type
|
|
653
672
|
// Agent type uses SVG-based hexagon with Bézier curves for true rounded corners
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
* - size: 'medium' (48px height)
|
|
20
20
|
* - variant: 'primary' (filled background with primary color)
|
|
21
21
|
* - noWrap: false (text wraps if needed)
|
|
22
|
-
* - disabled: false (interactive)
|
|
23
22
|
*
|
|
24
23
|
* @example
|
|
25
24
|
* ```html
|
|
@@ -54,7 +53,6 @@ export declare function customLabelButton(): void;
|
|
|
54
53
|
*
|
|
55
54
|
* The 'press' event:
|
|
56
55
|
* - Bubbles up through the DOM
|
|
57
|
-
* - Is not called when button is disabled
|
|
58
56
|
* - Works with click, tap, Enter key, and Space key
|
|
59
57
|
* - Provides originalEvent in event.detail for advanced use cases
|
|
60
58
|
*
|
|
@@ -67,39 +65,29 @@ export declare function customLabelButton(): void;
|
|
|
67
65
|
*/
|
|
68
66
|
export declare function buttonWithHandler(): void;
|
|
69
67
|
/**
|
|
70
|
-
* Example 4:
|
|
68
|
+
* Example 4: Unavailable Actions (no disabled state)
|
|
71
69
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
70
|
+
* DesignerPunk does not support disabled states for usability and
|
|
71
|
+
* accessibility reasons. If an action is unavailable, the component
|
|
72
|
+
* should not be rendered.
|
|
75
73
|
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* - Screen readers announce disabled state
|
|
81
|
-
* - onPress handler is not called
|
|
82
|
-
*
|
|
83
|
-
* Common use cases:
|
|
84
|
-
* - Form submission in progress
|
|
85
|
-
* - Required fields not filled
|
|
86
|
-
* - User lacks permissions
|
|
87
|
-
* - Action temporarily unavailable
|
|
88
|
-
*
|
|
89
|
-
* @example
|
|
90
|
-
* ```html
|
|
91
|
-
* <button-cta label="Submit" disabled></button-cta>
|
|
92
|
-
* ```
|
|
74
|
+
* For in-flight async operations (e.g. form submission), use the loading
|
|
75
|
+
* state instead of disabling the button. For actions the user cannot take
|
|
76
|
+
* yet, keep the button interactive and validate on press, or do not render
|
|
77
|
+
* the button at all.
|
|
93
78
|
*
|
|
94
79
|
* @example
|
|
95
80
|
* ```typescript
|
|
96
|
-
* //
|
|
97
|
-
*
|
|
98
|
-
* button
|
|
99
|
-
*
|
|
81
|
+
* // Conditionally render instead of disabling
|
|
82
|
+
* if (userCanSubmit) {
|
|
83
|
+
* const button = document.createElement('button-cta') as ButtonCTA;
|
|
84
|
+
* button.label = 'Submit';
|
|
85
|
+
* button.addEventListener('press', handleSubmit);
|
|
86
|
+
* document.body.appendChild(button);
|
|
87
|
+
* }
|
|
100
88
|
* ```
|
|
101
89
|
*/
|
|
102
|
-
export declare function
|
|
90
|
+
export declare function conditionallyRenderedButton(): void;
|
|
103
91
|
/**
|
|
104
92
|
* Example 5: All Examples Together
|
|
105
93
|
*
|
|
@@ -14,7 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
exports.defaultButton = defaultButton;
|
|
15
15
|
exports.customLabelButton = customLabelButton;
|
|
16
16
|
exports.buttonWithHandler = buttonWithHandler;
|
|
17
|
-
exports.
|
|
17
|
+
exports.conditionallyRenderedButton = conditionallyRenderedButton;
|
|
18
18
|
exports.renderAllBasicExamples = renderAllBasicExamples;
|
|
19
19
|
/**
|
|
20
20
|
* Example 1: Default Button (Medium, Primary)
|
|
@@ -26,7 +26,6 @@ exports.renderAllBasicExamples = renderAllBasicExamples;
|
|
|
26
26
|
* - size: 'medium' (48px height)
|
|
27
27
|
* - variant: 'primary' (filled background with primary color)
|
|
28
28
|
* - noWrap: false (text wraps if needed)
|
|
29
|
-
* - disabled: false (interactive)
|
|
30
29
|
*
|
|
31
30
|
* @example
|
|
32
31
|
* ```html
|
|
@@ -77,7 +76,6 @@ function customLabelButton() {
|
|
|
77
76
|
*
|
|
78
77
|
* The 'press' event:
|
|
79
78
|
* - Bubbles up through the DOM
|
|
80
|
-
* - Is not called when button is disabled
|
|
81
79
|
* - Works with click, tap, Enter key, and Space key
|
|
82
80
|
* - Provides originalEvent in event.detail for advanced use cases
|
|
83
81
|
*
|
|
@@ -105,52 +103,35 @@ function buttonWithHandler() {
|
|
|
105
103
|
document.body.appendChild(button);
|
|
106
104
|
}
|
|
107
105
|
/**
|
|
108
|
-
* Example 4:
|
|
106
|
+
* Example 4: Unavailable Actions (no disabled state)
|
|
109
107
|
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
108
|
+
* DesignerPunk does not support disabled states for usability and
|
|
109
|
+
* accessibility reasons. If an action is unavailable, the component
|
|
110
|
+
* should not be rendered.
|
|
113
111
|
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* - Screen readers announce disabled state
|
|
119
|
-
* - onPress handler is not called
|
|
120
|
-
*
|
|
121
|
-
* Common use cases:
|
|
122
|
-
* - Form submission in progress
|
|
123
|
-
* - Required fields not filled
|
|
124
|
-
* - User lacks permissions
|
|
125
|
-
* - Action temporarily unavailable
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* ```html
|
|
129
|
-
* <button-cta label="Submit" disabled></button-cta>
|
|
130
|
-
* ```
|
|
112
|
+
* For in-flight async operations (e.g. form submission), use the loading
|
|
113
|
+
* state instead of disabling the button. For actions the user cannot take
|
|
114
|
+
* yet, keep the button interactive and validate on press, or do not render
|
|
115
|
+
* the button at all.
|
|
131
116
|
*
|
|
132
117
|
* @example
|
|
133
118
|
* ```typescript
|
|
134
|
-
* //
|
|
135
|
-
*
|
|
136
|
-
* button
|
|
137
|
-
*
|
|
119
|
+
* // Conditionally render instead of disabling
|
|
120
|
+
* if (userCanSubmit) {
|
|
121
|
+
* const button = document.createElement('button-cta') as ButtonCTA;
|
|
122
|
+
* button.label = 'Submit';
|
|
123
|
+
* button.addEventListener('press', handleSubmit);
|
|
124
|
+
* document.body.appendChild(button);
|
|
125
|
+
* }
|
|
138
126
|
* ```
|
|
139
127
|
*/
|
|
140
|
-
function
|
|
128
|
+
function conditionallyRenderedButton() {
|
|
141
129
|
const button = document.createElement('button-cta');
|
|
142
130
|
button.label = 'Submit';
|
|
143
|
-
button.disabled = true; // Button is non-interactive
|
|
144
|
-
// This handler will NOT be called when button is disabled
|
|
145
131
|
button.addEventListener('press', () => {
|
|
146
|
-
console.log('
|
|
132
|
+
console.log('Submitted');
|
|
147
133
|
});
|
|
148
134
|
document.body.appendChild(button);
|
|
149
|
-
// Example: Enable button after 3 seconds (simulating async operation)
|
|
150
|
-
setTimeout(() => {
|
|
151
|
-
button.disabled = false;
|
|
152
|
-
console.log('Button is now enabled');
|
|
153
|
-
}, 3000);
|
|
154
135
|
}
|
|
155
136
|
/**
|
|
156
137
|
* Example 5: All Examples Together
|
|
@@ -188,12 +169,6 @@ function renderAllBasicExamples() {
|
|
|
188
169
|
alert('Form submitted successfully!');
|
|
189
170
|
});
|
|
190
171
|
container.appendChild(handlerBtn);
|
|
191
|
-
// Example 4: Disabled
|
|
192
|
-
const disabledBtn = document.createElement('button-cta');
|
|
193
|
-
disabledBtn.label = 'Disabled Button';
|
|
194
|
-
disabledBtn.disabled = true;
|
|
195
|
-
disabledBtn.addEventListener('press', () => console.log('This will not log'));
|
|
196
|
-
container.appendChild(disabledBtn);
|
|
197
172
|
// Add container to document
|
|
198
173
|
document.body.appendChild(container);
|
|
199
174
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* composition pattern as iOS and Android platforms. This ensures cross-platform
|
|
13
13
|
* consistency and single source of truth for icon rendering.
|
|
14
14
|
*
|
|
15
|
-
* Uses theme-aware blend utilities for state colors (hover, pressed,
|
|
15
|
+
* Uses theme-aware blend utilities for state colors (hover, pressed, icon)
|
|
16
16
|
* instead of opacity or filter workarounds. This ensures cross-platform consistency
|
|
17
17
|
* with iOS and Android implementations.
|
|
18
18
|
*
|
|
@@ -32,13 +32,12 @@ import '../../../Icon-Base/platforms/web/IconBase.web';
|
|
|
32
32
|
* - Semantic `<button>` element with proper accessibility
|
|
33
33
|
* - Token-based styling via CSS custom properties
|
|
34
34
|
* - Supports text wrapping by default (accessibility-first)
|
|
35
|
-
* - Uses blend utilities for state colors (hover, pressed,
|
|
35
|
+
* - Uses blend utilities for state colors (hover, pressed, icon)
|
|
36
36
|
* - WCAG 2.1 AA compliant:
|
|
37
37
|
* - Keyboard navigation (Tab, Enter, Space)
|
|
38
38
|
* - Focus indicators with 3:1 contrast ratio
|
|
39
39
|
* - Color contrast 4.5:1 for all styles
|
|
40
40
|
* - Screen reader support with ARIA attributes
|
|
41
|
-
* - Proper disabled state handling
|
|
42
41
|
*
|
|
43
42
|
* @example
|
|
44
43
|
* ```html
|
|
@@ -52,7 +51,6 @@ import '../../../Icon-Base/platforms/web/IconBase.web';
|
|
|
52
51
|
* variant="primary"
|
|
53
52
|
* icon="arrow-right"
|
|
54
53
|
* no-wrap="false"
|
|
55
|
-
* disabled="false"
|
|
56
54
|
* test-id="submit-button"
|
|
57
55
|
* ></button-cta>
|
|
58
56
|
* ```
|
|
@@ -77,7 +75,6 @@ export declare class ButtonCTA extends HTMLElement {
|
|
|
77
75
|
private _blendUtils;
|
|
78
76
|
private _hoverColor;
|
|
79
77
|
private _pressedColor;
|
|
80
|
-
private _disabledColor;
|
|
81
78
|
private _iconColor;
|
|
82
79
|
private _iconOpticalBalanceColor;
|
|
83
80
|
/**
|
|
@@ -108,7 +105,7 @@ export declare class ButtonCTA extends HTMLElement {
|
|
|
108
105
|
* Calculate blend colors from CSS custom properties.
|
|
109
106
|
*
|
|
110
107
|
* Reads base colors from CSS custom properties and applies theme-aware blend
|
|
111
|
-
* utilities to generate state colors (hover, pressed,
|
|
108
|
+
* utilities to generate state colors (hover, pressed, icon).
|
|
112
109
|
*
|
|
113
110
|
* Uses getBlendUtilities() factory functions instead of direct blend calculations
|
|
114
111
|
* for cross-platform consistency with iOS and Android implementations.
|
|
@@ -116,7 +113,6 @@ export declare class ButtonCTA extends HTMLElement {
|
|
|
116
113
|
* State color mappings:
|
|
117
114
|
* - Hover: darkerBlend(color.action.primary, blend.hoverDarker) - 8% darker
|
|
118
115
|
* - Pressed: darkerBlend(color.action.primary, blend.pressedDarker) - 12% darker
|
|
119
|
-
* - Disabled: desaturate(color.action.primary, blend.disabledDesaturate) - 12% less saturated
|
|
120
116
|
* - Icon: lighterBlend(color.contrast.onAction, blend.iconLighter) - 8% lighter
|
|
121
117
|
*
|
|
122
118
|
* @see Requirements: 7.1, 7.2, 7.3, 7.4 - Button-CTA state colors
|
|
@@ -180,14 +176,6 @@ export declare class ButtonCTA extends HTMLElement {
|
|
|
180
176
|
* Set the no-wrap state.
|
|
181
177
|
*/
|
|
182
178
|
set noWrap(value: boolean);
|
|
183
|
-
/**
|
|
184
|
-
* Get the disabled state.
|
|
185
|
-
*/
|
|
186
|
-
get disabled(): boolean;
|
|
187
|
-
/**
|
|
188
|
-
* Set the disabled state.
|
|
189
|
-
*/
|
|
190
|
-
set disabled(value: boolean);
|
|
191
179
|
/**
|
|
192
180
|
* Get the test ID.
|
|
193
181
|
*/
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* composition pattern as iOS and Android platforms. This ensures cross-platform
|
|
14
14
|
* consistency and single source of truth for icon rendering.
|
|
15
15
|
*
|
|
16
|
-
* Uses theme-aware blend utilities for state colors (hover, pressed,
|
|
16
|
+
* Uses theme-aware blend utilities for state colors (hover, pressed, icon)
|
|
17
17
|
* instead of opacity or filter workarounds. This ensures cross-platform consistency
|
|
18
18
|
* with iOS and Android implementations.
|
|
19
19
|
*
|
|
@@ -83,13 +83,12 @@ function getIconSizeForButton(buttonSize) {
|
|
|
83
83
|
* - Semantic `<button>` element with proper accessibility
|
|
84
84
|
* - Token-based styling via CSS custom properties
|
|
85
85
|
* - Supports text wrapping by default (accessibility-first)
|
|
86
|
-
* - Uses blend utilities for state colors (hover, pressed,
|
|
86
|
+
* - Uses blend utilities for state colors (hover, pressed, icon)
|
|
87
87
|
* - WCAG 2.1 AA compliant:
|
|
88
88
|
* - Keyboard navigation (Tab, Enter, Space)
|
|
89
89
|
* - Focus indicators with 3:1 contrast ratio
|
|
90
90
|
* - Color contrast 4.5:1 for all styles
|
|
91
91
|
* - Screen reader support with ARIA attributes
|
|
92
|
-
* - Proper disabled state handling
|
|
93
92
|
*
|
|
94
93
|
* @example
|
|
95
94
|
* ```html
|
|
@@ -103,7 +102,6 @@ function getIconSizeForButton(buttonSize) {
|
|
|
103
102
|
* variant="primary"
|
|
104
103
|
* icon="arrow-right"
|
|
105
104
|
* no-wrap="false"
|
|
106
|
-
* disabled="false"
|
|
107
105
|
* test-id="submit-button"
|
|
108
106
|
* ></button-cta>
|
|
109
107
|
* ```
|
|
@@ -125,7 +123,7 @@ class ButtonCTA extends HTMLElement {
|
|
|
125
123
|
* When these attributes change, attributeChangedCallback is invoked.
|
|
126
124
|
*/
|
|
127
125
|
static get observedAttributes() {
|
|
128
|
-
return ['label', 'size', 'variant', 'icon', 'no-wrap', '
|
|
126
|
+
return ['label', 'size', 'variant', 'icon', 'no-wrap', 'test-id'];
|
|
129
127
|
}
|
|
130
128
|
constructor() {
|
|
131
129
|
super();
|
|
@@ -141,7 +139,6 @@ class ButtonCTA extends HTMLElement {
|
|
|
141
139
|
// Cached blend colors for state styling
|
|
142
140
|
this._hoverColor = '';
|
|
143
141
|
this._pressedColor = '';
|
|
144
|
-
this._disabledColor = '';
|
|
145
142
|
this._iconColor = '';
|
|
146
143
|
this._iconOpticalBalanceColor = '';
|
|
147
144
|
/**
|
|
@@ -150,12 +147,6 @@ class ButtonCTA extends HTMLElement {
|
|
|
150
147
|
* Dispatches a custom 'press' event that bubbles up to parent elements.
|
|
151
148
|
*/
|
|
152
149
|
this._handleClick = (event) => {
|
|
153
|
-
// Don't dispatch if disabled
|
|
154
|
-
if (this.disabled) {
|
|
155
|
-
event.preventDefault();
|
|
156
|
-
event.stopPropagation();
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
150
|
// Dispatch custom 'press' event
|
|
160
151
|
this.dispatchEvent(new CustomEvent('press', {
|
|
161
152
|
bubbles: true,
|
|
@@ -173,10 +164,6 @@ class ButtonCTA extends HTMLElement {
|
|
|
173
164
|
* @param event - The keyboard event
|
|
174
165
|
*/
|
|
175
166
|
this._handleKeyDown = (event) => {
|
|
176
|
-
// Don't handle if disabled
|
|
177
|
-
if (this.disabled) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
167
|
// Handle Enter and Space keys (WCAG 2.1 AA keyboard navigation)
|
|
181
168
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
182
169
|
event.preventDefault(); // Prevent default space scrolling
|
|
@@ -247,7 +234,7 @@ class ButtonCTA extends HTMLElement {
|
|
|
247
234
|
* Calculate blend colors from CSS custom properties.
|
|
248
235
|
*
|
|
249
236
|
* Reads base colors from CSS custom properties and applies theme-aware blend
|
|
250
|
-
* utilities to generate state colors (hover, pressed,
|
|
237
|
+
* utilities to generate state colors (hover, pressed, icon).
|
|
251
238
|
*
|
|
252
239
|
* Uses getBlendUtilities() factory functions instead of direct blend calculations
|
|
253
240
|
* for cross-platform consistency with iOS and Android implementations.
|
|
@@ -255,7 +242,6 @@ class ButtonCTA extends HTMLElement {
|
|
|
255
242
|
* State color mappings:
|
|
256
243
|
* - Hover: darkerBlend(color.action.primary, blend.hoverDarker) - 8% darker
|
|
257
244
|
* - Pressed: darkerBlend(color.action.primary, blend.pressedDarker) - 12% darker
|
|
258
|
-
* - Disabled: desaturate(color.action.primary, blend.disabledDesaturate) - 12% less saturated
|
|
259
245
|
* - Icon: lighterBlend(color.contrast.onAction, blend.iconLighter) - 8% lighter
|
|
260
246
|
*
|
|
261
247
|
* @see Requirements: 7.1, 7.2, 7.3, 7.4 - Button-CTA state colors
|
|
@@ -282,8 +268,6 @@ class ButtonCTA extends HTMLElement {
|
|
|
282
268
|
this._hoverColor = this._blendUtils.hoverColor(primaryColor);
|
|
283
269
|
// @see Requirements: 7.2 - Pressed uses darkerBlend(color.action.primary, blend.pressedDarker)
|
|
284
270
|
this._pressedColor = this._blendUtils.pressedColor(primaryColor);
|
|
285
|
-
// @see Requirements: 7.3 - Disabled uses desaturate(color.action.primary, blend.disabledDesaturate)
|
|
286
|
-
this._disabledColor = this._blendUtils.disabledColor(primaryColor);
|
|
287
271
|
// @see Requirements: 7.4 - Icon uses lighterBlend(color.contrast.onAction, blend.iconLighter)
|
|
288
272
|
// Icon for primary buttons: provides optical balance for icons on primary background
|
|
289
273
|
this._iconColor = this._blendUtils.iconColor(onActionColor);
|
|
@@ -380,23 +364,6 @@ class ButtonCTA extends HTMLElement {
|
|
|
380
364
|
set noWrap(value) {
|
|
381
365
|
this.setAttribute('no-wrap', value.toString());
|
|
382
366
|
}
|
|
383
|
-
/**
|
|
384
|
-
* Get the disabled state.
|
|
385
|
-
*/
|
|
386
|
-
get disabled() {
|
|
387
|
-
return this.hasAttribute('disabled');
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* Set the disabled state.
|
|
391
|
-
*/
|
|
392
|
-
set disabled(value) {
|
|
393
|
-
if (value) {
|
|
394
|
-
this.setAttribute('disabled', '');
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
this.removeAttribute('disabled');
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
367
|
/**
|
|
401
368
|
* Get the test ID.
|
|
402
369
|
*/
|
|
@@ -457,15 +424,13 @@ class ButtonCTA extends HTMLElement {
|
|
|
457
424
|
const variant = this.buttonVariant;
|
|
458
425
|
const icon = this.icon;
|
|
459
426
|
const noWrap = this.noWrap;
|
|
460
|
-
const disabled = this.disabled;
|
|
461
427
|
const testID = this.testID;
|
|
462
428
|
// Generate class names
|
|
463
429
|
const buttonClasses = [
|
|
464
430
|
'button-cta',
|
|
465
431
|
`button-cta--${size}`,
|
|
466
|
-
`button-cta--${variant}
|
|
467
|
-
|
|
468
|
-
].filter(Boolean).join(' ');
|
|
432
|
+
`button-cta--${variant}`
|
|
433
|
+
].join(' ');
|
|
469
434
|
// Get icon size for button size variant
|
|
470
435
|
// Icon sizes are type-safe mapped from button size:
|
|
471
436
|
// - Small/Medium: 24px (iconBaseSize100)
|
|
@@ -481,7 +446,6 @@ class ButtonCTA extends HTMLElement {
|
|
|
481
446
|
const blendColorStyles = `
|
|
482
447
|
--_cta-hover-bg: ${this._hoverColor};
|
|
483
448
|
--_cta-pressed-bg: ${this._pressedColor};
|
|
484
|
-
--_cta-disabled-bg: ${this._disabledColor};
|
|
485
449
|
--_cta-icon-color: ${this._iconColor};
|
|
486
450
|
--_cta-icon-optical: ${this._iconOpticalBalanceColor};
|
|
487
451
|
`;
|
|
@@ -491,11 +455,10 @@ class ButtonCTA extends HTMLElement {
|
|
|
491
455
|
// @see Requirements: 8.2, 8.3 (components render correctly with interactivity)
|
|
492
456
|
this._shadowRoot.innerHTML = `
|
|
493
457
|
<style>${ButtonCTA_web_css_1.default}</style>
|
|
494
|
-
<button
|
|
458
|
+
<button
|
|
495
459
|
class="${buttonClasses}"
|
|
496
460
|
type="button"
|
|
497
461
|
role="button"
|
|
498
|
-
${disabled ? 'disabled aria-disabled="true"' : 'aria-disabled="false"'}
|
|
499
462
|
${testIDAttr}
|
|
500
463
|
aria-label="${label}"
|
|
501
464
|
style="${blendColorStyles}"
|
|
@@ -534,7 +497,6 @@ class ButtonCTA extends HTMLElement {
|
|
|
534
497
|
const variant = this.buttonVariant;
|
|
535
498
|
const icon = this.icon;
|
|
536
499
|
const noWrap = this.noWrap;
|
|
537
|
-
const disabled = this.disabled;
|
|
538
500
|
const testID = this.testID;
|
|
539
501
|
// Get icon size for button size variant
|
|
540
502
|
const iconSize = getIconSizeForButton(size);
|
|
@@ -545,19 +507,9 @@ class ButtonCTA extends HTMLElement {
|
|
|
545
507
|
const buttonClasses = [
|
|
546
508
|
'button-cta',
|
|
547
509
|
`button-cta--${size}`,
|
|
548
|
-
`button-cta--${variant}
|
|
549
|
-
|
|
550
|
-
].filter(Boolean).join(' ');
|
|
510
|
+
`button-cta--${variant}`
|
|
511
|
+
].join(' ');
|
|
551
512
|
this._button.className = buttonClasses;
|
|
552
|
-
// Update disabled state
|
|
553
|
-
if (disabled) {
|
|
554
|
-
this._button.setAttribute('disabled', '');
|
|
555
|
-
this._button.setAttribute('aria-disabled', 'true');
|
|
556
|
-
}
|
|
557
|
-
else {
|
|
558
|
-
this._button.removeAttribute('disabled');
|
|
559
|
-
this._button.setAttribute('aria-disabled', 'false');
|
|
560
|
-
}
|
|
561
513
|
// Update aria-label
|
|
562
514
|
this._button.setAttribute('aria-label', label);
|
|
563
515
|
// Update test ID
|
|
@@ -570,7 +522,6 @@ class ButtonCTA extends HTMLElement {
|
|
|
570
522
|
// Update blend color CSS custom properties
|
|
571
523
|
this._button.style.setProperty('--_cta-hover-bg', this._hoverColor);
|
|
572
524
|
this._button.style.setProperty('--_cta-pressed-bg', this._pressedColor);
|
|
573
|
-
this._button.style.setProperty('--_cta-disabled-bg', this._disabledColor);
|
|
574
525
|
this._button.style.setProperty('--_cta-icon-color', this._iconColor);
|
|
575
526
|
this._button.style.setProperty('--_cta-icon-optical', this._iconOpticalBalanceColor);
|
|
576
527
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -78,7 +78,6 @@ export type ButtonStyle = 'primary' | 'secondary' | 'tertiary';
|
|
|
78
78
|
* variant="primary"
|
|
79
79
|
* icon="arrow-right"
|
|
80
80
|
* noWrap={false}
|
|
81
|
-
* disabled={false}
|
|
82
81
|
* testID="submit-button"
|
|
83
82
|
* onPress={handleSubmit}
|
|
84
83
|
* />
|
|
@@ -190,11 +189,9 @@ export interface ButtonProps {
|
|
|
190
189
|
* Click/tap handler (required)
|
|
191
190
|
*
|
|
192
191
|
* Callback function invoked when the button is clicked or tapped.
|
|
193
|
-
* Not called when button is disabled.
|
|
194
192
|
*
|
|
195
193
|
* @remarks
|
|
196
194
|
* - Function signature: `() => void`
|
|
197
|
-
* - Not invoked when `disabled` is true
|
|
198
195
|
* - Triggered by click, tap, Enter key, or Space key
|
|
199
196
|
*
|
|
200
197
|
* @example
|
|
@@ -222,26 +219,5 @@ export interface ButtonProps {
|
|
|
222
219
|
* ```
|
|
223
220
|
*/
|
|
224
221
|
testID?: string;
|
|
225
|
-
/**
|
|
226
|
-
* Optional disabled state (default: false)
|
|
227
|
-
*
|
|
228
|
-
* When true, the button is non-interactive and visually indicates
|
|
229
|
-
* disabled state. The onPress handler is not called when disabled.
|
|
230
|
-
*
|
|
231
|
-
* @defaultValue false
|
|
232
|
-
*
|
|
233
|
-
* @remarks
|
|
234
|
-
* - Disabled buttons are not keyboard focusable
|
|
235
|
-
* - Screen readers announce disabled state
|
|
236
|
-
* - Visual styling indicates non-interactive state
|
|
237
|
-
*
|
|
238
|
-
* @example
|
|
239
|
-
* ```typescript
|
|
240
|
-
* disabled={false} // Interactive (default)
|
|
241
|
-
* disabled={true} // Non-interactive
|
|
242
|
-
* disabled={isSubmitting} // Conditional disable
|
|
243
|
-
* ```
|
|
244
|
-
*/
|
|
245
|
-
disabled?: boolean;
|
|
246
222
|
}
|
|
247
223
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -11,4 +11,10 @@
|
|
|
11
11
|
* @module Button-CTA/types
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
// NO DISABLED STATES
|
|
15
|
+
// DesignerPunk does not support disabled states for usability and
|
|
16
|
+
// accessibility reasons. If an action is unavailable, the component
|
|
17
|
+
// should not be rendered. For in-flight async actions, use the loading
|
|
18
|
+
// state (state_loading) instead.
|
|
19
|
+
// Ruled by Peter 2026-07-15 (Button-CTA disabled-state adjudication).
|
|
14
20
|
//# sourceMappingURL=types.js.map
|
|
@@ -40,7 +40,19 @@ export interface InputTextBaseProps {
|
|
|
40
40
|
autocomplete?: string;
|
|
41
41
|
/** Placeholder text (only shown when label is floated and input is empty) */
|
|
42
42
|
placeholder?: string;
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Read-only state (state_readonly contract): the value is displayed
|
|
45
|
+
* non-editably while remaining perceivable, selectable, and copyable —
|
|
46
|
+
* never rendered with disabled semantics on any platform.
|
|
47
|
+
*
|
|
48
|
+
* Platform note: web and Android readOnly fields participate in keyboard
|
|
49
|
+
* focus order; iOS renders readOnly as selectable static text in the
|
|
50
|
+
* field chrome and is not in focus order (declared carve-out — see
|
|
51
|
+
* contracts.yaml interaction_focusable).
|
|
52
|
+
*
|
|
53
|
+
* NOT supported by Input-Text-Password: readOnly is contracted out of the
|
|
54
|
+
* Password variant (see its contracts.yaml excludes) and is ignored there.
|
|
55
|
+
*/
|
|
44
56
|
readOnly?: boolean;
|
|
45
57
|
/** Required field indicator */
|
|
46
58
|
required?: boolean;
|
|
@@ -152,6 +152,9 @@ class InputTextPassword extends HTMLElement {
|
|
|
152
152
|
'error-message',
|
|
153
153
|
'is-success',
|
|
154
154
|
'show-info-icon',
|
|
155
|
+
// read-only is accepted for API stability but IGNORED — readOnly is
|
|
156
|
+
// contracted out of Input-Text-Password (see render(), and
|
|
157
|
+
// contracts.yaml excludes.state_readonly).
|
|
155
158
|
'read-only',
|
|
156
159
|
'required',
|
|
157
160
|
'max-length',
|
|
@@ -225,7 +228,14 @@ class InputTextPassword extends HTMLElement {
|
|
|
225
228
|
const propsErrorMessage = this.getAttribute('error-message') || '';
|
|
226
229
|
const isSuccess = this.getAttribute('is-success') === 'true';
|
|
227
230
|
const showInfoIcon = this.getAttribute('show-info-icon') === 'true';
|
|
228
|
-
|
|
231
|
+
// read-only is NOT read or forwarded: readOnly is contracted out of
|
|
232
|
+
// Input-Text-Password (adjudication condition 4:
|
|
233
|
+
// .kiro/issues/input-text-base-ios-readonly-adjudication.md — RULED
|
|
234
|
+
// B-prime, Peter 2026-07-15). On web this is contract conformance, not a
|
|
235
|
+
// security fix — a readonly password input stays masked and browsers
|
|
236
|
+
// block copy from type=password — but the exclusion holds uniformly on
|
|
237
|
+
// all three platforms. The attribute is accepted (observedAttributes)
|
|
238
|
+
// for API stability and ignored.
|
|
229
239
|
const required = this.hasAttribute('required');
|
|
230
240
|
const maxLength = this.getAttribute('max-length');
|
|
231
241
|
const showToggle = this.getAttribute('show-toggle') !== 'false'; // Default true
|
|
@@ -264,7 +274,6 @@ class InputTextPassword extends HTMLElement {
|
|
|
264
274
|
${errorMessage ? `error-message="${errorMessage}"` : ''}
|
|
265
275
|
${isSuccess ? 'is-success="true"' : ''}
|
|
266
276
|
${showInfoIcon ? 'show-info-icon="true"' : ''}
|
|
267
|
-
${readOnly ? 'read-only' : ''}
|
|
268
277
|
${required ? 'required' : ''}
|
|
269
278
|
${maxLength ? `max-length="${maxLength}"` : ''}
|
|
270
279
|
></input-text-base>
|
|
@@ -686,6 +686,14 @@ class DTCGFormatGenerator {
|
|
|
686
686
|
else if (token.direction === 'lighter') {
|
|
687
687
|
extensions.blendType = 'lighterBlend';
|
|
688
688
|
}
|
|
689
|
+
// Deprecation metadata (e.g. blend.disabledDesaturate) — lets includeDeprecated: false strip it
|
|
690
|
+
if (token.deprecated) {
|
|
691
|
+
extensions.deprecated = true;
|
|
692
|
+
if (token.deprecatedSince)
|
|
693
|
+
extensions.deprecatedSince = token.deprecatedSince;
|
|
694
|
+
if (token.deprecatedReason)
|
|
695
|
+
extensions.deprecatedReason = token.deprecatedReason;
|
|
696
|
+
}
|
|
689
697
|
group[key] = this.toDTCGToken(aliasValue, 'number', token.description, extensions);
|
|
690
698
|
}
|
|
691
699
|
return group;
|
|
@@ -149,7 +149,7 @@ class BuildErrorHandler {
|
|
|
149
149
|
'Validate configuration against schema'
|
|
150
150
|
],
|
|
151
151
|
documentation: [
|
|
152
|
-
'https://github.com/3fn/
|
|
152
|
+
'https://github.com/3fn/DesignerPunk/docs/build-integration.md'
|
|
153
153
|
]
|
|
154
154
|
};
|
|
155
155
|
}
|
|
@@ -169,7 +169,7 @@ class BuildErrorHandler {
|
|
|
169
169
|
'Ensure platform files are generated correctly'
|
|
170
170
|
],
|
|
171
171
|
documentation: [
|
|
172
|
-
`https://github.com/3fn/
|
|
172
|
+
`https://github.com/3fn/DesignerPunk/docs/platforms/${platform}.md`
|
|
173
173
|
]
|
|
174
174
|
};
|
|
175
175
|
}
|