@ankhorage/surface 9.1.116 → 9.3.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 (100) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/dist/features/badge/adapters/inbound/Badge.d.ts.map +1 -1
  4. package/dist/features/badge/adapters/inbound/Badge.js +1 -1
  5. package/dist/features/badge/adapters/inbound/Badge.js.map +1 -1
  6. package/dist/features/button/adapters/inbound/Button.js +1 -2
  7. package/dist/features/button/adapters/inbound/Button.js.map +1 -1
  8. package/dist/features/icon/adapters/inbound/Icon.d.ts.map +1 -1
  9. package/dist/features/icon/adapters/inbound/Icon.js +9 -1
  10. package/dist/features/icon/adapters/inbound/Icon.js.map +1 -1
  11. package/dist/features/tabs/adapters/inbound/Tab.d.ts.map +1 -1
  12. package/dist/features/tabs/adapters/inbound/Tab.js +14 -2
  13. package/dist/features/tabs/adapters/inbound/Tab.js.map +1 -1
  14. package/dist/features/tabs/adapters/inbound/TabPanel.d.ts +1 -1
  15. package/dist/features/tabs/adapters/inbound/TabPanel.d.ts.map +1 -1
  16. package/dist/features/tabs/adapters/inbound/TabPanel.js +8 -3
  17. package/dist/features/tabs/adapters/inbound/TabPanel.js.map +1 -1
  18. package/dist/features/tabs/adapters/inbound/Tabs.d.ts +1 -1
  19. package/dist/features/tabs/adapters/inbound/Tabs.d.ts.map +1 -1
  20. package/dist/features/tabs/adapters/inbound/Tabs.js +2 -2
  21. package/dist/features/tabs/adapters/inbound/Tabs.js.map +1 -1
  22. package/dist/features/tabs/composition/useTabsController.d.ts +1 -1
  23. package/dist/features/tabs/composition/useTabsController.d.ts.map +1 -1
  24. package/dist/features/tabs/composition/useTabsController.js +3 -2
  25. package/dist/features/tabs/composition/useTabsController.js.map +1 -1
  26. package/dist/features/tabs/public.d.ts +1 -1
  27. package/dist/features/tabs/public.d.ts.map +1 -1
  28. package/dist/features/tabs/public.js.map +1 -1
  29. package/dist/features/theme/adapters/inbound/ThemeProvider.d.ts.map +1 -1
  30. package/dist/features/theme/adapters/inbound/ThemeProvider.js +1 -0
  31. package/dist/features/theme/adapters/inbound/ThemeProvider.js.map +1 -1
  32. package/dist/features/theme/adapters/inbound/ThemeRuntimeContext.d.ts.map +1 -1
  33. package/dist/features/theme/adapters/inbound/ThemeRuntimeContext.js +1 -0
  34. package/dist/features/theme/adapters/inbound/ThemeRuntimeContext.js.map +1 -1
  35. package/dist/features/theme/adapters/inbound/ThemeScope.d.ts +2 -2
  36. package/dist/features/theme/adapters/inbound/ThemeScope.d.ts.map +1 -1
  37. package/dist/features/theme/adapters/inbound/ThemeScope.js +5 -4
  38. package/dist/features/theme/adapters/inbound/ThemeScope.js.map +1 -1
  39. package/dist/features/theme/application/use-cases/createTheme.d.ts +2 -2
  40. package/dist/features/theme/application/use-cases/createTheme.d.ts.map +1 -1
  41. package/dist/features/theme/application/use-cases/createTheme.js +6 -3
  42. package/dist/features/theme/application/use-cases/createTheme.js.map +1 -1
  43. package/dist/features/theme/domain/projectInvertedTheme.d.ts +4 -0
  44. package/dist/features/theme/domain/projectInvertedTheme.d.ts.map +1 -0
  45. package/dist/features/theme/domain/projectInvertedTheme.js +178 -0
  46. package/dist/features/theme/domain/projectInvertedTheme.js.map +1 -0
  47. package/dist/features/theme/domain/resolveInverseSurface.d.ts +10 -0
  48. package/dist/features/theme/domain/resolveInverseSurface.d.ts.map +1 -0
  49. package/dist/features/theme/domain/resolveInverseSurface.js +31 -0
  50. package/dist/features/theme/domain/resolveInverseSurface.js.map +1 -0
  51. package/dist/features/typography/adapters/inbound/Text.d.ts +1 -1
  52. package/dist/features/typography/adapters/inbound/Text.d.ts.map +1 -1
  53. package/dist/features/typography/adapters/inbound/Text.js +2 -1
  54. package/dist/features/typography/adapters/inbound/Text.js.map +1 -1
  55. package/dist/index.d.ts +1 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js.map +1 -1
  58. package/dist/internal/resolvers/resolveInteractiveColors.d.ts.map +1 -1
  59. package/dist/internal/resolvers/resolveInteractiveColors.js +10 -2
  60. package/dist/internal/resolvers/resolveInteractiveColors.js.map +1 -1
  61. package/dist/internal/resolvers/resolveTextColor.d.ts.map +1 -1
  62. package/dist/internal/resolvers/resolveTextColor.js +2 -1
  63. package/dist/internal/resolvers/resolveTextColor.js.map +1 -1
  64. package/dist/types/tabs.d.ts +3 -0
  65. package/dist/types/tabs.d.ts.map +1 -1
  66. package/dist/types/tabs.js.map +1 -1
  67. package/dist/types/theme.d.ts +3 -0
  68. package/dist/types/theme.d.ts.map +1 -1
  69. package/dist/types/theme.js.map +1 -1
  70. package/dist/types/typography.d.ts +1 -0
  71. package/dist/types/typography.d.ts.map +1 -1
  72. package/dist/types/typography.js.map +1 -1
  73. package/package.json +2 -2
  74. package/src/features/badge/adapters/inbound/Badge.tsx +1 -6
  75. package/src/features/button/adapters/inbound/Button.tsx +1 -3
  76. package/src/features/icon/adapters/inbound/Icon.tsx +12 -1
  77. package/src/features/icon/adapters/inbound/PortableIcon.test.tsx +32 -0
  78. package/src/features/tabs/adapters/inbound/Tab.tsx +23 -1
  79. package/src/features/tabs/adapters/inbound/TabPanel.tsx +8 -2
  80. package/src/features/tabs/adapters/inbound/Tabs.presentation.test.tsx +70 -1
  81. package/src/features/tabs/adapters/inbound/Tabs.tsx +2 -1
  82. package/src/features/tabs/composition/useTabsController.ts +7 -2
  83. package/src/features/tabs/public.ts +7 -1
  84. package/src/features/theme/adapters/inbound/ThemeProvider.tsx +1 -0
  85. package/src/features/theme/adapters/inbound/ThemeRuntimeContext.tsx +1 -0
  86. package/src/features/theme/adapters/inbound/ThemeScope.test.tsx +38 -7
  87. package/src/features/theme/adapters/inbound/ThemeScope.tsx +7 -6
  88. package/src/features/theme/application/use-cases/createTheme.ts +6 -2
  89. package/src/features/theme/domain/projectInvertedTheme.ts +300 -0
  90. package/src/features/theme/domain/resolveInverseSurface.ts +55 -0
  91. package/src/features/typography/adapters/inbound/Text.tsx +2 -0
  92. package/src/index.ts +7 -1
  93. package/src/internal/resolvers/resolveInteractiveColors.test.ts +1 -1
  94. package/src/internal/resolvers/resolveInteractiveColors.ts +12 -2
  95. package/src/internal/resolvers/resolveTextColor.test.ts +5 -0
  96. package/src/internal/resolvers/resolveTextColor.ts +2 -1
  97. package/src/invertedThemeAcceptance.test.ts +204 -0
  98. package/src/types/tabs.ts +4 -0
  99. package/src/types/theme.ts +3 -0
  100. package/src/types/typography.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/types/theme.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/types/theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,QAAQ,EACR,yBAAyB,EACzB,cAAc,EACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,QAAQ,CAAC;IACrB,UAAU,EAAE,QAAQ,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,gFAAgF;AAChF,MAAM,WAAW,+BAA+B;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,0BAA0B,CAAC;CACpC;AAED,8EAA8E;AAC9E,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,wBAAwB,CAAC;IACpC,kBAAkB,EAAE,yBAAyB,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC,yBAAyB,EAAE,sBAAsB,CAAC,CAAC;IAC1E,UAAU,EAAE,SAAS,+BAA+B,EAAE,CAAC;IACvD,SAAS,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAChD,iBAAiB,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACzD;AAED,MAAM,MAAM,UAAU,GACpB,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5F,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;IACF,QAAQ,EAAE,sBAAsB,CAAC;IACjC,SAAS,EAAE,cAAc,CAAC;IAC1B,4FAA4F;IAC5F,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,OAAO,EAAE;QACP,IAAI,EAAE,CAAC,CAAC;QACR,EAAE,EAAE,MAAM,CAAC;QACX,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;IACF,KAAK,EAAE;QACL,IAAI,EAAE,CAAC,CAAC;QACR,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;IACF,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CACd,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EACrB;YACE,IAAI,EAAE,MAAM,CAAC;YACb,UAAU,EAAE,MAAM,CAAC;YACnB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;SACpD,CACF,CAAC;QACF,KAAK,EAAE;YACL,EAAE,EAAE,MAAM,CAAC;YACX,CAAC,EAAE,MAAM,CAAC;YACV,CAAC,EAAE,MAAM,CAAC;YACV,CAAC,EAAE,MAAM,CAAC;YACV,EAAE,EAAE,MAAM,CAAC;YACX,GAAG,EAAE,MAAM,CAAC;YACZ,KAAK,EAAE,MAAM,CAAC;YACd,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;SACvB,CAAC;QACF,OAAO,EAAE;YACP,IAAI,EAAE,UAAU,CAAC;YACjB,UAAU,EAAE,UAAU,CAAC;YACvB,KAAK,EAAE,UAAU,CAAC;YAClB,OAAO,EAAE,UAAU,CAAC;YACpB,MAAM,EAAE,UAAU,CAAC;YACnB,QAAQ,EAAE,UAAU,CAAC;YACrB,IAAI,EAAE,UAAU,CAAC;YACjB,SAAS,EAAE,UAAU,CAAC;YACtB,KAAK,EAAE,UAAU,CAAC;SACnB,CAAC;QACF,KAAK,EAAE;YACL,wDAAwD;YACxD,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;YAC/C,wDAAwD;YACxD,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;SAChD,CAAC;KACH,CAAC;IACF,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,MAAM,EAAE,oBAAoB,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEzC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,KAAK,IAAI,CAAC;IAChE,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/types/theme.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ColorSwatchDiagnostics,\n ColorSwatchSelectionResult,\n DefaultSemanticStatusRole,\n GeneratedThemeModeColors,\n GeneratedThemeSwatches,\n HexColor,\n SemanticColorReferenceMap,\n ThemeColorMode,\n} from '@ankhorage/color-theory';\nimport type { ThemeConfig as ContractsThemeConfig } from '@ankhorage/contracts';\nimport type { ReactNode } from 'react';\n\nexport interface NeutralSemantics {\n bg: string;\n bgSubtle: string;\n surface: string;\n surfaceHover: string;\n surfaceActive: string;\n border: string;\n borderStrong: string;\n divider: string;\n text: string;\n textMuted: string;\n textSubtle: string;\n disabledBg: string;\n disabledText: string;\n}\n\nexport interface RoleSemantics {\n base: string;\n hover: string;\n strong: string;\n softBg: string;\n softHover: string;\n softActive: string;\n outline: string;\n onSurfaceText: string;\n onSolidText: string;\n onHoverText: string;\n onStrongText: string;\n onSoftText: string;\n onSoftHoverText: string;\n onSoftActiveText: string;\n disabledBg: string;\n onDisabledText: string;\n}\n\nexport interface SurfaceSemantics {\n default: string;\n subtle: string;\n raised: string;\n sunken: string;\n overlay: string;\n scrim: string;\n disabled: string;\n inverse: string;\n}\n\nexport interface ContentSemantics {\n default: string;\n muted: string;\n subtle: string;\n disabled: string;\n icon: string;\n link: string;\n visited: string;\n inverse: string;\n}\n\nexport interface BorderSemantics {\n default: string;\n subtle: string;\n strong: string;\n divider: string;\n focus: string;\n}\n\nexport interface SelectionSemantics {\n background: string;\n content: string;\n border: string;\n}\n\nexport interface ActionSemantics {\n primary: RoleSemantics;\n neutral: RoleSemantics;\n danger: RoleSemantics;\n}\n\nexport interface ThemeSemantics {\n neutral: NeutralSemantics;\n brand: RoleSemantics;\n secondary: RoleSemantics;\n accent: RoleSemantics;\n highlight: RoleSemantics;\n danger: RoleSemantics;\n success: RoleSemantics;\n warning: RoleSemantics;\n error: RoleSemantics;\n info: RoleSemantics;\n surface: SurfaceSemantics;\n content: ContentSemantics;\n border: BorderSemantics;\n selection: SelectionSemantics;\n action: ActionSemantics;\n}\n\nexport interface SurfaceContrastDiagnostic {\n id: string;\n foreground: HexColor;\n background: HexColor;\n contrast: number;\n minimumContrast: number;\n passes: boolean;\n}\n\n/** A Color Theory swatch selection together with its stable Surface purpose. */\nexport interface SurfaceColorSelectionDiagnostic {\n id: string;\n result: ColorSwatchSelectionResult;\n}\n\n/** Owner-produced color evidence used to explain a resolved Surface theme. */\nexport interface SurfaceColorDiagnostics {\n mode: ThemeColorMode;\n generated: GeneratedThemeModeColors;\n semanticReferences: SemanticColorReferenceMap;\n statusSwatches: Record<DefaultSemanticStatusRole, ColorSwatchDiagnostics>;\n selections: readonly SurfaceColorSelectionDiagnostic[];\n contrasts: readonly SurfaceContrastDiagnostic[];\n surfaceSeparation: readonly SurfaceContrastDiagnostic[];\n}\n\nexport type FontWeight =\n '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | 'bold' | 'normal';\n\nexport interface ThemeTokens {\n colors: {\n primary: string;\n secondary: string;\n accent: string;\n highlight: string;\n tertiary: string;\n quaternary: string;\n background: string;\n surface: string;\n text: string;\n textSecondary: string;\n border: string;\n error: string;\n success: string;\n warning: string;\n info: string;\n [key: string]: string;\n };\n swatches: GeneratedThemeSwatches;\n semantics: ThemeSemantics;\n /** Generated owner evidence; this is runtime output and is not persisted in ThemeConfig. */\n colorDiagnostics: SurfaceColorDiagnostics;\n spacing: {\n none: 0;\n xs: number;\n s: number;\n m: number;\n l: number;\n xl: number;\n xxl: number;\n [key: string]: number;\n };\n radii: {\n none: 0;\n s: number;\n m: number;\n l: number;\n full: number;\n [key: string]: number;\n };\n typography: {\n headings: Record<\n 1 | 2 | 3 | 4 | 5 | 6,\n {\n size: number;\n lineHeight: number;\n weight: 'regular' | 'medium' | 'semiBold' | 'bold';\n }\n >;\n sizes: {\n xs: number;\n s: number;\n m: number;\n l: number;\n xl: number;\n xxl: number;\n '3xl': number;\n h1: number;\n h2: number;\n h3: number;\n h4: number;\n h5: number;\n h6: number;\n [key: string]: number;\n };\n weights: {\n thin: FontWeight;\n extraLight: FontWeight;\n light: FontWeight;\n regular: FontWeight;\n medium: FontWeight;\n semiBold: FontWeight;\n bold: FontWeight;\n extraBold: FontWeight;\n black: FontWeight;\n };\n fonts: {\n /** Map of weight -> fontFamily name for normal style */\n normal: Record<FontWeight, string | undefined>;\n /** Map of weight -> fontFamily name for italic style */\n italic: Record<FontWeight, string | undefined>;\n };\n };\n shadows: {\n soft: number;\n medium: number;\n hard: number;\n [key: string]: number;\n };\n}\n\nexport interface SurfaceTheme extends ThemeTokens {\n config: ContractsThemeConfig;\n}\n\nexport type ThemeMode = 'light' | 'dark';\n\nexport interface ThemeRuntime {\n theme: SurfaceTheme;\n mode: ThemeMode;\n setThemeConfig: (config: Partial<ContractsThemeConfig>) => void;\n setMode: (mode: ThemeMode) => void;\n}\n\nexport interface ThemeProviderProps {\n children: ReactNode;\n initialConfig?: Partial<ContractsThemeConfig>;\n initialMode?: ThemeMode;\n}\n\nexport interface ThemeScopeProps {\n children: ReactNode;\n themeConfig?: Partial<ContractsThemeConfig>;\n mode?: ThemeMode;\n}\n"]}
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/types/theme.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n ColorSwatchDiagnostics,\n ColorSwatchSelectionResult,\n DefaultSemanticStatusRole,\n GeneratedThemeModeColors,\n GeneratedThemeSwatches,\n HexColor,\n SemanticColorReferenceMap,\n ThemeColorMode,\n} from '@ankhorage/color-theory';\nimport type { ThemeConfig as ContractsThemeConfig } from '@ankhorage/contracts';\nimport type { ReactNode } from 'react';\n\nexport interface NeutralSemantics {\n bg: string;\n bgSubtle: string;\n surface: string;\n surfaceHover: string;\n surfaceActive: string;\n border: string;\n borderStrong: string;\n divider: string;\n text: string;\n textMuted: string;\n textSubtle: string;\n disabledBg: string;\n disabledText: string;\n}\n\nexport interface RoleSemantics {\n base: string;\n hover: string;\n strong: string;\n softBg: string;\n softHover: string;\n softActive: string;\n outline: string;\n onSurfaceText: string;\n onSolidText: string;\n onHoverText: string;\n onStrongText: string;\n onSoftText: string;\n onSoftHoverText: string;\n onSoftActiveText: string;\n disabledBg: string;\n onDisabledText: string;\n}\n\nexport interface SurfaceSemantics {\n default: string;\n subtle: string;\n raised: string;\n sunken: string;\n overlay: string;\n scrim: string;\n disabled: string;\n inverse: string;\n}\n\nexport interface ContentSemantics {\n default: string;\n muted: string;\n subtle: string;\n disabled: string;\n icon: string;\n link: string;\n visited: string;\n inverse: string;\n}\n\nexport interface BorderSemantics {\n default: string;\n subtle: string;\n strong: string;\n divider: string;\n focus: string;\n}\n\nexport interface SelectionSemantics {\n background: string;\n content: string;\n border: string;\n}\n\nexport interface ActionSemantics {\n primary: RoleSemantics;\n neutral: RoleSemantics;\n danger: RoleSemantics;\n}\n\nexport interface ThemeSemantics {\n neutral: NeutralSemantics;\n brand: RoleSemantics;\n secondary: RoleSemantics;\n accent: RoleSemantics;\n highlight: RoleSemantics;\n danger: RoleSemantics;\n success: RoleSemantics;\n warning: RoleSemantics;\n error: RoleSemantics;\n info: RoleSemantics;\n surface: SurfaceSemantics;\n content: ContentSemantics;\n border: BorderSemantics;\n selection: SelectionSemantics;\n action: ActionSemantics;\n}\n\nexport interface SurfaceContrastDiagnostic {\n id: string;\n foreground: HexColor;\n background: HexColor;\n contrast: number;\n minimumContrast: number;\n passes: boolean;\n}\n\n/** A Color Theory swatch selection together with its stable Surface purpose. */\nexport interface SurfaceColorSelectionDiagnostic {\n id: string;\n result: ColorSwatchSelectionResult;\n}\n\n/** Owner-produced color evidence used to explain a resolved Surface theme. */\nexport interface SurfaceColorDiagnostics {\n mode: ThemeColorMode;\n generated: GeneratedThemeModeColors;\n semanticReferences: SemanticColorReferenceMap;\n statusSwatches: Record<DefaultSemanticStatusRole, ColorSwatchDiagnostics>;\n selections: readonly SurfaceColorSelectionDiagnostic[];\n contrasts: readonly SurfaceContrastDiagnostic[];\n surfaceSeparation: readonly SurfaceContrastDiagnostic[];\n}\n\nexport type FontWeight =\n '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | 'bold' | 'normal';\n\nexport interface ThemeTokens {\n colors: {\n primary: string;\n secondary: string;\n accent: string;\n highlight: string;\n tertiary: string;\n quaternary: string;\n background: string;\n surface: string;\n text: string;\n textSecondary: string;\n border: string;\n error: string;\n success: string;\n warning: string;\n info: string;\n [key: string]: string;\n };\n swatches: GeneratedThemeSwatches;\n semantics: ThemeSemantics;\n /** Generated owner evidence; this is runtime output and is not persisted in ThemeConfig. */\n colorDiagnostics: SurfaceColorDiagnostics;\n spacing: {\n none: 0;\n xs: number;\n s: number;\n m: number;\n l: number;\n xl: number;\n xxl: number;\n [key: string]: number;\n };\n radii: {\n none: 0;\n s: number;\n m: number;\n l: number;\n full: number;\n [key: string]: number;\n };\n typography: {\n headings: Record<\n 1 | 2 | 3 | 4 | 5 | 6,\n {\n size: number;\n lineHeight: number;\n weight: 'regular' | 'medium' | 'semiBold' | 'bold';\n }\n >;\n sizes: {\n xs: number;\n s: number;\n m: number;\n l: number;\n xl: number;\n xxl: number;\n '3xl': number;\n h1: number;\n h2: number;\n h3: number;\n h4: number;\n h5: number;\n h6: number;\n [key: string]: number;\n };\n weights: {\n thin: FontWeight;\n extraLight: FontWeight;\n light: FontWeight;\n regular: FontWeight;\n medium: FontWeight;\n semiBold: FontWeight;\n bold: FontWeight;\n extraBold: FontWeight;\n black: FontWeight;\n };\n fonts: {\n /** Map of weight -> fontFamily name for normal style */\n normal: Record<FontWeight, string | undefined>;\n /** Map of weight -> fontFamily name for italic style */\n italic: Record<FontWeight, string | undefined>;\n };\n };\n shadows: {\n soft: number;\n medium: number;\n hard: number;\n [key: string]: number;\n };\n}\n\nexport interface SurfaceTheme extends ThemeTokens {\n config: ContractsThemeConfig;\n inverted?: boolean;\n}\n\nexport type ThemeMode = 'light' | 'dark';\n\nexport interface ThemeRuntime {\n theme: SurfaceTheme;\n mode: ThemeMode;\n inverted?: boolean;\n setThemeConfig: (config: Partial<ContractsThemeConfig>) => void;\n setMode: (mode: ThemeMode) => void;\n}\n\nexport interface ThemeProviderProps {\n children: ReactNode;\n initialConfig?: Partial<ContractsThemeConfig>;\n initialMode?: ThemeMode;\n}\n\nexport interface ThemeScopeProps {\n children: ReactNode;\n themeConfig?: Partial<ContractsThemeConfig>;\n mode?: ThemeMode;\n inverted?: boolean;\n}\n"]}
@@ -27,5 +27,6 @@ export interface TextProps {
27
27
  italic?: boolean;
28
28
  numberOfLines?: number;
29
29
  testID?: string;
30
+ style?: TextStyle;
30
31
  }
31
32
  //# sourceMappingURL=typography.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../src/types/typography.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAC9E,MAAM,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,GAAG,UAAU,CAAC;AAElF,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../src/types/typography.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAC9E,MAAM,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,GAAG,UAAU,CAAC;AAElF,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"typography.js","sourceRoot":"","sources":["../../src/types/typography.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\nimport type { TextStyle } from 'react-native';\n\nimport type { SurfaceColor, SurfaceEmphasis } from './surfaceColor';\nimport type { FontWeight, SurfaceTheme } from './theme';\n\nexport type TextVariant = 'body' | 'bodySmall' | 'caption' | 'label' | 'mono';\nexport type TextWeight = keyof SurfaceTheme['typography']['weights'] | FontWeight;\n\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport interface HeadingProps {\n text?: string;\n children?: React.ReactNode;\n level?: HeadingLevel;\n align?: 'auto' | 'left' | 'right' | 'center' | 'justify';\n color?: SurfaceColor;\n emphasis?: SurfaceEmphasis;\n numberOfLines?: number;\n i18nKey?: string;\n testID?: string;\n}\n\nexport interface TextProps {\n children?: React.ReactNode;\n i18nKey?: string;\n variant?: TextVariant;\n emphasis?: SurfaceEmphasis;\n color?: SurfaceColor;\n align?: TextStyle['textAlign'];\n weight?: TextWeight;\n italic?: boolean;\n numberOfLines?: number;\n testID?: string;\n}\n"]}
1
+ {"version":3,"file":"typography.js","sourceRoot":"","sources":["../../src/types/typography.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\nimport type { TextStyle } from 'react-native';\n\nimport type { SurfaceColor, SurfaceEmphasis } from './surfaceColor';\nimport type { FontWeight, SurfaceTheme } from './theme';\n\nexport type TextVariant = 'body' | 'bodySmall' | 'caption' | 'label' | 'mono';\nexport type TextWeight = keyof SurfaceTheme['typography']['weights'] | FontWeight;\n\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport interface HeadingProps {\n text?: string;\n children?: React.ReactNode;\n level?: HeadingLevel;\n align?: 'auto' | 'left' | 'right' | 'center' | 'justify';\n color?: SurfaceColor;\n emphasis?: SurfaceEmphasis;\n numberOfLines?: number;\n i18nKey?: string;\n testID?: string;\n}\n\nexport interface TextProps {\n children?: React.ReactNode;\n i18nKey?: string;\n variant?: TextVariant;\n emphasis?: SurfaceEmphasis;\n color?: SurfaceColor;\n align?: TextStyle['textAlign'];\n weight?: TextWeight;\n italic?: boolean;\n numberOfLines?: number;\n testID?: string;\n style?: TextStyle;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/surface",
3
3
  "type": "module",
4
- "version": "9.1.116",
4
+ "version": "9.3.0",
5
5
  "description": "Stable UI foundation for React Native and React Native Web.",
6
6
  "homepage": "https://github.com/ankhorage/surface#readme",
7
7
  "bugs": {
@@ -107,7 +107,7 @@
107
107
  "version-packages": "ankhorage-changeset version"
108
108
  },
109
109
  "devDependencies": {
110
- "@ankhorage/devtools": "^2.1.11",
110
+ "@ankhorage/devtools": "^2.1.13",
111
111
  "@ankhorage/paradox": "^0.2.28",
112
112
  "@react-native-vector-icons/fontawesome": "^13.1.4",
113
113
  "@react-native-vector-icons/fontawesome5": "^13.1.4",
@@ -31,12 +31,7 @@ export function Badge({
31
31
  style={resolveBadgeStyle(colors.backgroundColor, colors.borderColor, variant)}
32
32
  testID={testID}
33
33
  >
34
- <Text
35
- color={color}
36
- emphasis={variant === 'solid' ? 'inverse' : 'default'}
37
- variant="bodySmall"
38
- weight="medium"
39
- >
34
+ <Text style={{ color: colors.contentColor }} variant="bodySmall" weight="medium">
40
35
  {content}
41
36
  </Text>
42
37
  </View>
@@ -76,7 +76,6 @@ function ButtonContent({
76
76
  variant,
77
77
  }: ButtonContentProps) {
78
78
  const colors = resolveButtonColors(theme, { variant, color, state });
79
- const muted = colors.contentColor === theme.semantics.content.muted;
80
79
  const iconSize = resolveIconSize(theme, size);
81
80
 
82
81
  return (
@@ -96,8 +95,7 @@ function ButtonContent({
96
95
  </ReactNativeView>
97
96
  ) : null}
98
97
  <Text
99
- color={muted ? undefined : color}
100
- emphasis={muted ? 'muted' : variant === 'solid' ? 'inverse' : 'default'}
98
+ style={{ color: colors.contentColor }}
101
99
  variant={controlSize.textVariant}
102
100
  weight="semiBold"
103
101
  >
@@ -1,4 +1,7 @@
1
+ import { SURFACE_COLORS } from '../../../../constants/surfaceColor';
2
+ import { resolveTextColor } from '../../../../internal/resolvers/resolveTextColor';
1
3
  import type { IconProps } from '../../../../types/icon';
4
+ import type { SurfaceColor } from '../../../../types/surfaceColor';
2
5
  import { useTheme } from '../../../theme/runtime';
3
6
  import { resolveToken } from '../../../theme/utils/resolveToken';
4
7
  import { PortableIcon } from './PortableIcon';
@@ -9,6 +12,14 @@ export function Icon(props: IconProps) {
9
12
  const size = props.size ?? 'm';
10
13
  const color = props.color ?? 'text';
11
14
  const resolvedSize = typeof size === 'number' ? size : resolveToken(theme.spacing, size);
12
- const resolvedColor = resolveToken(theme.colors, color);
15
+ const resolvedColor =
16
+ typeof color === 'string' && isSurfaceColor(color)
17
+ ? resolveTextColor(theme, 'default', color)
18
+ : resolveToken(theme.colors, color);
13
19
  return <PortableIcon {...props} color={resolvedColor} size={resolvedSize} />;
14
20
  }
21
+
22
+ /*** Distinguish semantic color roles from raw icon colors and other tokens. */
23
+ function isSurfaceColor(value: string): value is SurfaceColor {
24
+ return SURFACE_COLORS.some((role) => role === value);
25
+ }
@@ -37,6 +37,8 @@ await mock.module('react-native-svg', () => ({
37
37
  const { SUPPORTED_ICON_PROVIDERS } = await import('../../constants');
38
38
  const { Icon } = await import('./Icon');
39
39
  const { PortableIcon } = await import('./PortableIcon');
40
+ const { createTheme } = await import('../../../theme/application/use-cases/createTheme');
41
+ const { ThemeRuntimeContext } = await import('../../../theme/adapters/inbound/ThemeRuntimeContext');
40
42
 
41
43
  describe('portable icon rendering', () => {
42
44
  test('renders Ionicons through the public Icon API', () => {
@@ -90,6 +92,36 @@ describe('portable icon rendering', () => {
90
92
  });
91
93
  });
92
94
 
95
+ test('semantic icon roles follow polarity while raw colors remain unchanged', () => {
96
+ for (const mode of ['light', 'dark'] as const) {
97
+ const normal = createTheme(undefined, mode);
98
+ const inverted = createTheme(undefined, mode, undefined, true);
99
+ const renderColor = (theme: typeof normal, color: string) =>
100
+ renderToStaticMarkup(
101
+ <ThemeRuntimeContext
102
+ value={{
103
+ theme,
104
+ mode,
105
+ inverted: theme.inverted,
106
+ setThemeConfig: () => undefined,
107
+ setMode: () => undefined,
108
+ }}
109
+ >
110
+ <Icon color={color} size={18} source="https://example.com/icons/home.svg" />
111
+ </ThemeRuntimeContext>,
112
+ );
113
+
114
+ expect(renderColor(normal, 'primary')).toContain(`data-color="${normal.semantics.brand.base}"`);
115
+ expect(renderColor(inverted, 'primary')).toContain(
116
+ `data-color="${inverted.semantics.brand.onSurfaceText}"`,
117
+ );
118
+ expect(renderColor(inverted, 'text')).toContain(
119
+ `data-color="${inverted.semantics.content.default}"`,
120
+ );
121
+ expect(renderColor(inverted, '#123456')).toContain('data-color="#123456"');
122
+ }
123
+ });
124
+
93
125
  describe('portable icon web assets', () => {
94
126
  test('renders a bundled SVG asset through React Native Web Image', () => {
95
127
  const markup = renderToStaticMarkup(
@@ -18,7 +18,8 @@ export function Tab({
18
18
  trailing,
19
19
  }: TabProps) {
20
20
  const { theme } = useTheme();
21
- const { activeValue, getPanelId, getTabId, setActiveValue, setFocusedValue } = useTabsContext();
21
+ const { activeValue, getPanelId, getTabId, setActiveValue, setFocusedValue, variant } =
22
+ useTabsContext();
22
23
  const pressableRef = useTabRegistration({ disabled, value });
23
24
  const selected = activeValue === value;
24
25
  const passive = interactionPolicy === 'passive';
@@ -42,8 +43,12 @@ export function Tab({
42
43
  px="m"
43
44
  py="s"
44
45
  style={resolveTabStyle({
46
+ activeBackground: theme.semantics.surface.subtle,
45
47
  borderColor: selected ? 'transparent' : theme.semantics.border.default,
46
48
  disabled,
49
+ radius: theme.radii.s,
50
+ selected,
51
+ variant,
47
52
  })}
48
53
  >
49
54
  {renderTabContent(children, trailing, selected)}
@@ -74,11 +79,28 @@ function renderTabContent(
74
79
 
75
80
  /*** Resolves active and disabled visual state without inline JSX styles. */
76
81
  function resolveTabStyle({
82
+ activeBackground,
77
83
  borderColor,
78
84
  disabled,
85
+ radius,
86
+ selected,
87
+ variant,
79
88
  }: {
89
+ activeBackground: string;
80
90
  borderColor: string;
81
91
  disabled: boolean;
92
+ radius: number;
93
+ selected: boolean;
94
+ variant: 'line' | 'attached';
82
95
  }): ViewStyle {
96
+ if (variant === 'attached') {
97
+ return {
98
+ backgroundColor: selected ? activeBackground : 'transparent',
99
+ borderTopLeftRadius: selected ? radius : 0,
100
+ borderTopRightRadius: selected ? radius : 0,
101
+ opacity: disabled ? 0.64 : 1,
102
+ };
103
+ }
104
+
83
105
  return { borderBottomColor: borderColor, borderBottomWidth: 2, opacity: disabled ? 0.64 : 1 };
84
106
  }
@@ -2,13 +2,15 @@ import React from 'react';
2
2
 
3
3
  import type { TabPanelProps } from '../../../../types/tabs';
4
4
  import { View } from '../../../layout/public';
5
+ import { useTheme } from '../../../theme/runtime';
5
6
  import { useTabsContext } from '../../composition/useTabsContext';
6
7
 
7
8
  const TAB_PANEL_ROLE = 'tabpanel' as React.ComponentProps<typeof View>['accessibilityRole'];
8
9
 
9
10
  /*** Renders the active content panel with the supplied View layout and tab accessibility linkage. */
10
- export function TabPanel({ value, children, testID, ...layoutProps }: TabPanelProps) {
11
- const { activeValue, getPanelId, getTabId } = useTabsContext();
11
+ export function TabPanel({ value, children, testID, style, ...layoutProps }: TabPanelProps) {
12
+ const { theme } = useTheme();
13
+ const { activeValue, getPanelId, getTabId, variant } = useTabsContext();
12
14
 
13
15
  if (activeValue !== value) return null;
14
16
 
@@ -18,6 +20,10 @@ export function TabPanel({ value, children, testID, ...layoutProps }: TabPanelPr
18
20
  accessibilityLabelledBy={getTabId(value)}
19
21
  accessibilityRole={TAB_PANEL_ROLE}
20
22
  nativeID={getPanelId(value)}
23
+ style={[
24
+ style,
25
+ variant === 'attached' ? { backgroundColor: theme.semantics.surface.subtle } : undefined,
26
+ ]}
21
27
  testID={testID}
22
28
  >
23
29
  {children}
@@ -6,9 +6,12 @@ import * as ReactNativeWeb from 'react-native-web';
6
6
 
7
7
  await mock.module('react-native', () => ReactNativeWeb);
8
8
 
9
- const { ThemeProvider } = await import('../../../theme/runtime');
9
+ const CONSUMER_PANEL_STYLE = { backgroundColor: '#ff00ff' };
10
+
11
+ const { ThemeProvider, ThemeScope } = await import('../../../theme/runtime');
10
12
  const { Tab } = await import('./Tab');
11
13
  const { TabList } = await import('./TabList');
14
+ const { TabPanel } = await import('./TabPanel');
12
15
  const { Tabs } = await import('./Tabs');
13
16
 
14
17
  test('opens the selected tab into its panel while retaining inactive separators', () => {
@@ -40,3 +43,69 @@ test('opens the selected tab into its panel while retaining inactive separators'
40
43
  expect(activeStyle).toMatch(/border-bottom-color:(?:transparent|rgba\(0,0,0,0(?:\.0+)?\))/u);
41
44
  browserWindow.close();
42
45
  });
46
+
47
+ test.each([
48
+ ['light', false],
49
+ ['light', true],
50
+ ['dark', false],
51
+ ['dark', true],
52
+ ] as const)('%s attached tabs own one semantic surface (inverted=%p)', (mode, inverted) => {
53
+ const styles = renderAttachedStyles(mode, inverted);
54
+
55
+ expect(styles.active).not.toContain('border-bottom-width');
56
+ expect(styles.inactive).not.toContain('border-bottom-width');
57
+ expect(styles.inactive).toMatch(/background-color:(?:transparent|rgba\(0,0,0,0(?:\.0+)?\))/u);
58
+ expect(styles.activeBackground).toBeTruthy();
59
+ expect(styles.panel).toContain(`background-color:${styles.activeBackground}`);
60
+ expect(styles.panel).not.toContain('rgb(255, 0, 255)');
61
+ });
62
+
63
+ test.each(['light', 'dark'] as const)(
64
+ '%s attached tabs follow inherited surface polarity',
65
+ (mode) => {
66
+ const normal = renderAttachedStyles(mode, false);
67
+ const inverted = renderAttachedStyles(mode, true);
68
+
69
+ expect(normal.activeBackground).not.toBe(inverted.activeBackground);
70
+ expect(normal.panel).toContain(`background-color:${normal.activeBackground}`);
71
+ expect(inverted.panel).toContain(`background-color:${inverted.activeBackground}`);
72
+ },
73
+ );
74
+
75
+ /*** Render attached tabs and return their observable web presentation styles. */
76
+ function renderAttachedStyles(mode: 'light' | 'dark', inverted: boolean) {
77
+ const markup = renderToStaticMarkup(
78
+ <ThemeProvider initialMode={mode}>
79
+ <ThemeScope inverted={inverted}>
80
+ <Tabs defaultValue="tree" variant="attached">
81
+ <TabList>
82
+ <Tab testID="tree-tab" value="tree">
83
+ Tree
84
+ </Tab>
85
+ <Tab testID="export-tab" value="export">
86
+ Export
87
+ </Tab>
88
+ </TabList>
89
+ <TabPanel style={CONSUMER_PANEL_STYLE} testID="tree-panel" value="tree">
90
+ Content
91
+ </TabPanel>
92
+ </Tabs>
93
+ </ThemeScope>
94
+ </ThemeProvider>,
95
+ );
96
+
97
+ const browserWindow = new Window();
98
+ browserWindow.document.body.innerHTML = markup;
99
+ const active = browserWindow.document.querySelector('[data-testid="tree-tab"] > div');
100
+ const inactive = browserWindow.document.querySelector('[data-testid="export-tab"] > div');
101
+ const panel = browserWindow.document.querySelector('[data-testid="tree-panel"]');
102
+ const activeStyle = active?.getAttribute('style') ?? '';
103
+ const result = {
104
+ active: activeStyle,
105
+ inactive: inactive?.getAttribute('style') ?? '',
106
+ panel: panel?.getAttribute('style') ?? '',
107
+ activeBackground: /background-color:([^;]+)/u.exec(activeStyle)?.[1],
108
+ };
109
+ browserWindow.close();
110
+ return result;
111
+ }
@@ -12,9 +12,10 @@ export function Tabs({
12
12
  onValueChange,
13
13
  testID,
14
14
  value,
15
+ variant,
15
16
  ...layoutProps
16
17
  }: TabsProps) {
17
- const contextValue = useTabsController({ defaultValue, onValueChange, testID, value });
18
+ const contextValue = useTabsController({ defaultValue, onValueChange, testID, value, variant });
18
19
 
19
20
  return (
20
21
  <TabsContext value={contextValue}>
@@ -10,7 +10,11 @@ export function useTabsController({
10
10
  onValueChange,
11
11
  testID,
12
12
  value,
13
- }: Pick<TabsProps, 'defaultValue' | 'onValueChange' | 'testID' | 'value'>): TabsContextValue {
13
+ variant = 'line',
14
+ }: Pick<
15
+ TabsProps,
16
+ 'defaultValue' | 'onValueChange' | 'testID' | 'value' | 'variant'
17
+ >): TabsContextValue {
14
18
  const [activeValue, setActiveValue] = useControllableState<string | undefined>({
15
19
  defaultValue,
16
20
  onChange: (nextValue) => {
@@ -49,7 +53,8 @@ export function useTabsController({
49
53
  setFocusedValue,
50
54
  tabs,
51
55
  unregisterTab,
56
+ variant,
52
57
  }),
53
- [activeValue, focusedValue, registerTab, setActiveValue, tabs, testID, unregisterTab],
58
+ [activeValue, focusedValue, registerTab, setActiveValue, tabs, testID, unregisterTab, variant],
54
59
  );
55
60
  }
@@ -1,4 +1,10 @@
1
- export type { TabListProps, TabPanelProps, TabProps, TabsProps } from '../../types/tabs';
1
+ export type {
2
+ TabListProps,
3
+ TabPanelProps,
4
+ TabProps,
5
+ TabsProps,
6
+ TabsVariant,
7
+ } from '../../types/tabs';
2
8
  export { Tab } from './adapters/inbound/Tab';
3
9
  export { TabList } from './adapters/inbound/TabList';
4
10
  export { TabPanel } from './adapters/inbound/TabPanel';
@@ -30,6 +30,7 @@ export function ThemeProvider({
30
30
  () => ({
31
31
  theme,
32
32
  mode,
33
+ inverted: false,
33
34
  setThemeConfig: (nextConfig) => setConfig((previous) => deepMerge(previous, nextConfig)),
34
35
  setMode,
35
36
  }),
@@ -9,6 +9,7 @@ const defaultTheme = createTheme();
9
9
  export const ThemeRuntimeContext = createContext<ThemeRuntime>({
10
10
  theme: defaultTheme,
11
11
  mode: 'light',
12
+ inverted: false,
12
13
  setThemeConfig: () => undefined,
13
14
  setMode: () => undefined,
14
15
  });
@@ -8,8 +8,10 @@ import { ThemeScope } from './ThemeScope';
8
8
  import { useTheme } from './useTheme';
9
9
 
10
10
  function ThemeProbe() {
11
- const { mode, theme } = useTheme();
12
- return <span>{`${theme.config.id}:${mode}:${theme.colorDiagnostics.mode}`}</span>;
11
+ const { mode, theme, inverted } = useTheme();
12
+ return (
13
+ <span>{`${theme.config.id}:${mode}:${theme.colorDiagnostics.mode}:${inverted}:${theme.semantics.surface.default}`}</span>
14
+ );
13
15
  }
14
16
 
15
17
  const parentRuntime: ThemeRuntime = {
@@ -30,9 +32,9 @@ test('overrides mode without mutating the parent theme runtime', () => {
30
32
  </ThemeRuntimeContext>,
31
33
  );
32
34
 
33
- expect(markup).toContain('default:light:light');
34
- expect(markup).toContain('default:dark:dark');
35
- expect(markup.match(/default:light:light/g)).toHaveLength(2);
35
+ expect(markup).toContain('default:light:light:undefined');
36
+ expect(markup).toContain('default:dark:dark:false');
37
+ expect(markup.match(/default:light:light:undefined/g)).toHaveLength(2);
36
38
  });
37
39
 
38
40
  test('deep-merges a nested config override while preserving the parent config', () => {
@@ -46,7 +48,36 @@ test('deep-merges a nested config override while preserving the parent config',
46
48
  </ThemeRuntimeContext>,
47
49
  );
48
50
 
49
- expect(markup).toContain('scoped:light:light');
50
- expect(markup.match(/default:light:light/g)).toHaveLength(2);
51
+ expect(markup).toContain('scoped:light:light:false');
52
+ expect(markup.match(/default:light:light:undefined/g)).toHaveLength(2);
51
53
  expect(parentRuntime.theme.config.id).toBe('default');
52
54
  });
55
+
56
+ test.each(['light', 'dark'] as const)(
57
+ 'inherits and resets inverted polarity in %s mode',
58
+ (mode) => {
59
+ const root = { ...parentRuntime, mode, theme: createTheme(undefined, mode) };
60
+ const { default: normal, inverse } = root.theme.semantics.surface;
61
+ const markup = renderToStaticMarkup(
62
+ <ThemeRuntimeContext value={root}>
63
+ <ThemeScope inverted>
64
+ <ThemeProbe />
65
+ <ThemeScope>
66
+ <ThemeProbe />
67
+ <ThemeScope inverted={false}>
68
+ <ThemeProbe />
69
+ <ThemeScope inverted>
70
+ <ThemeProbe />
71
+ </ThemeScope>
72
+ </ThemeScope>
73
+ </ThemeScope>
74
+ </ThemeScope>
75
+ </ThemeRuntimeContext>,
76
+ );
77
+
78
+ expect(markup.match(new RegExp(`${mode}:${mode}:true:${inverse}`, 'g'))).toHaveLength(3);
79
+ expect(markup).toContain(`${mode}:${mode}:false:${normal}`);
80
+ expect(root.inverted).toBeUndefined();
81
+ expect(root.theme.semantics.surface.default).toBe(normal);
82
+ },
83
+ );
@@ -7,22 +7,23 @@ import { createTheme } from '../../application/use-cases/createTheme';
7
7
  import { ThemeRuntimeContext } from './ThemeRuntimeContext';
8
8
  import { useTheme } from './useTheme';
9
9
 
10
- /*** Apply a nested Surface theme or mode override without remounting app-level providers. */
11
- export function ThemeScope({ children, themeConfig, mode }: ThemeScopeProps) {
10
+ /*** Apply nested theme, mode, or inherited surface-polarity overrides without remounting providers. */
11
+ export function ThemeScope({ children, themeConfig, mode, inverted }: ThemeScopeProps) {
12
12
  const parent = useTheme();
13
13
  const { activeFontId } = useFontRuntime();
14
14
  const scopedMode = mode ?? parent.mode;
15
+ const scopedInverted = inverted ?? parent.inverted ?? false;
15
16
  const scopedConfig = useMemo(
16
17
  () => (themeConfig ? deepMerge(parent.theme.config, themeConfig) : parent.theme.config),
17
18
  [parent.theme.config, themeConfig],
18
19
  );
19
20
  const theme = useMemo(
20
- () => createTheme(scopedConfig, scopedMode, activeFontId),
21
- [activeFontId, scopedConfig, scopedMode],
21
+ () => createTheme(scopedConfig, scopedMode, activeFontId, scopedInverted),
22
+ [activeFontId, scopedConfig, scopedMode, scopedInverted],
22
23
  );
23
24
  const value = useMemo<ThemeRuntime>(
24
- () => ({ ...parent, theme, mode: scopedMode }),
25
- [parent, scopedMode, theme],
25
+ () => ({ ...parent, theme, mode: scopedMode, inverted: scopedInverted }),
26
+ [parent, scopedMode, scopedInverted, theme],
26
27
  );
27
28
 
28
29
  return <ThemeRuntimeContext value={value}>{children}</ThemeRuntimeContext>;
@@ -2,6 +2,7 @@ import type { ThemeConfig } from '@ankhorage/contracts';
2
2
 
3
3
  import type { FontWeight, SurfaceTheme } from '../../../../types/theme';
4
4
  import { generatePalette } from '../../domain/generatePalette';
5
+ import { projectInvertedTheme } from '../../domain/projectInvertedTheme';
5
6
  import { resolveGlobalTokens } from '../../utils/resolveGlobalTokens';
6
7
 
7
8
  const DEFAULT_CONFIG: ThemeConfig = {
@@ -11,11 +12,12 @@ const DEFAULT_CONFIG: ThemeConfig = {
11
12
  dark: { primaryColor: '#3B82F6', harmony: 'monochromatic' },
12
13
  };
13
14
 
14
- /*** Resolve canonical persisted theme source into the complete Surface runtime theme. */
15
+ /*** Resolve canonical theme source into a normal or inverted Surface runtime theme. */
15
16
  export function createTheme(
16
17
  config: ThemeConfig = DEFAULT_CONFIG,
17
18
  mode: 'light' | 'dark' = 'light',
18
19
  activeFontId?: string | null,
20
+ inverted = false,
19
21
  ): SurfaceTheme {
20
22
  const { colors, swatches, semantics, colorDiagnostics } = generatePalette(config, mode);
21
23
  const baseTheme: SurfaceTheme = {
@@ -25,8 +27,10 @@ export function createTheme(
25
27
  semantics,
26
28
  colorDiagnostics,
27
29
  config,
30
+ inverted: false,
28
31
  };
29
- return activeFontId ? withActiveFont(baseTheme, activeFontId) : baseTheme;
32
+ const themed = activeFontId ? withActiveFont(baseTheme, activeFontId) : baseTheme;
33
+ return inverted ? projectInvertedTheme(themed) : themed;
30
34
  }
31
35
 
32
36
  /*** Return a theme with generated module font-family names without mutating the base theme. */