@salesforce/ui-bundle-template-feature-angular-language-switcher 12.5.4

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 (253) hide show
  1. package/LICENSE.txt +82 -0
  2. package/README.md +193 -0
  3. package/dist/.forceignore +15 -0
  4. package/dist/.husky/pre-commit +4 -0
  5. package/dist/.prettierignore +11 -0
  6. package/dist/.prettierrc +17 -0
  7. package/dist/CHANGELOG.md +5238 -0
  8. package/dist/README.md +77 -0
  9. package/dist/config/project-scratch-def.json +13 -0
  10. package/dist/eslint.config.js +7 -0
  11. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.forceignore +15 -0
  12. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.graphqlrc.yml +2 -0
  13. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.postcssrc.json +5 -0
  14. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.prettierignore +8 -0
  15. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/.prettierrc +12 -0
  16. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/CHANGELOG.md +4 -0
  17. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/README.md +85 -0
  18. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/angular.json +98 -0
  19. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/codegen.yml +95 -0
  20. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/components.json +6 -0
  21. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/e2e/app.spec.ts +15 -0
  22. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/esbuild/api-version.mjs +17 -0
  23. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/esbuild/graphql-codegen.mjs +13 -0
  24. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/eslint-plugin-angular-graphql.js +148 -0
  25. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/eslint.config.js +76 -0
  26. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/feature-angular-language-switcher.uibundle-meta.xml +7 -0
  27. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/middleware/html.mjs +3 -0
  28. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/middleware/proxy.mjs +12 -0
  29. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/package.json +69 -0
  30. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/playwright.config.ts +25 -0
  31. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/public/favicon.ico +0 -0
  32. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/scripts/get-graphql-schema.mjs +69 -0
  33. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/scripts/rewrite-e2e-assets.mjs +30 -0
  34. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/api/data-client.service.spec.ts +184 -0
  35. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/api/data-client.service.ts +74 -0
  36. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.config.ts +20 -0
  37. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.html +1 -0
  38. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.routes.ts +26 -0
  39. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.spec.ts +18 -0
  40. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/app.ts +15 -0
  41. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/layout/app-layout/app-layout.html +51 -0
  42. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/layout/app-layout/app-layout.spec.ts +63 -0
  43. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/layout/app-layout/app-layout.ts +27 -0
  44. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/alert/alert.html +27 -0
  45. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/alert/alert.ts +41 -0
  46. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/button/button.html +27 -0
  47. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/button/button.ts +66 -0
  48. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/card/card.ts +100 -0
  49. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/collapsible/collapsible.html +38 -0
  50. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/collapsible/collapsible.ts +21 -0
  51. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/date-picker/date-picker.html +20 -0
  52. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/date-picker/date-picker.ts +49 -0
  53. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/date-range-picker/date-range-picker.html +20 -0
  54. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/date-range-picker/date-range-picker.ts +69 -0
  55. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/dialog/dialog.html +20 -0
  56. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/dialog/dialog.ts +40 -0
  57. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/dropdown-menu/dropdown-menu.html +20 -0
  58. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/dropdown-menu/dropdown-menu.ts +100 -0
  59. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/field/field.html +15 -0
  60. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/field/field.ts +28 -0
  61. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/field-appearance.ts +8 -0
  62. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/field-size.ts +8 -0
  63. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/icon/icon.ts +68 -0
  64. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/input/input.html +34 -0
  65. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/input/input.ts +79 -0
  66. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/label/label.ts +21 -0
  67. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/paginator/paginator.html +74 -0
  68. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/paginator/paginator.ts +93 -0
  69. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/paginator/types.ts +13 -0
  70. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/popover/popover.html +13 -0
  71. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/popover/popover.ts +37 -0
  72. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/select/select.html +36 -0
  73. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/select/select.ts +63 -0
  74. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/separator/separator.ts +31 -0
  75. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/skeleton/skeleton.ts +20 -0
  76. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/components/ui/spinner/spinner.ts +28 -0
  77. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/__examples__/html-middleware-site-example.ts +41 -0
  78. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/__examples__/language-switcher-example.ts +41 -0
  79. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/build-language-url.ts +158 -0
  80. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/index.ts +28 -0
  81. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/language-switcher.html +22 -0
  82. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/language-switcher.ts +110 -0
  83. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/features/language-switcher/languages.ts +46 -0
  84. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/home/home.html +6 -0
  85. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/home/home.spec.ts +23 -0
  86. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/home/home.ts +13 -0
  87. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/not-found/not-found.html +12 -0
  88. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/not-found/not-found.spec.ts +33 -0
  89. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/pages/not-found/not-found.ts +15 -0
  90. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/hlm-alert-action.ts +14 -0
  91. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/hlm-alert-description.ts +17 -0
  92. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/hlm-alert-title.ts +17 -0
  93. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/hlm-alert.ts +35 -0
  94. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/alert/index.ts +16 -0
  95. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/button/hlm-button.token.ts +22 -0
  96. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/button/hlm-button.ts +72 -0
  97. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/button/index.ts +6 -0
  98. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/hlm-calendar-multi.ts +195 -0
  99. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/hlm-calendar-range.ts +194 -0
  100. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/hlm-calendar.ts +189 -0
  101. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/hlm-month-year-calendar.ts +119 -0
  102. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/calendar/index.ts +16 -0
  103. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-action.ts +12 -0
  104. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-avatar.ts +14 -0
  105. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-content.ts +12 -0
  106. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-description.ts +12 -0
  107. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-footer.ts +12 -0
  108. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-header.ts +15 -0
  109. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card-title.ts +12 -0
  110. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card.token.ts +19 -0
  111. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/hlm-card.ts +22 -0
  112. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/card/index.ts +28 -0
  113. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/collapsible/hlm-collapsible-content.ts +14 -0
  114. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/collapsible/hlm-collapsible-trigger.ts +9 -0
  115. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/collapsible/hlm-collapsible.ts +15 -0
  116. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/collapsible/index.ts +13 -0
  117. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-multi-input.ts +104 -0
  118. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-anchor.ts +23 -0
  119. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-input.ts +118 -0
  120. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-multi.token.ts +109 -0
  121. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-multi.ts +220 -0
  122. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker-trigger.ts +104 -0
  123. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker.token.ts +69 -0
  124. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-picker.ts +203 -0
  125. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-range-input.ts +120 -0
  126. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-range-picker.token.ts +86 -0
  127. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-date-range-picker.ts +252 -0
  128. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-month-year-input.ts +105 -0
  129. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-month-year-picker.token.ts +89 -0
  130. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/hlm-month-year-picker.ts +196 -0
  131. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/date-picker/index.ts +38 -0
  132. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-close.ts +9 -0
  133. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-content.ts +74 -0
  134. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-description.ts +17 -0
  135. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-footer.ts +15 -0
  136. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-header.ts +12 -0
  137. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-overlay.ts +27 -0
  138. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-portal.ts +8 -0
  139. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-title.ts +14 -0
  140. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog-trigger.ts +14 -0
  141. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog.service.ts +46 -0
  142. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/hlm-dialog.ts +24 -0
  143. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dialog/index.ts +35 -0
  144. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-checkbox-indicator.ts +21 -0
  145. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-checkbox.ts +54 -0
  146. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-focus-on-hover.ts +35 -0
  147. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-group.ts +14 -0
  148. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-item-sub-indicator.ts +19 -0
  149. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-item.ts +42 -0
  150. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-label.ts +20 -0
  151. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-radio-indicator.ts +21 -0
  152. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-radio.ts +49 -0
  153. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-separator.ts +12 -0
  154. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-shortcut.ts +15 -0
  155. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-sub-trigger.ts +52 -0
  156. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-sub.ts +53 -0
  157. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-token.ts +26 -0
  158. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu-trigger.ts +46 -0
  159. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/hlm-dropdown-menu.ts +57 -0
  160. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/dropdown-menu/index.ts +49 -0
  161. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-content.ts +12 -0
  162. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-description.ts +53 -0
  163. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-error.ts +100 -0
  164. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-group.ts +15 -0
  165. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-label.ts +17 -0
  166. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-legend.ts +19 -0
  167. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-separator.ts +24 -0
  168. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-set.ts +15 -0
  169. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field-title.ts +15 -0
  170. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/hlm-field.ts +47 -0
  171. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/field/index.ts +34 -0
  172. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input/hlm-input.ts +21 -0
  173. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input/index.ts +5 -0
  174. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group-addon.ts +40 -0
  175. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group-button.ts +47 -0
  176. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group-input.ts +17 -0
  177. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group-text.ts +14 -0
  178. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/hlm-input-group.ts +18 -0
  179. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/input-group/index.ts +19 -0
  180. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/label/hlm-label.ts +17 -0
  181. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/label/index.ts +5 -0
  182. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/label/label.html +11 -0
  183. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-numbered-pagination-query-params.ts +191 -0
  184. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-numbered-pagination.ts +290 -0
  185. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-content.ts +12 -0
  186. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-ellipsis.ts +27 -0
  187. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-item.ts +7 -0
  188. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-link.ts +51 -0
  189. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-next.ts +65 -0
  190. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination-previous.ts +65 -0
  191. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/hlm-pagination.ts +19 -0
  192. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/pagination/index.ts +31 -0
  193. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-content.ts +25 -0
  194. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-description.ts +12 -0
  195. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-header.ts +12 -0
  196. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-portal.ts +8 -0
  197. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-title.ts +12 -0
  198. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover-trigger.ts +14 -0
  199. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/hlm-popover.ts +23 -0
  200. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/popover/index.ts +25 -0
  201. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-content.ts +44 -0
  202. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-group.ts +14 -0
  203. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-item.ts +36 -0
  204. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-label.ts +14 -0
  205. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-multiple.ts +37 -0
  206. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-placeholder.ts +17 -0
  207. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-portal.ts +8 -0
  208. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-scroll-down.ts +22 -0
  209. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-scroll-up.ts +22 -0
  210. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-separator.ts +14 -0
  211. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-trigger.ts +59 -0
  212. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-value-template.ts +5 -0
  213. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-value.ts +18 -0
  214. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-values-content.ts +9 -0
  215. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select-values.ts +5 -0
  216. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/hlm-select.ts +37 -0
  217. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/select/index.ts +52 -0
  218. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/separator/hlm-separator.ts +19 -0
  219. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/separator/index.ts +5 -0
  220. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/skeleton/hlm-skeleton.ts +14 -0
  221. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/skeleton/index.ts +5 -0
  222. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/spinner/hlm-spinner.ts +26 -0
  223. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/spinner/index.ts +5 -0
  224. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/utils/hlm.ts +313 -0
  225. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/utils/index.ts +2 -0
  226. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/shared/utils/provide-spartan-hlm.ts +34 -0
  227. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/app/utils/async-data.ts +99 -0
  228. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/index.html +13 -0
  229. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/main.ts +5 -0
  230. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/styles.css +139 -0
  231. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/src/types/sf-globals.d.ts +23 -0
  232. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/tsconfig.app.json +11 -0
  233. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/tsconfig.json +36 -0
  234. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/tsconfig.spec.json +10 -0
  235. package/dist/force-app/main/default/uiBundles/feature-angular-language-switcher/ui-bundle.json +7 -0
  236. package/dist/jest.config.js +6 -0
  237. package/dist/package-lock.json +12554 -0
  238. package/dist/package.json +46 -0
  239. package/dist/scripts/apex/hello.apex +10 -0
  240. package/dist/scripts/gitignore-templates.json +4 -0
  241. package/dist/scripts/graphql-search.sh +191 -0
  242. package/dist/scripts/org-setup-config-schema.mjs +132 -0
  243. package/dist/scripts/org-setup-dev.mjs +114 -0
  244. package/dist/scripts/org-setup-url.mjs +108 -0
  245. package/dist/scripts/org-setup-utils.mjs +569 -0
  246. package/dist/scripts/org-setup-xml.mjs +278 -0
  247. package/dist/scripts/org-setup.config.json +5 -0
  248. package/dist/scripts/org-setup.mjs +2537 -0
  249. package/dist/scripts/sf-project-setup.mjs +103 -0
  250. package/dist/scripts/soql/account.soql +6 -0
  251. package/dist/scripts/validate-org-setup-config.mjs +38 -0
  252. package/dist/sfdx-project.json +12 -0
  253. package/package.json +46 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { ChangeDetectionStrategy, Component, input, model, output } from '@angular/core';
7
+ import { HlmDialogImports } from '@spartan-ng/styles/dialog';
8
+
9
+ @Component({
10
+ selector: 'app-dialog',
11
+ changeDetection: ChangeDetectionStrategy.OnPush,
12
+ imports: [HlmDialogImports],
13
+ templateUrl: './dialog.html',
14
+ })
15
+ export class DialogComponent {
16
+ readonly open = model<boolean>(false);
17
+ readonly closeOnBackdrop = input<boolean>(true);
18
+ readonly ariaLabel = input<string | null>(null, { alias: 'aria-label' });
19
+ readonly ariaLabelledby = input<string | null>(null, { alias: 'aria-labelledby' });
20
+ readonly closed = output<void>();
21
+
22
+ show(): void {
23
+ this.open.set(true);
24
+ }
25
+
26
+ close(): void {
27
+ if (this.open()) {
28
+ this.open.set(false);
29
+ this.closed.emit();
30
+ }
31
+ }
32
+
33
+ protected onStateChanged(state: 'open' | 'closed'): void {
34
+ if (state === 'closed' && this.open()) {
35
+ this.close();
36
+ }
37
+ }
38
+ }
39
+
40
+ export const DialogImports = [DialogComponent] as const;
@@ -0,0 +1,20 @@
1
+ <button
2
+ [hlmDropdownMenuTrigger]="menuTpl"
3
+ [align]="align()"
4
+ [side]="side()"
5
+ type="button"
6
+ [class]="triggerClass()"
7
+ [attr.aria-label]="ariaLabel()"
8
+ >
9
+ <ng-content select="[trigger]" />
10
+ </button>
11
+ <ng-template #menuTpl>
12
+ <div
13
+ hlmDropdownMenu
14
+ appDropdownMenuInjector
15
+ #menuInjector="appDropdownMenuInjector"
16
+ [sideOffset]="sideOffset()"
17
+ >
18
+ <ng-container *ngTemplateOutlet="content().templateRef; injector: menuInjector.injector" />
19
+ </div>
20
+ </ng-template>
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { CdkMenuItem } from '@angular/cdk/menu';
7
+ import { NgTemplateOutlet } from '@angular/common';
8
+ import {
9
+ ChangeDetectionStrategy,
10
+ Component,
11
+ Directive,
12
+ inject,
13
+ Injector,
14
+ input,
15
+ TemplateRef,
16
+ contentChild,
17
+ } from '@angular/core';
18
+ import { outputFromObservable } from '@angular/core/rxjs-interop';
19
+ import type { MenuAlign, MenuSide } from '@spartan-ng/brain/core';
20
+ import {
21
+ HlmDropdownMenu,
22
+ HlmDropdownMenuItem,
23
+ HlmDropdownMenuLabel,
24
+ HlmDropdownMenuSeparator,
25
+ HlmDropdownMenuTrigger,
26
+ } from '@spartan-ng/styles/dropdown-menu';
27
+
28
+ // `appDropdownMenuItem` must be a directive (not a component) so it can be applied
29
+ // directly to the feature's own `<a>`/`<button>`, preserving native ENTER→click for
30
+ // `routerLink` and keyboard nav.
31
+ // Marker for the projected menu body. Consumers declare their items inside
32
+ // `<ng-template appDropdownMenuContent>` so the template can be rendered *inside*
33
+ // the `hlmDropdownMenu` (CdkMenu) with that element's injector — otherwise the
34
+ // items resolve DI at their declaration site and can't find `cdk-menu-stack`.
35
+ @Directive({ selector: '[appDropdownMenuContent]' })
36
+ export class DropdownMenuContentDirective {
37
+ readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);
38
+ }
39
+
40
+ // Captures the node injector of the `hlmDropdownMenu` element (which carries the
41
+ // `cdk-menu-stack` provider) so the projected content can inherit it.
42
+ @Directive({ selector: '[appDropdownMenuInjector]', exportAs: 'appDropdownMenuInjector' })
43
+ export class DropdownMenuInjectorDirective {
44
+ readonly injector = inject(Injector);
45
+ }
46
+
47
+ @Component({
48
+ selector: 'app-dropdown-menu',
49
+ changeDetection: ChangeDetectionStrategy.OnPush,
50
+ imports: [
51
+ HlmDropdownMenuTrigger,
52
+ HlmDropdownMenu,
53
+ NgTemplateOutlet,
54
+ DropdownMenuInjectorDirective,
55
+ ],
56
+ templateUrl: './dropdown-menu.html',
57
+ })
58
+ export class DropdownMenuComponent {
59
+ readonly align = input<MenuAlign>('start');
60
+ readonly side = input<MenuSide>('bottom');
61
+ readonly sideOffset = input<number>(1);
62
+ readonly triggerClass = input<string>('');
63
+ readonly ariaLabel = input<string | null>(null, { alias: 'aria-label' });
64
+
65
+ protected readonly content = contentChild.required(DropdownMenuContentDirective);
66
+ }
67
+
68
+ @Directive({
69
+ selector: 'a[appDropdownMenuItem], button[appDropdownMenuItem]',
70
+ hostDirectives: [{ directive: HlmDropdownMenuItem, inputs: ['disabled', 'variant', 'inset'] }],
71
+ })
72
+ export class DropdownMenuItemDirective {
73
+ // outputFromObservable workaround: a parent hostDirective can't re-export a host
74
+ // directive's output directly (raises NG2017), so bridge it via CdkMenuItem's observable.
75
+ readonly triggered = outputFromObservable(inject(CdkMenuItem).triggered);
76
+ }
77
+
78
+ @Component({
79
+ selector: 'app-dropdown-menu-label',
80
+ changeDetection: ChangeDetectionStrategy.OnPush,
81
+ hostDirectives: [{ directive: HlmDropdownMenuLabel, inputs: ['inset'] }],
82
+ template: '<ng-content />',
83
+ })
84
+ export class DropdownMenuLabelComponent {}
85
+
86
+ @Component({
87
+ selector: 'app-dropdown-menu-separator',
88
+ changeDetection: ChangeDetectionStrategy.OnPush,
89
+ hostDirectives: [HlmDropdownMenuSeparator],
90
+ template: '',
91
+ })
92
+ export class DropdownMenuSeparatorComponent {}
93
+
94
+ export const DropdownMenuImports = [
95
+ DropdownMenuComponent,
96
+ DropdownMenuContentDirective,
97
+ DropdownMenuItemDirective,
98
+ DropdownMenuLabelComponent,
99
+ DropdownMenuSeparatorComponent,
100
+ ] as const;
@@ -0,0 +1,15 @@
1
+ @if (label()) {
2
+ <label hlmFieldLabel [for]="htmlFor() ?? undefined">
3
+ {{ label() }}
4
+ @if (required()) {
5
+ <span aria-hidden="true" class="text-destructive">*</span>
6
+ }
7
+ </label>
8
+ }
9
+ @if (description()) {
10
+ <p hlmFieldDescription>{{ description() }}</p>
11
+ }
12
+ <ng-content />
13
+ @if (error()) {
14
+ <hlm-field-error [forceShow]="true">{{ error() }}</hlm-field-error>
15
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { booleanAttribute, ChangeDetectionStrategy, Component, input } from '@angular/core';
7
+ import { HlmField, HlmFieldImports } from '@spartan-ng/styles/field';
8
+
9
+ @Component({
10
+ selector: 'app-field',
11
+ changeDetection: ChangeDetectionStrategy.OnPush,
12
+ imports: [HlmFieldImports],
13
+ hostDirectives: [HlmField],
14
+ host: {
15
+ 'data-slot': 'field',
16
+ '[attr.data-invalid]': 'error() ? true : null',
17
+ },
18
+ templateUrl: './field.html',
19
+ })
20
+ export class FieldComponent {
21
+ readonly label = input<string>('');
22
+ readonly description = input<string>('');
23
+ readonly error = input<string | null>(null);
24
+ readonly required = input(false, { transform: booleanAttribute });
25
+ readonly htmlFor = input<string | null>(null);
26
+ }
27
+
28
+ export const FieldImports = [FieldComponent] as const;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+
7
+ /** Form-field visual treatment: `outline` = bordered (default), `fill` = borderless muted background. */
8
+ export type AppFieldAppearance = 'outline' | 'fill';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+
7
+ /** Form-field height scale: `sm` = 24px, `default` = 32px, `lg` = 40px. */
8
+ export type AppFieldSize = 'sm' | 'default' | 'lg';
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { ChangeDetectionStrategy, Component, input } from '@angular/core';
7
+ import { NgIcon, provideIcons } from '@ng-icons/core';
8
+ import {
9
+ lucideArrowDown,
10
+ lucideArrowUp,
11
+ lucideCheck,
12
+ lucideChevronDown,
13
+ lucideChevronRight,
14
+ lucideCircleAlert,
15
+ lucideFileQuestion,
16
+ lucideGlobe,
17
+ lucideListFilter,
18
+ lucideLogIn,
19
+ lucideLogOut,
20
+ lucideSearch,
21
+ lucideSearchX,
22
+ lucideUser,
23
+ lucideUserPen,
24
+ lucideUserPlus,
25
+ lucideX,
26
+ } from '@ng-icons/lucide';
27
+
28
+ export const APP_ICONS = {
29
+ error: lucideCircleAlert,
30
+ close: lucideX,
31
+ person: lucideUser,
32
+ login: lucideLogIn,
33
+ logout: lucideLogOut,
34
+ editProfile: lucideUserPen,
35
+ personAdd: lucideUserPlus,
36
+ search: lucideSearch,
37
+ filter: lucideListFilter,
38
+ chevronRight: lucideChevronRight,
39
+ chevronDown: lucideChevronDown,
40
+ arrowUp: lucideArrowUp,
41
+ arrowDown: lucideArrowDown,
42
+ noResults: lucideSearchX,
43
+ notFound: lucideFileQuestion,
44
+ globe: lucideGlobe,
45
+ check: lucideCheck,
46
+ } as const;
47
+
48
+ export type AppIconName = keyof typeof APP_ICONS;
49
+
50
+ @Component({
51
+ selector: 'app-icon',
52
+ changeDetection: ChangeDetectionStrategy.OnPush,
53
+ imports: [NgIcon],
54
+ providers: [provideIcons(APP_ICONS)],
55
+ host: {
56
+ '[class]': 'classes()',
57
+ '[attr.aria-label]': 'ariaLabel()',
58
+ '[attr.aria-hidden]': 'ariaLabel() ? null : true',
59
+ },
60
+ template: '<ng-icon [name]="name()" [size]="size()" />',
61
+ })
62
+ export class IconComponent {
63
+ readonly name = input.required<AppIconName>();
64
+ readonly size = input<string>('1rem');
65
+ readonly ariaLabel = input<string | null>(null, { alias: 'aria-label' });
66
+ // Non-size utilities (color, margin) still pass through to the host.
67
+ readonly classes = input<string>('', { alias: 'class' });
68
+ }
@@ -0,0 +1,34 @@
1
+ <div class="w-full space-y-1.5">
2
+ @if (label()) {
3
+ <label hlmLabel [for]="resolvedId()">{{ label() }}</label>
4
+ }
5
+ <hlm-input-group [class]="groupClasses()">
6
+ @if (icon(); as leadingIcon) {
7
+ <hlm-input-group-addon>
8
+ <app-icon [name]="leadingIcon" class="flex items-end" aria-hidden="true" />
9
+ </hlm-input-group-addon>
10
+ }
11
+ <input
12
+ hlmInputGroupInput
13
+ [type]="type()"
14
+ [placeholder]="placeholder()"
15
+ [disabled]="disabled()"
16
+ [id]="resolvedId()"
17
+ [attr.aria-label]="ariaLabel() || null"
18
+ [attr.aria-describedby]="describedBy()"
19
+ [attr.aria-invalid]="error() || null"
20
+ [attr.data-matches-spartan-invalid]="error() || null"
21
+ [(ngModel)]="value"
22
+ />
23
+ @if (iconEnd(); as trailingIcon) {
24
+ <hlm-input-group-addon align="inline-end">
25
+ <app-icon [name]="trailingIcon" class="flex items-end" aria-hidden="true" />
26
+ </hlm-input-group-addon>
27
+ }
28
+ </hlm-input-group>
29
+ @if (error() && errorMessage()) {
30
+ <p [id]="errorId()" class="text-sm text-destructive" role="alert" aria-live="polite">
31
+ {{ errorMessage() }}
32
+ </p>
33
+ }
34
+ </div>
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import {
7
+ ChangeDetectionStrategy,
8
+ Component,
9
+ booleanAttribute,
10
+ computed,
11
+ input,
12
+ model,
13
+ } from '@angular/core';
14
+ import { FormsModule } from '@angular/forms';
15
+ import { HlmInputGroupImports } from '@spartan-ng/styles/input-group';
16
+ import { HlmLabelImports } from '@spartan-ng/styles/label';
17
+ import type { AppFieldSize } from '../field-size';
18
+ import type { AppFieldAppearance } from '../field-appearance';
19
+ import { IconComponent, type AppIconName } from '../icon/icon';
20
+
21
+ const SIZE_CLASSES: Record<AppFieldSize, string> = {
22
+ sm: 'h-6 text-xs',
23
+ default: 'h-8',
24
+ lg: 'h-10',
25
+ };
26
+
27
+ const APPEARANCE_CLASSES: Record<AppFieldAppearance, string> = {
28
+ outline: '',
29
+ fill: 'border-transparent bg-muted',
30
+ };
31
+
32
+ @Component({
33
+ selector: 'app-input',
34
+ changeDetection: ChangeDetectionStrategy.OnPush,
35
+ imports: [FormsModule, HlmInputGroupImports, HlmLabelImports, IconComponent],
36
+ host: { class: 'block min-w-0' },
37
+ templateUrl: './input.html',
38
+ })
39
+ export class InputComponent {
40
+ readonly value = model<string>('');
41
+ readonly placeholder = input<string>('');
42
+ readonly label = input<string>('');
43
+ readonly type = input<string>('text');
44
+ readonly disabled = input(false, { transform: booleanAttribute });
45
+ readonly appearance = input<AppFieldAppearance>('outline');
46
+ readonly error = input(false, { transform: booleanAttribute });
47
+ readonly errorMessage = input<string>('');
48
+ readonly size = input<AppFieldSize>('default');
49
+ readonly id = input<string>('');
50
+ readonly ariaDescribedby = input<string>('');
51
+ // Accessible name for inputs with no visible <label> (e.g. an icon-only
52
+ // search box); harmless when a label is present.
53
+ readonly ariaLabel = input<string>('');
54
+ // Optional leading/trailing icons. When set the input renders inside an
55
+ // input-group so the icon sits inside the shared border.
56
+ readonly icon = input<AppIconName | ''>('');
57
+ readonly iconEnd = input<AppIconName | ''>('');
58
+
59
+ private static _uid = 0;
60
+ private readonly _autoId = `app-input-${InputComponent._uid++}`;
61
+ protected readonly resolvedId = computed(() => this.id() || this._autoId);
62
+ protected readonly errorId = computed(() => `${this.resolvedId()}-error`);
63
+
64
+ // Link the error message to the input via aria-describedby (merged with any
65
+ // caller-supplied ids) so screen readers announce it; null when absent.
66
+ protected readonly describedBy = computed(() => {
67
+ const ids = [this.ariaDescribedby(), this.error() && this.errorMessage() ? this.errorId() : '']
68
+ .filter(Boolean)
69
+ .join(' ');
70
+ return ids || null;
71
+ });
72
+
73
+ // Size + appearance apply to the input-group wrapper, which owns the border.
74
+ protected readonly groupClasses = computed(() =>
75
+ [SIZE_CLASSES[this.size()], APPEARANCE_CLASSES[this.appearance()]].filter(Boolean).join(' '),
76
+ );
77
+ }
78
+
79
+ export const InputImports = [InputComponent] as const;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { ChangeDetectionStrategy, Component, input } from '@angular/core';
7
+ import { HlmLabelImports } from '@spartan-ng/styles/label';
8
+
9
+ @Component({
10
+ selector: 'app-label',
11
+ changeDetection: ChangeDetectionStrategy.OnPush,
12
+ imports: [HlmLabelImports],
13
+ template: `
14
+ <label hlmLabel [for]="for() ?? undefined" class="mb-1.5 block"><ng-content /></label>
15
+ `,
16
+ })
17
+ export class LabelComponent {
18
+ readonly for = input<string | null | undefined>(undefined);
19
+ }
20
+
21
+ export const LabelImports = [LabelComponent] as const;
@@ -0,0 +1,74 @@
1
+ @if (!hidePageSize()) {
2
+ <div class="flex items-center gap-2">
3
+ <span [id]="pageSizeLabelId" class="text-muted-foreground text-nowrap">Items per page:</span>
4
+ @if (pageSizeOptions().length > 0) {
5
+ <select
6
+ class="h-8 rounded-md border border-input bg-background px-2 text-sm"
7
+ [attr.aria-labelledby]="pageSizeLabelId"
8
+ [disabled]="disabled()"
9
+ (change)="onPageSizeChange($event)"
10
+ >
11
+ @for (opt of pageSizeOptions(); track opt) {
12
+ <option [value]="opt" [selected]="opt === pageSize()">{{ opt }}</option>
13
+ }
14
+ </select>
15
+ } @else {
16
+ <span class="text-muted-foreground">{{ pageSize() }}</span>
17
+ }
18
+ </div>
19
+ }
20
+ <div class="text-muted-foreground text-nowrap">
21
+ {{ rangeLabel() }}
22
+ </div>
23
+ <nav hlmPagination class="w-auto mx-0">
24
+ <ul hlmPaginationContent>
25
+ @if (showFirstLastButtons()) {
26
+ <li hlmPaginationItem>
27
+ <button
28
+ type="button"
29
+ class="inline-flex items-center justify-center size-8 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:pointer-events-none"
30
+ [disabled]="disabled() || clampedPageIndex() === 0"
31
+ (click)="goToPage(0)"
32
+ aria-label="First page"
33
+ >
34
+ <ng-icon name="lucideChevronFirst" size="16" />
35
+ </button>
36
+ </li>
37
+ }
38
+ <li hlmPaginationItem>
39
+ <button
40
+ type="button"
41
+ class="inline-flex items-center justify-center size-8 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:pointer-events-none"
42
+ [disabled]="disabled() || clampedPageIndex() === 0"
43
+ (click)="goToPage(clampedPageIndex() - 1)"
44
+ aria-label="Previous page"
45
+ >
46
+ <ng-icon name="lucideChevronLeft" size="16" />
47
+ </button>
48
+ </li>
49
+ <li hlmPaginationItem>
50
+ <button
51
+ type="button"
52
+ class="inline-flex items-center justify-center size-8 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:pointer-events-none"
53
+ [disabled]="disabled() || clampedPageIndex() >= lastPage()"
54
+ (click)="goToPage(clampedPageIndex() + 1)"
55
+ aria-label="Next page"
56
+ >
57
+ <ng-icon name="lucideChevronRight" size="16" />
58
+ </button>
59
+ </li>
60
+ @if (showFirstLastButtons()) {
61
+ <li hlmPaginationItem>
62
+ <button
63
+ type="button"
64
+ class="inline-flex items-center justify-center size-8 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:pointer-events-none"
65
+ [disabled]="disabled() || clampedPageIndex() >= lastPage()"
66
+ (click)="goToPage(lastPage())"
67
+ aria-label="Last page"
68
+ >
69
+ <ng-icon name="lucideChevronLast" size="16" />
70
+ </button>
71
+ </li>
72
+ }
73
+ </ul>
74
+ </nav>
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import {
7
+ ChangeDetectionStrategy,
8
+ Component,
9
+ booleanAttribute,
10
+ computed,
11
+ input,
12
+ model,
13
+ output,
14
+ } from '@angular/core';
15
+ import { NgIcon, provideIcons } from '@ng-icons/core';
16
+ import {
17
+ lucideChevronFirst,
18
+ lucideChevronLast,
19
+ lucideChevronLeft,
20
+ lucideChevronRight,
21
+ } from '@ng-icons/lucide';
22
+ import { HlmPaginationImports } from '@spartan-ng/styles/pagination';
23
+ import type { PageEvent } from './types';
24
+
25
+ export type { PageEvent } from './types';
26
+
27
+ @Component({
28
+ selector: 'app-paginator',
29
+ changeDetection: ChangeDetectionStrategy.OnPush,
30
+ imports: [HlmPaginationImports, NgIcon],
31
+ providers: [
32
+ provideIcons({ lucideChevronFirst, lucideChevronLast, lucideChevronLeft, lucideChevronRight }),
33
+ ],
34
+ host: { class: 'flex items-center justify-end gap-4 text-sm' },
35
+ templateUrl: './paginator.html',
36
+ })
37
+ export class PaginatorComponent {
38
+ readonly length = input<number>(0);
39
+ readonly pageIndex = model<number>(0);
40
+ readonly pageSize = model<number>(10);
41
+ readonly pageSizeOptions = input<readonly number[]>([]);
42
+ readonly disabled = input(false, { transform: booleanAttribute });
43
+ readonly hidePageSize = input(false, { transform: booleanAttribute });
44
+ readonly showFirstLastButtons = input(false, { transform: booleanAttribute });
45
+ readonly page = output<PageEvent>();
46
+
47
+ private static _uid = 0;
48
+ // Unique so the label→select association survives multiple paginators on a page.
49
+ protected readonly pageSizeLabelId = `app-paginator-page-size-${PaginatorComponent._uid++}`;
50
+
51
+ protected readonly lastPage = computed(() =>
52
+ Math.max(0, Math.ceil(this.length() / this.pageSize()) - 1),
53
+ );
54
+
55
+ protected readonly clampedPageIndex = computed(() =>
56
+ Math.max(0, Math.min(this.pageIndex(), this.lastPage())),
57
+ );
58
+
59
+ protected readonly rangeLabel = computed(() => {
60
+ const len = this.length();
61
+ if (len === 0) return '0 of 0';
62
+ const idx = this.clampedPageIndex();
63
+ const start = idx * this.pageSize() + 1;
64
+ const end = Math.min((idx + 1) * this.pageSize(), len);
65
+ return `${start} – ${end} of ${len}`;
66
+ });
67
+
68
+ protected goToPage(index: number): void {
69
+ const previousPageIndex = this.pageIndex();
70
+ this.pageIndex.set(index);
71
+ this.page.emit({
72
+ pageIndex: index,
73
+ previousPageIndex,
74
+ pageSize: this.pageSize(),
75
+ length: this.length(),
76
+ });
77
+ }
78
+
79
+ protected onPageSizeChange(event: Event): void {
80
+ const newSize = Number((event.target as HTMLSelectElement).value);
81
+ const previousPageIndex = this.pageIndex();
82
+ this.pageSize.set(newSize);
83
+ this.pageIndex.set(0);
84
+ this.page.emit({
85
+ pageIndex: 0,
86
+ previousPageIndex,
87
+ pageSize: newSize,
88
+ length: this.length(),
89
+ });
90
+ }
91
+ }
92
+
93
+ export const PaginatorImports = [PaginatorComponent] as const;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+
7
+ /** Payload emitted by PaginatorComponent's `(page)` output. */
8
+ export interface PageEvent {
9
+ pageIndex: number;
10
+ previousPageIndex: number;
11
+ pageSize: number;
12
+ length: number;
13
+ }
@@ -0,0 +1,13 @@
1
+ <hlm-popover
2
+ [align]="align()"
3
+ [sideOffset]="sideOffset()"
4
+ [state]="open() ? 'open' : 'closed'"
5
+ (stateChanged)="onStateChanged($event)"
6
+ >
7
+ <button hlmPopoverTrigger type="button" [class]="triggerClass()" [attr.aria-label]="ariaLabel()">
8
+ <ng-content select="[trigger]" />
9
+ </button>
10
+ <div hlmPopoverContent *hlmPopoverPortal>
11
+ <ng-content />
12
+ </div>
13
+ </hlm-popover>
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { ChangeDetectionStrategy, Component, input, model } from '@angular/core';
7
+ import { HlmPopoverImports } from '@spartan-ng/styles/popover';
8
+
9
+ @Component({
10
+ selector: 'app-popover',
11
+ changeDetection: ChangeDetectionStrategy.OnPush,
12
+ imports: [HlmPopoverImports],
13
+ templateUrl: './popover.html',
14
+ })
15
+ export class PopoverComponent {
16
+ readonly open = model<boolean>(false);
17
+ readonly align = input<'start' | 'center' | 'end'>('start');
18
+ readonly sideOffset = input<number>(4);
19
+ // The wrapper owns the single real trigger `<button>` (so callers project
20
+ // plain content, never a nested button); these style/label it.
21
+ readonly triggerClass = input<string>('');
22
+ readonly ariaLabel = input<string | null>(null, { alias: 'aria-label' });
23
+
24
+ toggle(): void {
25
+ this.open.set(!this.open());
26
+ }
27
+
28
+ close(): void {
29
+ this.open.set(false);
30
+ }
31
+
32
+ protected onStateChanged(state: 'open' | 'closed'): void {
33
+ this.open.set(state === 'open');
34
+ }
35
+ }
36
+
37
+ export const PopoverImports = [PopoverComponent] as const;