@pitchfork-ui/elements 0.1.0 → 0.2.1

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 (264) hide show
  1. package/dist/cjs/control-label-C0eK8bPh.js +36 -0
  2. package/dist/cjs/control-label-C0eK8bPh.js.map +1 -0
  3. package/dist/cjs/index-CIskGKk1.js +4 -4
  4. package/dist/cjs/loader.cjs.js +1 -1
  5. package/dist/cjs/pf-checkbox.cjs.entry.js +3 -1
  6. package/dist/cjs/pf-checkbox.cjs.entry.js.map +1 -1
  7. package/dist/cjs/pf-combobox.cjs.entry.js +4 -3
  8. package/dist/cjs/pf-combobox.cjs.entry.js.map +1 -1
  9. package/dist/cjs/pf-date-picker.cjs.entry.js +3 -2
  10. package/dist/cjs/pf-date-picker.cjs.entry.js.map +1 -1
  11. package/dist/cjs/pf-date-range-picker.cjs.entry.js +6 -5
  12. package/dist/cjs/pf-date-range-picker.cjs.entry.js.map +1 -1
  13. package/dist/cjs/pf-header-navigation.cjs.entry.js +15 -3
  14. package/dist/cjs/pf-header-navigation.cjs.entry.js.map +1 -1
  15. package/dist/cjs/pf-input.cjs.entry.js +3 -1
  16. package/dist/cjs/pf-input.cjs.entry.js.map +1 -1
  17. package/dist/cjs/pf-modal.cjs.entry.js +89 -1
  18. package/dist/cjs/pf-modal.cjs.entry.js.map +1 -1
  19. package/dist/cjs/pf-multi-select.cjs.entry.js +4 -3
  20. package/dist/cjs/pf-multi-select.cjs.entry.js.map +1 -1
  21. package/dist/cjs/pf-nav-item.cjs.entry.js +29 -4
  22. package/dist/cjs/pf-nav-item.cjs.entry.js.map +1 -1
  23. package/dist/cjs/pf-number-input.cjs.entry.js +2 -1
  24. package/dist/cjs/pf-number-input.cjs.entry.js.map +1 -1
  25. package/dist/cjs/pf-select.cjs.entry.js +4 -3
  26. package/dist/cjs/pf-select.cjs.entry.js.map +1 -1
  27. package/dist/cjs/pf-sidebar-navigation.cjs.entry.js +11 -8
  28. package/dist/cjs/pf-sidebar-navigation.cjs.entry.js.map +1 -1
  29. package/dist/cjs/pf-slider.cjs.entry.js +4 -2
  30. package/dist/cjs/pf-slider.cjs.entry.js.map +1 -1
  31. package/dist/cjs/pf-switch.cjs.entry.js +3 -1
  32. package/dist/cjs/pf-switch.cjs.entry.js.map +1 -1
  33. package/dist/cjs/pf-tag-input.cjs.entry.js +3 -2
  34. package/dist/cjs/pf-tag-input.cjs.entry.js.map +1 -1
  35. package/dist/cjs/pf-textarea.cjs.entry.js +2 -1
  36. package/dist/cjs/pf-textarea.cjs.entry.js.map +1 -1
  37. package/dist/cjs/pf-time-picker.cjs.entry.js +3 -2
  38. package/dist/cjs/pf-time-picker.cjs.entry.js.map +1 -1
  39. package/dist/cjs/pitchfork.cjs.js +1 -1
  40. package/dist/collection/components/pf-accordion/pf-accordion.js +2 -2
  41. package/dist/collection/components/pf-alert/pf-alert.js +1 -1
  42. package/dist/collection/components/pf-avatar/pf-avatar.js +2 -2
  43. package/dist/collection/components/pf-badge/pf-badge.js +1 -1
  44. package/dist/collection/components/pf-badge-group/pf-badge-group.js +3 -3
  45. package/dist/collection/components/pf-button/pf-button.js +3 -3
  46. package/dist/collection/components/pf-checkbox/pf-checkbox.js +4 -1
  47. package/dist/collection/components/pf-checkbox/pf-checkbox.js.map +1 -1
  48. package/dist/collection/components/pf-combobox/pf-combobox.js +4 -3
  49. package/dist/collection/components/pf-combobox/pf-combobox.js.map +1 -1
  50. package/dist/collection/components/pf-content-divider/pf-content-divider.js +1 -1
  51. package/dist/collection/components/pf-credit-card/pf-credit-card.js +1 -1
  52. package/dist/collection/components/pf-date-picker/pf-date-picker.js +3 -2
  53. package/dist/collection/components/pf-date-picker/pf-date-picker.js.map +1 -1
  54. package/dist/collection/components/pf-date-range-picker/pf-date-range-picker.js +6 -5
  55. package/dist/collection/components/pf-date-range-picker/pf-date-range-picker.js.map +1 -1
  56. package/dist/collection/components/pf-empty-state/pf-empty-state.js +1 -1
  57. package/dist/collection/components/pf-header-navigation/pf-header-navigation.js +25 -4
  58. package/dist/collection/components/pf-header-navigation/pf-header-navigation.js.map +1 -1
  59. package/dist/collection/components/pf-inline-cta/pf-inline-cta.js +1 -1
  60. package/dist/collection/components/pf-input/pf-input.js +5 -2
  61. package/dist/collection/components/pf-input/pf-input.js.map +1 -1
  62. package/dist/collection/components/pf-kbd/pf-kbd.js +1 -1
  63. package/dist/collection/components/pf-line-chart/pf-line-chart.js +1 -1
  64. package/dist/collection/components/pf-loading-dots/pf-loading-dots.js +1 -1
  65. package/dist/collection/components/pf-metric-card/pf-metric-card.js +1 -1
  66. package/dist/collection/components/pf-modal/pf-modal.js +77 -6
  67. package/dist/collection/components/pf-modal/pf-modal.js.map +1 -1
  68. package/dist/collection/components/pf-multi-select/pf-multi-select.js +4 -3
  69. package/dist/collection/components/pf-multi-select/pf-multi-select.js.map +1 -1
  70. package/dist/collection/components/pf-nav-item/pf-nav-item.js +50 -5
  71. package/dist/collection/components/pf-nav-item/pf-nav-item.js.map +1 -1
  72. package/dist/collection/components/pf-notification/pf-notification.js +1 -1
  73. package/dist/collection/components/pf-number-input/pf-number-input.js +2 -1
  74. package/dist/collection/components/pf-number-input/pf-number-input.js.map +1 -1
  75. package/dist/collection/components/pf-progress-steps/pf-progress-steps.js +1 -1
  76. package/dist/collection/components/pf-radio-group/pf-radio-group.js +1 -1
  77. package/dist/collection/components/pf-rating-badge/pf-rating-badge.js +1 -1
  78. package/dist/collection/components/pf-scroll-area/pf-scroll-area.js +1 -1
  79. package/dist/collection/components/pf-section-header/pf-section-header.js +1 -1
  80. package/dist/collection/components/pf-select/pf-select.js +4 -3
  81. package/dist/collection/components/pf-select/pf-select.js.map +1 -1
  82. package/dist/collection/components/pf-sidebar-navigation/pf-sidebar-navigation.js +12 -9
  83. package/dist/collection/components/pf-sidebar-navigation/pf-sidebar-navigation.js.map +1 -1
  84. package/dist/collection/components/pf-slideout-menu/pf-slideout-menu.js +2 -2
  85. package/dist/collection/components/pf-slider/pf-slider.js +5 -2
  86. package/dist/collection/components/pf-slider/pf-slider.js.map +1 -1
  87. package/dist/collection/components/pf-switch/pf-switch.js +4 -1
  88. package/dist/collection/components/pf-switch/pf-switch.js.map +1 -1
  89. package/dist/collection/components/pf-tab/pf-tab.js +2 -2
  90. package/dist/collection/components/pf-table-cell/pf-table-cell.js +1 -1
  91. package/dist/collection/components/pf-tabs/pf-tabs.js +2 -2
  92. package/dist/collection/components/pf-tag/pf-tag.js +1 -1
  93. package/dist/collection/components/pf-tag-input/pf-tag-input.js +3 -2
  94. package/dist/collection/components/pf-tag-input/pf-tag-input.js.map +1 -1
  95. package/dist/collection/components/pf-textarea/pf-textarea.js +2 -1
  96. package/dist/collection/components/pf-textarea/pf-textarea.js.map +1 -1
  97. package/dist/collection/components/pf-time-picker/pf-time-picker.js +3 -2
  98. package/dist/collection/components/pf-time-picker/pf-time-picker.js.map +1 -1
  99. package/dist/collection/components/pf-timeline-item/pf-timeline-item.js +1 -1
  100. package/dist/collection/components/pf-toaster/pf-toaster.js +2 -2
  101. package/dist/collection/components/pf-toolbar/pf-toolbar.js +1 -1
  102. package/dist/collection/components/pf-toolbar-separator/pf-toolbar-separator.js +1 -1
  103. package/dist/collection/components/pf-utility-button/pf-utility-button.js +2 -2
  104. package/dist/collection/components/pf-video-player/pf-video-player.js +2 -2
  105. package/dist/collection/control-label.js +30 -0
  106. package/dist/collection/control-label.js.map +1 -0
  107. package/dist/components/p-Cy_kHPeC.js +2 -0
  108. package/dist/components/p-Cy_kHPeC.js.map +1 -0
  109. package/dist/components/pf-checkbox.js +1 -1
  110. package/dist/components/pf-checkbox.js.map +1 -1
  111. package/dist/components/pf-combobox.js +1 -1
  112. package/dist/components/pf-combobox.js.map +1 -1
  113. package/dist/components/pf-date-picker.js +1 -1
  114. package/dist/components/pf-date-picker.js.map +1 -1
  115. package/dist/components/pf-date-range-picker.js +1 -1
  116. package/dist/components/pf-date-range-picker.js.map +1 -1
  117. package/dist/components/pf-header-navigation.js +1 -1
  118. package/dist/components/pf-header-navigation.js.map +1 -1
  119. package/dist/components/pf-input.js +1 -1
  120. package/dist/components/pf-input.js.map +1 -1
  121. package/dist/components/pf-modal.js +1 -1
  122. package/dist/components/pf-modal.js.map +1 -1
  123. package/dist/components/pf-multi-select.js +1 -1
  124. package/dist/components/pf-multi-select.js.map +1 -1
  125. package/dist/components/pf-nav-item.js +1 -1
  126. package/dist/components/pf-nav-item.js.map +1 -1
  127. package/dist/components/pf-number-input.js +1 -1
  128. package/dist/components/pf-number-input.js.map +1 -1
  129. package/dist/components/pf-select.js +1 -1
  130. package/dist/components/pf-select.js.map +1 -1
  131. package/dist/components/pf-sidebar-navigation.js +1 -1
  132. package/dist/components/pf-sidebar-navigation.js.map +1 -1
  133. package/dist/components/pf-slider.js +1 -1
  134. package/dist/components/pf-slider.js.map +1 -1
  135. package/dist/components/pf-switch.js +1 -1
  136. package/dist/components/pf-switch.js.map +1 -1
  137. package/dist/components/pf-tag-input.js +1 -1
  138. package/dist/components/pf-tag-input.js.map +1 -1
  139. package/dist/components/pf-textarea.js +1 -1
  140. package/dist/components/pf-textarea.js.map +1 -1
  141. package/dist/components/pf-time-picker.js +1 -1
  142. package/dist/components/pf-time-picker.js.map +1 -1
  143. package/dist/docs.json +73 -52
  144. package/dist/elements.json +100 -10
  145. package/dist/esm/control-label-Cy_kHPeC.js +34 -0
  146. package/dist/esm/control-label-Cy_kHPeC.js.map +1 -0
  147. package/dist/esm/index-Bm6UxEit.js +4 -4
  148. package/dist/esm/loader.js +1 -1
  149. package/dist/esm/pf-checkbox.entry.js +4 -2
  150. package/dist/esm/pf-checkbox.entry.js.map +1 -1
  151. package/dist/esm/pf-combobox.entry.js +4 -3
  152. package/dist/esm/pf-combobox.entry.js.map +1 -1
  153. package/dist/esm/pf-date-picker.entry.js +3 -2
  154. package/dist/esm/pf-date-picker.entry.js.map +1 -1
  155. package/dist/esm/pf-date-range-picker.entry.js +6 -5
  156. package/dist/esm/pf-date-range-picker.entry.js.map +1 -1
  157. package/dist/esm/pf-header-navigation.entry.js +15 -3
  158. package/dist/esm/pf-header-navigation.entry.js.map +1 -1
  159. package/dist/esm/pf-input.entry.js +4 -2
  160. package/dist/esm/pf-input.entry.js.map +1 -1
  161. package/dist/esm/pf-modal.entry.js +89 -1
  162. package/dist/esm/pf-modal.entry.js.map +1 -1
  163. package/dist/esm/pf-multi-select.entry.js +4 -3
  164. package/dist/esm/pf-multi-select.entry.js.map +1 -1
  165. package/dist/esm/pf-nav-item.entry.js +30 -5
  166. package/dist/esm/pf-nav-item.entry.js.map +1 -1
  167. package/dist/esm/pf-number-input.entry.js +2 -1
  168. package/dist/esm/pf-number-input.entry.js.map +1 -1
  169. package/dist/esm/pf-select.entry.js +4 -3
  170. package/dist/esm/pf-select.entry.js.map +1 -1
  171. package/dist/esm/pf-sidebar-navigation.entry.js +11 -8
  172. package/dist/esm/pf-sidebar-navigation.entry.js.map +1 -1
  173. package/dist/esm/pf-slider.entry.js +5 -3
  174. package/dist/esm/pf-slider.entry.js.map +1 -1
  175. package/dist/esm/pf-switch.entry.js +4 -2
  176. package/dist/esm/pf-switch.entry.js.map +1 -1
  177. package/dist/esm/pf-tag-input.entry.js +3 -2
  178. package/dist/esm/pf-tag-input.entry.js.map +1 -1
  179. package/dist/esm/pf-textarea.entry.js +2 -1
  180. package/dist/esm/pf-textarea.entry.js.map +1 -1
  181. package/dist/esm/pf-time-picker.entry.js +3 -2
  182. package/dist/esm/pf-time-picker.entry.js.map +1 -1
  183. package/dist/esm/pitchfork.js +1 -1
  184. package/dist/pitchfork/p-01ed0d56.entry.js +2 -0
  185. package/dist/pitchfork/p-01ed0d56.entry.js.map +1 -0
  186. package/dist/pitchfork/p-02e28338.entry.js +2 -0
  187. package/dist/pitchfork/p-02e28338.entry.js.map +1 -0
  188. package/dist/pitchfork/p-19c0145c.entry.js +2 -0
  189. package/dist/pitchfork/p-19c0145c.entry.js.map +1 -0
  190. package/dist/pitchfork/p-22d8c69d.entry.js +2 -0
  191. package/dist/pitchfork/p-22d8c69d.entry.js.map +1 -0
  192. package/dist/pitchfork/p-2add2e98.entry.js +2 -0
  193. package/dist/pitchfork/p-2add2e98.entry.js.map +1 -0
  194. package/dist/pitchfork/p-45039de3.entry.js +2 -0
  195. package/dist/pitchfork/p-45039de3.entry.js.map +1 -0
  196. package/dist/pitchfork/p-4dfe7e8a.entry.js +2 -0
  197. package/dist/pitchfork/p-4dfe7e8a.entry.js.map +1 -0
  198. package/dist/pitchfork/p-51353d53.entry.js +2 -0
  199. package/dist/pitchfork/p-51353d53.entry.js.map +1 -0
  200. package/dist/pitchfork/p-5b98848c.entry.js +2 -0
  201. package/dist/pitchfork/{p-fd5a5ea1.entry.js.map → p-5b98848c.entry.js.map} +1 -1
  202. package/dist/pitchfork/p-7197ef71.entry.js +2 -0
  203. package/dist/pitchfork/p-7197ef71.entry.js.map +1 -0
  204. package/dist/pitchfork/p-Cy_kHPeC.js +2 -0
  205. package/dist/pitchfork/p-Cy_kHPeC.js.map +1 -0
  206. package/dist/pitchfork/p-ab6c09e7.entry.js +2 -0
  207. package/dist/pitchfork/p-ab6c09e7.entry.js.map +1 -0
  208. package/dist/pitchfork/p-d7ca4026.entry.js +2 -0
  209. package/dist/pitchfork/p-d7ca4026.entry.js.map +1 -0
  210. package/dist/pitchfork/p-dd48d94d.entry.js +2 -0
  211. package/dist/pitchfork/p-dd48d94d.entry.js.map +1 -0
  212. package/dist/pitchfork/p-ec8df806.entry.js +2 -0
  213. package/dist/pitchfork/p-ec8df806.entry.js.map +1 -0
  214. package/dist/pitchfork/p-f5df568f.entry.js +2 -0
  215. package/dist/pitchfork/p-f5df568f.entry.js.map +1 -0
  216. package/dist/pitchfork/p-f713c62d.entry.js +2 -0
  217. package/dist/pitchfork/p-f713c62d.entry.js.map +1 -0
  218. package/dist/pitchfork/p-fd802631.entry.js +2 -0
  219. package/dist/pitchfork/p-fd802631.entry.js.map +1 -0
  220. package/dist/pitchfork/pitchfork.esm.js +1 -1
  221. package/dist/types/components/pf-checkbox/pf-checkbox.d.ts +1 -0
  222. package/dist/types/components/pf-header-navigation/pf-header-navigation.d.ts +11 -2
  223. package/dist/types/components/pf-input/pf-input.d.ts +1 -0
  224. package/dist/types/components/pf-modal/pf-modal.d.ts +56 -3
  225. package/dist/types/components/pf-nav-item/pf-nav-item.d.ts +21 -1
  226. package/dist/types/components/pf-sidebar-navigation/pf-sidebar-navigation.d.ts +10 -7
  227. package/dist/types/components/pf-slider/pf-slider.d.ts +1 -0
  228. package/dist/types/components/pf-switch/pf-switch.d.ts +1 -0
  229. package/dist/types/components.d.ts +57 -18
  230. package/dist/types/control-label.d.ts +24 -0
  231. package/package.json +4 -4
  232. package/dist/pitchfork/p-1dbea97f.entry.js +0 -2
  233. package/dist/pitchfork/p-1dbea97f.entry.js.map +0 -1
  234. package/dist/pitchfork/p-23b1be9b.entry.js +0 -2
  235. package/dist/pitchfork/p-23b1be9b.entry.js.map +0 -1
  236. package/dist/pitchfork/p-33857f80.entry.js +0 -2
  237. package/dist/pitchfork/p-33857f80.entry.js.map +0 -1
  238. package/dist/pitchfork/p-47cabc33.entry.js +0 -2
  239. package/dist/pitchfork/p-47cabc33.entry.js.map +0 -1
  240. package/dist/pitchfork/p-48b2d3f7.entry.js +0 -2
  241. package/dist/pitchfork/p-48b2d3f7.entry.js.map +0 -1
  242. package/dist/pitchfork/p-5064d2dd.entry.js +0 -2
  243. package/dist/pitchfork/p-5064d2dd.entry.js.map +0 -1
  244. package/dist/pitchfork/p-52eef7eb.entry.js +0 -2
  245. package/dist/pitchfork/p-52eef7eb.entry.js.map +0 -1
  246. package/dist/pitchfork/p-845c5252.entry.js +0 -2
  247. package/dist/pitchfork/p-845c5252.entry.js.map +0 -1
  248. package/dist/pitchfork/p-a24bf2bd.entry.js +0 -2
  249. package/dist/pitchfork/p-a24bf2bd.entry.js.map +0 -1
  250. package/dist/pitchfork/p-a9b77dbb.entry.js +0 -2
  251. package/dist/pitchfork/p-a9b77dbb.entry.js.map +0 -1
  252. package/dist/pitchfork/p-c6bdd9cd.entry.js +0 -2
  253. package/dist/pitchfork/p-c6bdd9cd.entry.js.map +0 -1
  254. package/dist/pitchfork/p-d0d2070b.entry.js +0 -2
  255. package/dist/pitchfork/p-d0d2070b.entry.js.map +0 -1
  256. package/dist/pitchfork/p-d248b027.entry.js +0 -2
  257. package/dist/pitchfork/p-d248b027.entry.js.map +0 -1
  258. package/dist/pitchfork/p-d6425298.entry.js +0 -2
  259. package/dist/pitchfork/p-d6425298.entry.js.map +0 -1
  260. package/dist/pitchfork/p-d7eb6335.entry.js +0 -2
  261. package/dist/pitchfork/p-d7eb6335.entry.js.map +0 -1
  262. package/dist/pitchfork/p-e944f504.entry.js +0 -2
  263. package/dist/pitchfork/p-e944f504.entry.js.map +0 -1
  264. package/dist/pitchfork/p-fd5a5ea1.entry.js +0 -2
@@ -44,18 +44,21 @@ export declare class PfSidebarNavigation {
44
44
  componentWillLoad(): void;
45
45
  componentDidLoad(): void;
46
46
  /**
47
- * A section's own slot changed, so the items below it have moved.
47
+ * A section's items moved, or an item's `current` changed. Either way the
48
+ * resolution has to run again.
48
49
  *
49
50
  * `slotchange` is not composed, so this is the only way the navigation
50
- * hears about an item appended inside a section. The event comes from a
51
- * slotted child in the navigation's own tree, so `event.target` is the
52
- * section rather than the host — nothing is retargeted, which is what makes
53
- * a host listener safe here and not on a child in the shadow root.
51
+ * hears about an item appended inside a section — and an item's `current`
52
+ * arriving as a *property* fires no DOM event at all, which is why the item
53
+ * emits this too. The event comes from a slotted child in the navigation's
54
+ * own tree, so `event.target` is the section or the item rather than the
55
+ * host — nothing is retargeted, which is what makes a host listener safe
56
+ * here and not on a child in the shadow root.
54
57
  */
55
58
  handleStructureChange(event: CustomEvent<void>): void;
56
59
  /**
57
- * Re-reads the items, for a consumer who marked one current through its
58
- * *property* — which leaves no attribute and fires no `slotchange`.
60
+ * Re-reads the items, for a consumer who changed something the group reads
61
+ * and has no event for.
59
62
  */
60
63
  refresh(): Promise<void>;
61
64
  /**
@@ -15,6 +15,7 @@ import { EventEmitter } from '../../stencil-public-runtime';
15
15
  * @part error - the error message below the control.
16
16
  */
17
17
  export declare class PfSlider {
18
+ el: HTMLElement;
18
19
  internals: ElementInternals;
19
20
  /**
20
21
  * Submitted under this name. Reflected, because a form-associated element
@@ -12,6 +12,7 @@ import { EventEmitter } from '../../stencil-public-runtime';
12
12
  * @part label - the label element.
13
13
  */
14
14
  export declare class PfSwitch {
15
+ el: HTMLElement;
15
16
  internals: ElementInternals;
16
17
  /**
17
18
  * Submitted under this name.
@@ -1417,7 +1417,7 @@ export namespace Components {
1417
1417
  */
1418
1418
  "label": string;
1419
1419
  /**
1420
- * Re-reads the items, for a consumer who marked one current through its *property* — which leaves no attribute and fires no `slotchange`.
1420
+ * Re-reads the items, for a consumer who changed something the group reads and has no event for.
1421
1421
  */
1422
1422
  "refresh": () => Promise<void>;
1423
1423
  }
@@ -1772,9 +1772,12 @@ export namespace Components {
1772
1772
  * A modal dialog.
1773
1773
  * A native `<dialog>` opened with `showModal()`, which from inside a shadow
1774
1774
  * root gives the focus trap, Escape and the backdrop for nothing — all
1775
- * measured: focus moves inside on open and cannot be taken by a light-DOM
1776
- * button, and a real Escape fires `cancel` then `close`. So `trapFocus` from
1777
- * core is not needed here, unlike in the React component.
1775
+ * measured: focus cannot be taken by a light-DOM button, and a real Escape
1776
+ * fires `cancel` then `close`. So `trapFocus` from core is not needed here,
1777
+ * unlike in the React component.
1778
+ * The one part of `showModal()` that cannot be relied on is where it puts
1779
+ * focus, and the gap is exactly the case every framework consumer is in. See
1780
+ * `showDialog` below.
1778
1781
  * What `showModal()` does *not* do is lock page scroll — measured: a real
1779
1782
  * wheel still scrolled the page behind an open modal — so this element locks
1780
1783
  * it, exactly as the React component does.
@@ -1907,7 +1910,9 @@ export namespace Components {
1907
1910
  * `<Link>` in and leave `href` unset.
1908
1911
  * `currentPage` and `orientation` are the group's to set. A consumer asks by
1909
1912
  * setting `current`; the group resolves every item with core's rule and
1910
- * writes the answer to `currentPage`.
1913
+ * writes the answer to `currentPage`. Changing the ask tells the group, so
1914
+ * the answer follows a framework's re-render without the consumer calling
1915
+ * anything.
1911
1916
  */
1912
1917
  interface PfNavItem {
1913
1918
  /**
@@ -2827,7 +2832,7 @@ export namespace Components {
2827
2832
  */
2828
2833
  "label": string;
2829
2834
  /**
2830
- * Re-reads the items, for a consumer who marked one current through its *property* — which leaves no attribute and fires no `slotchange`.
2835
+ * Re-reads the items, for a consumer who changed something the group reads and has no event for.
2831
2836
  */
2832
2837
  "refresh": () => Promise<void>;
2833
2838
  }
@@ -3947,6 +3952,10 @@ export interface PfMultiSelectCustomEvent<T> extends CustomEvent<T> {
3947
3952
  detail: T;
3948
3953
  target: HTMLPfMultiSelectElement;
3949
3954
  }
3955
+ export interface PfNavItemCustomEvent<T> extends CustomEvent<T> {
3956
+ detail: T;
3957
+ target: HTMLPfNavItemElement;
3958
+ }
3950
3959
  export interface PfNavSectionCustomEvent<T> extends CustomEvent<T> {
3951
3960
  detail: T;
3952
3961
  target: HTMLPfNavSectionElement;
@@ -5026,9 +5035,12 @@ declare global {
5026
5035
  * A modal dialog.
5027
5036
  * A native `<dialog>` opened with `showModal()`, which from inside a shadow
5028
5037
  * root gives the focus trap, Escape and the backdrop for nothing — all
5029
- * measured: focus moves inside on open and cannot be taken by a light-DOM
5030
- * button, and a real Escape fires `cancel` then `close`. So `trapFocus` from
5031
- * core is not needed here, unlike in the React component.
5038
+ * measured: focus cannot be taken by a light-DOM button, and a real Escape
5039
+ * fires `cancel` then `close`. So `trapFocus` from core is not needed here,
5040
+ * unlike in the React component.
5041
+ * The one part of `showModal()` that cannot be relied on is where it puts
5042
+ * focus, and the gap is exactly the case every framework consumer is in. See
5043
+ * `showDialog` below.
5032
5044
  * What `showModal()` does *not* do is lock page scroll — measured: a real
5033
5045
  * wheel still scrolled the page behind an open modal — so this element locks
5034
5046
  * it, exactly as the React component does.
@@ -5115,6 +5127,9 @@ declare global {
5115
5127
  prototype: HTMLPfMultiSelectElement;
5116
5128
  new (): HTMLPfMultiSelectElement;
5117
5129
  };
5130
+ interface HTMLPfNavItemElementEventMap {
5131
+ "pfNavStructure": void;
5132
+ }
5118
5133
  /**
5119
5134
  * One item in a `pf-header-navigation` or a `pf-sidebar-navigation`.
5120
5135
  * Shared by both, because the React library's `HeaderNavigationItem` and
@@ -5127,9 +5142,19 @@ declare global {
5127
5142
  * `<Link>` in and leave `href` unset.
5128
5143
  * `currentPage` and `orientation` are the group's to set. A consumer asks by
5129
5144
  * setting `current`; the group resolves every item with core's rule and
5130
- * writes the answer to `currentPage`.
5145
+ * writes the answer to `currentPage`. Changing the ask tells the group, so
5146
+ * the answer follows a framework's re-render without the consumer calling
5147
+ * anything.
5131
5148
  */
5132
5149
  interface HTMLPfNavItemElement extends Components.PfNavItem, HTMLStencilElement {
5150
+ addEventListener<K extends keyof HTMLPfNavItemElementEventMap>(type: K, listener: (this: HTMLPfNavItemElement, ev: PfNavItemCustomEvent<HTMLPfNavItemElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
5151
+ addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
5152
+ addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
5153
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
5154
+ removeEventListener<K extends keyof HTMLPfNavItemElementEventMap>(type: K, listener: (this: HTMLPfNavItemElement, ev: PfNavItemCustomEvent<HTMLPfNavItemElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
5155
+ removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
5156
+ removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
5157
+ removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
5133
5158
  }
5134
5159
  var HTMLPfNavItemElement: {
5135
5160
  prototype: HTMLPfNavItemElement;
@@ -7987,9 +8012,12 @@ declare namespace LocalJSX {
7987
8012
  * A modal dialog.
7988
8013
  * A native `<dialog>` opened with `showModal()`, which from inside a shadow
7989
8014
  * root gives the focus trap, Escape and the backdrop for nothing — all
7990
- * measured: focus moves inside on open and cannot be taken by a light-DOM
7991
- * button, and a real Escape fires `cancel` then `close`. So `trapFocus` from
7992
- * core is not needed here, unlike in the React component.
8015
+ * measured: focus cannot be taken by a light-DOM button, and a real Escape
8016
+ * fires `cancel` then `close`. So `trapFocus` from core is not needed here,
8017
+ * unlike in the React component.
8018
+ * The one part of `showModal()` that cannot be relied on is where it puts
8019
+ * focus, and the gap is exactly the case every framework consumer is in. See
8020
+ * `showDialog` below.
7993
8021
  * What `showModal()` does *not* do is lock page scroll — measured: a real
7994
8022
  * wheel still scrolled the page behind an open modal — so this element locks
7995
8023
  * it, exactly as the React component does.
@@ -8121,7 +8149,9 @@ declare namespace LocalJSX {
8121
8149
  * `<Link>` in and leave `href` unset.
8122
8150
  * `currentPage` and `orientation` are the group's to set. A consumer asks by
8123
8151
  * setting `current`; the group resolves every item with core's rule and
8124
- * writes the answer to `currentPage`.
8152
+ * writes the answer to `currentPage`. Changing the ask tells the group, so
8153
+ * the answer follows a framework's re-render without the consumer calling
8154
+ * anything.
8125
8155
  */
8126
8156
  interface PfNavItem {
8127
8157
  /**
@@ -8143,6 +8173,10 @@ declare namespace LocalJSX {
8143
8173
  * Where the item goes. Reflected; a consumer's stylesheet reads it.
8144
8174
  */
8145
8175
  "href"?: string;
8176
+ /**
8177
+ * Tells the group the ask changed, so it can resolve again. The same event `pf-nav-section` emits when its items move, because the groups do the same thing with both: re-read every item and resolve the one current page. Without this a navigation resolves at load and never again for a consumer who marks items through the *property*, which is every framework consumer — the generated bindings set props as properties, so there is no attribute change and no `slotchange` either. The symptom is a navigation whose highlight never moves while the router works perfectly, which is what porting `apps/demo` ran into. `current` only. Watching `currentPage` would loop, since that is what the group writes back.
8178
+ */
8179
+ "onPfNavStructure"?: (event: PfNavItemCustomEvent<void>) => void;
8146
8180
  /**
8147
8181
  * Set by the group, which is the only one that knows which it is.
8148
8182
  * @default 'horizontal'
@@ -11362,9 +11396,12 @@ declare module "@stencil/core" {
11362
11396
  * A modal dialog.
11363
11397
  * A native `<dialog>` opened with `showModal()`, which from inside a shadow
11364
11398
  * root gives the focus trap, Escape and the backdrop for nothing — all
11365
- * measured: focus moves inside on open and cannot be taken by a light-DOM
11366
- * button, and a real Escape fires `cancel` then `close`. So `trapFocus` from
11367
- * core is not needed here, unlike in the React component.
11399
+ * measured: focus cannot be taken by a light-DOM button, and a real Escape
11400
+ * fires `cancel` then `close`. So `trapFocus` from core is not needed here,
11401
+ * unlike in the React component.
11402
+ * The one part of `showModal()` that cannot be relied on is where it puts
11403
+ * focus, and the gap is exactly the case every framework consumer is in. See
11404
+ * `showDialog` below.
11368
11405
  * What `showModal()` does *not* do is lock page scroll — measured: a real
11369
11406
  * wheel still scrolled the page behind an open modal — so this element locks
11370
11407
  * it, exactly as the React component does.
@@ -11418,7 +11455,9 @@ declare module "@stencil/core" {
11418
11455
  * `<Link>` in and leave `href` unset.
11419
11456
  * `currentPage` and `orientation` are the group's to set. A consumer asks by
11420
11457
  * setting `current`; the group resolves every item with core's rule and
11421
- * writes the answer to `currentPage`.
11458
+ * writes the answer to `currentPage`. Changing the ask tells the group, so
11459
+ * the answer follows a framework's re-render without the consumer calling
11460
+ * anything.
11422
11461
  */
11423
11462
  "pf-nav-item": LocalJSX.IntrinsicElements["pf-nav-item"] & JSXBase.HTMLAttributes<HTMLPfNavItemElement>;
11424
11463
  /**
@@ -0,0 +1,24 @@
1
+ /**
2
+ * How a form control here gets an accessible name when it has no visible one.
3
+ *
4
+ * Not in `@pitchfork-ui/core`: it is about the shadow boundary, which only
5
+ * this layer has.
6
+ *
7
+ * The React components extend `InputHTMLAttributes`, so
8
+ * `<Input aria-label="Search" />` lands the attribute on the real `<input>`
9
+ * and names it. An element cannot do that. `aria-label` on the host names the
10
+ * **host**, and the host is not the control -- the `<input>` lives in the
11
+ * shadow root with nothing pointing at it, so a consumer who writes the same
12
+ * thing gets a control with no accessible name at all and no warning. Measured
13
+ * against Chromium's accessibility tree: the host reports the name and the
14
+ * textbox inside it reports none.
15
+ *
16
+ * `aria-labelledby` has no answer either, for the rule this library keeps
17
+ * running into: an IDREF cannot point into a shadow root. So the text is
18
+ * copied across, which is what `pf-tooltip` does for its trigger's
19
+ * description and for the same reason.
20
+ *
21
+ * A visible `label` wins, because it is both the name and a `for` target in
22
+ * the control's own root -- the kind of reference that does resolve.
23
+ */
24
+ export declare function controlAriaLabel(host: HTMLElement, label: string | undefined): string | null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pitchfork-ui/elements",
3
- "version": "0.1.0",
4
- "description": "Framework-agnostic custom elements for Pitchfork UI \u2014 the design system as standard web components, usable from React, Angular, Vue or plain HTML.",
3
+ "version": "0.2.1",
4
+ "description": "Framework-agnostic custom elements for Pitchfork UI — the design system as standard web components, usable from React, Angular, Vue or plain HTML.",
5
5
  "license": "MIT",
6
6
  "author": "Leland Rangel",
7
7
  "homepage": "https://lelandrangel.com/pitchfork-ui/",
@@ -47,8 +47,8 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@fortawesome/free-regular-svg-icons": "^7.2.0",
50
- "@pitchfork-ui/core": "^0.1.0",
51
- "@pitchfork-ui/tokens": "^0.4.1",
50
+ "@pitchfork-ui/core": "^0.2.0",
51
+ "@pitchfork-ui/tokens": "^0.5.0",
52
52
  "@stencil/core": "^4.45.1"
53
53
  },
54
54
  "devDependencies": {
@@ -1,2 +0,0 @@
1
- import{r as e,h as a,H as t}from"./p-Bm6UxEit.js";const i=()=>`:host{display:block}:host([hidden]){display:none}:host([orientation='horizontal']){flex:0 0 auto}.link{align-items:center;background:transparent;border:0;border-radius:var(--pf-nav-item-radius, var(--radius-sm));color:var(--pf-nav-item-text);cursor:pointer;display:flex;font:inherit;gap:var(--pf-nav-item-gap, var(--space-2));min-height:var(--pf-nav-item-min-height, 32px);padding:var(--pf-nav-item-padding, 0 var(--space-2));text-decoration:none;white-space:nowrap}:host([orientation='vertical']) .link{min-height:var(--pf-nav-item-vertical-min-height, 36px);padding:var(--pf-nav-item-vertical-padding, 0 var(--space-3));width:100%}.link:hover{background:var(--pf-nav-item-hover-bg);color:var(--pf-nav-item-hover-text)}a.link:focus-visible{box-shadow:var(--pf-nav-item-focus-ring, var(--pf-focus-ring));outline:none}:host([current-page]) .link{background:var(--pf-nav-item-current-bg);color:var(--pf-nav-item-current-text);font-weight:var(--font-weight-semibold)}:host([disabled]) .link{cursor:not-allowed;opacity:var(--pf-nav-item-disabled-opacity, 0.5)}:host([disabled]) .link:hover{background:transparent;color:var(--pf-nav-item-text)}.label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}:host([orientation='horizontal']) .label{flex:0 0 auto}::slotted([slot='icon']){color:inherit;flex:0 0 auto}::slotted([slot='badge']){flex:0 0 auto}::slotted(a),::slotted(button){align-items:center;align-self:stretch;background:none;border:0;color:inherit;cursor:inherit;display:flex;flex:1 1 auto;font:inherit;margin:0;padding:0;text-decoration:none}`;const r=class{constructor(a){e(this,a)}href;target;rel;current=false;currentPage=false;disabled=false;orientation="horizontal";render(){const e=[a("slot",{key:"35769e4f7edb3524591111fd8c78eca5a6ae5e76",name:"icon"}),a("span",{key:"201e0efd80af4ec26fde67d5c90fbf47d2f8f16f",class:"label",part:"label"},a("slot",{key:"bf2ada457257d25f3a054beb41133e872585a26b"})),a("slot",{key:"c807ea3208d83e9f205392aa655a35e211c75e3e",name:"badge"})];return a(t,{key:"ad28038cf786d9c8431e1da725305cceacac5a15",role:"listitem"},this.href&&!this.disabled?a("a",{class:"link",part:"link",href:this.href,target:this.target,rel:this.rel,"aria-current":this.currentPage?"page":null},e):a("span",{class:"link",part:"link","aria-current":this.currentPage?"page":null,"aria-disabled":this.disabled?"true":null},e))}};r.style=i();export{r as pf_nav_item};
2
- //# sourceMappingURL=p-1dbea97f.entry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["pfNavItemCss","PfNavItem","href","target","rel","current","currentPage","disabled","orientation","render","content","h","key","name","class","part","Host","role","this"],"sources":["src/components/pf-nav-item/pf-nav-item.css?tag=pf-nav-item&encapsulation=shadow","src/components/pf-nav-item/pf-nav-item.tsx"],"sourcesContent":["/*\n * This element is shared by pf-header-navigation and pf-sidebar-navigation,\n * whose React counterparts have separate alias families with their own\n * values. Rather than pick one and diverge from the other, the item reads a\n * generic `--pf-nav-item-*` set that each navigation defines on itself --\n * custom properties inherit through the shadow boundary, so a slotted item\n * picks up whichever navigation it is inside, which no selector can do\n * (`:host-context` is not in Firefox). Exactly the pf-option arrangement, for\n * the same reason. There is deliberately no `:root` default: without one the\n * bridge is load-bearing, and a missing one shows up as an item with no\n * colours at all rather than as one that quietly looks right.\n */\n:host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n:host([orientation='horizontal']) {\n flex: 0 0 auto;\n}\n\n.link {\n align-items: center;\n background: transparent;\n border: 0;\n border-radius: var(--pf-nav-item-radius, var(--radius-sm));\n color: var(--pf-nav-item-text);\n cursor: pointer;\n display: flex;\n font: inherit;\n gap: var(--pf-nav-item-gap, var(--space-2));\n min-height: var(--pf-nav-item-min-height, 32px);\n padding: var(--pf-nav-item-padding, 0 var(--space-2));\n text-decoration: none;\n white-space: nowrap;\n}\n\n:host([orientation='vertical']) .link {\n min-height: var(--pf-nav-item-vertical-min-height, 36px);\n padding: var(--pf-nav-item-vertical-padding, 0 var(--space-3));\n width: 100%;\n}\n\n.link:hover {\n background: var(--pf-nav-item-hover-bg);\n color: var(--pf-nav-item-hover-text);\n}\n\na.link:focus-visible {\n box-shadow: var(--pf-nav-item-focus-ring, var(--pf-focus-ring));\n outline: none;\n}\n\n/*\n * `current-page` is the group's answer, not the consumer's `current` ask: the\n * highlight and the announcement are the same decision, so they read the same\n * attribute.\n */\n:host([current-page]) .link {\n background: var(--pf-nav-item-current-bg);\n color: var(--pf-nav-item-current-text);\n font-weight: var(--font-weight-semibold);\n}\n\n:host([disabled]) .link {\n cursor: not-allowed;\n opacity: var(--pf-nav-item-disabled-opacity, 0.5);\n}\n\n:host([disabled]) .link:hover {\n background: transparent;\n color: var(--pf-nav-item-text);\n}\n\n/* The label takes the slack so a badge sits at the far edge of a sidebar. */\n.label {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n:host([orientation='horizontal']) .label {\n flex: 0 0 auto;\n}\n\n/*\n * No wrapper around the icon and badge slots: an unassigned slot is\n * `display: contents` and generates nothing, while a wrapper around one\n * cannot be collapsed from CSS and would cost a gap in front of every label\n * with no icon.\n */\n::slotted([slot='icon']) {\n color: inherit;\n flex: 0 0 auto;\n}\n\n::slotted([slot='badge']) {\n flex: 0 0 auto;\n}\n\n/*\n * A consumer's own router link, slotted in with no `href` of ours. It fills\n * the box's content area rather than being a word inside it, and it inherits\n * every colour the box resolved, so hover and the current page look the same\n * whichever of the two is the control.\n */\n::slotted(a),\n::slotted(button) {\n align-items: center;\n align-self: stretch;\n background: none;\n border: 0;\n color: inherit;\n cursor: inherit;\n display: flex;\n flex: 1 1 auto;\n font: inherit;\n margin: 0;\n padding: 0;\n text-decoration: none;\n}\n","import { Component, h, Host, Prop } from '@stencil/core';\n\n/**\n * One item in a `pf-header-navigation` or a `pf-sidebar-navigation`.\n *\n * Shared by both, because the React library's `HeaderNavigationItem` and\n * `SidebarNavigationItem` are the same shape — one element rather than two\n * that would drift. What differs is the layout, and that is the group's to\n * say: it pushes `orientation` down, which is the only thing an item cannot\n * work out for itself.\n *\n * With an `href` it renders a link; without one it renders a plain box, which\n * is how a framework's own router is used — slot an `<a routerLink>` or a\n * `<Link>` in and leave `href` unset.\n *\n * `currentPage` and `orientation` are the group's to set. A consumer asks by\n * setting `current`; the group resolves every item with core's rule and\n * writes the answer to `currentPage`.\n *\n * @slot - the item's label.\n * @slot icon - a leading icon.\n * @slot badge - a trailing badge or count.\n * @part link - the link, or the box standing in for one.\n */\n@Component({\n tag: 'pf-nav-item',\n styleUrl: 'pf-nav-item.css',\n shadow: true,\n})\nexport class PfNavItem {\n /** Where the item goes. Reflected; a consumer's stylesheet reads it. */\n @Prop({ reflect: true }) href?: string;\n\n /** Opens elsewhere, as on a plain anchor. Ignored without an `href`. */\n @Prop() target?: string;\n\n /** Goes on the anchor as-is. Ignored without an `href`. */\n @Prop() rel?: string;\n\n /**\n * Set it to mark this item as the current page.\n *\n * The *asking* half, which the group never writes — `currentPage` below is\n * the answer. The two are kept apart for the reason `pf-breadcrumb` keeps\n * them apart: a group that wrote its answer back would leave the mark\n * behind on an item the consumer had not marked.\n */\n @Prop({ reflect: true }) current = false;\n\n /**\n * Set by the group: the resolved current page, which is the one thing that\n * renders `aria-current=\"page\"`. At most one item in a navigation carries\n * it, and the highlight follows it rather than `current` — a second\n * highlighted item with no `aria-current` would be a sighted-only lie.\n */\n @Prop({ mutable: true, reflect: true }) currentPage = false;\n\n /**\n * Takes the item out of the navigation without removing it.\n *\n * A disabled item renders **no anchor at all**, because an anchor has no\n * disabled state: `aria-disabled` alone leaves it focusable and clickable,\n * and dropping the `href` is the only thing that really takes it out of the\n * tab order.\n */\n @Prop({ reflect: true }) disabled = false;\n\n /** Set by the group, which is the only one that knows which it is. */\n @Prop({ mutable: true, reflect: true }) orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n render() {\n const content = [\n <slot name=\"icon\" />,\n <span class=\"label\" part=\"label\">\n <slot />\n </span>,\n <slot name=\"badge\" />,\n ];\n\n return (\n <Host role=\"listitem\">\n {this.href && !this.disabled ? (\n <a\n class=\"link\"\n part=\"link\"\n href={this.href}\n target={this.target}\n rel={this.rel}\n aria-current={this.currentPage ? 'page' : null}\n >\n {content}\n </a>\n ) : (\n <span\n class=\"link\"\n part=\"link\"\n aria-current={this.currentPage ? 'page' : null}\n aria-disabled={this.disabled ? 'true' : null}\n >\n {content}\n </span>\n )}\n </Host>\n );\n }\n}\n"],"mappings":"kDAAA,MAAMA,EAAe,IAAM,6hD,MC6BdC,EAAS,M,yBAEKC,KAGjBC,OAGAC,IAUiBC,QAAU,MAQKC,YAAc,MAU7BC,SAAW,MAGIC,YAAyC,aAEjF,MAAAC,GACE,MAAMC,EAAU,CACdC,EAAA,QAAAC,IAAA,2CAAMC,KAAK,SACXF,EAAA,QAAAC,IAAA,2CAAME,MAAM,QAAQC,KAAK,SACvBJ,EAAA,QAAAC,IAAA,8CAEFD,EAAA,QAAAC,IAAA,2CAAMC,KAAK,WAGb,OACEF,EAACK,EAAI,CAAAJ,IAAA,2CAACK,KAAK,YACRC,KAAKhB,OAASgB,KAAKX,SAClBI,EAAA,KACEG,MAAM,OACNC,KAAK,OACLb,KAAMgB,KAAKhB,KACXC,OAAQe,KAAKf,OACbC,IAAKc,KAAKd,IAAG,eACCc,KAAKZ,YAAc,OAAS,MAEzCI,GAGHC,EAAA,QACEG,MAAM,OACNC,KAAK,OAAM,eACGG,KAAKZ,YAAc,OAAS,KAAI,gBAC/BY,KAAKX,SAAW,OAAS,MAEvCG,G","ignoreList":[]}
@@ -1,2 +0,0 @@
1
- import{r as t,c as i,a as s,h as e,H as a}from"./p-Bm6UxEit.js";import{c as r}from"./p-DfpCerXM.js";import{K as o}from"./p-g4FlTDZx.js";import{p as n,f as c,c as l,r as d,s as p}from"./p-BmcsJLdy.js";import{a as f}from"./p-Cr6IXrUk.js";const h=()=>`:host{display:block}:host([hidden]){display:none}.field{display:grid;gap:var(--space-1)}.label{color:var(--pf-taginput-text);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium)}.required{color:var(--pf-taginput-invalid-border);margin-inline-start:var(--space-1)}.control{align-items:center;background:var(--pf-taginput-bg);border:1px solid var(--pf-taginput-border);border-radius:var(--radius-md);display:flex;flex-wrap:wrap;gap:var(--space-1);padding:var(--space-1) var(--space-2)}.control:focus-within{border-color:var(--pf-taginput-focus-border);box-shadow:var(--pf-focus-ring)}.control--invalid{border-color:var(--pf-taginput-invalid-border)}.input{background:none;border:0;color:var(--pf-taginput-text);flex:1 1 6ch;font-family:inherit;font-size:var(--font-size-sm);min-width:6ch;outline:none;padding:var(--space-1)}.input::placeholder{color:var(--pf-taginput-placeholder)}.input:disabled{cursor:not-allowed}.description{color:var(--pf-taginput-placeholder);font-size:var(--font-size-xs);margin:0}.error{color:var(--pf-taginput-invalid-border);font-size:var(--font-size-xs);margin:0}`;const u=class{constructor(s){t(this,s);this.pfChange=i(this,"pfChange");if(s.$hostElement$["s-ei"]){this.internals=s.$hostElement$["s-ei"]}else{this.internals=s.$hostElement$.attachInternals();s.$hostElement$["s-ei"]=this.internals}}get el(){return s(this)}internals;name;value="";label;description;error;placeholder="Add a tag…";max;allowDuplicates=false;tagVariant="neutral";required=false;disabled=false;validate;pfChange;initialValue="";componentWillLoad(){this.initialValue=this.value??"";this.syncFormState()}syncFormState(){const t=this.tags();if(t.length===0||!this.name){this.internals.setFormValue(null)}else{const i=new FormData;for(const s of t)i.append(this.name,s);this.internals.setFormValue(i)}f(this.internals,t.length>0,this.required,this.error)}async checkValidity(){return this.internals.checkValidity()}async reportValidity(){return this.internals.reportValidity()}async getValidationMessage(){return this.internals.validationMessage}formResetCallback(){this.value=this.initialValue;const t=this.input;if(t)t.value=""}tags(){return n(this.value)}get input(){return this.el.shadowRoot?.querySelector('[part="input"]')??null}get options(){return{max:this.max,allowDuplicates:this.allowDuplicates,validate:this.validate}}commit(t){this.value=c(t);this.pfChange.emit({value:this.value,values:t})}addDraft(t){const i=l(this.tags(),t,this.options);const s=this.input;if(i.added){this.commit(i.tags);if(s)s.value="";return}if(i.refusal==="duplicate"&&s)s.value=""}remove(t){if(this.disabled)return;this.commit(d(this.tags(),t));this.input?.focus()}onKeyDown=t=>{if(this.disabled)return;const i=t.target;if(t.key===o.Enter||t.key===","){if(i.value.trim()){t.preventDefault();this.addDraft(i.value)}else if(t.key!==o.Enter){t.preventDefault()}return}if(t.key==="Backspace"&&i.value===""&&this.tags().length>0){t.preventDefault();this.remove(this.tags().length-1)}};onPaste=t=>{if(this.disabled)return;const i=p(t.clipboardData?.getData("text")??"");if(i.length===0)return;t.preventDefault();let s=this.tags();for(const t of i)s=l(s,t,this.options).tags;this.commit(s);const e=this.input;if(e)e.value=""};render(){const t=r(this.description&&"description",this.error&&"error");const i=this.tags();const s=this.max!==undefined&&i.length>=this.max;return e(a,{key:"57924b0d046c1abc64450b0a70b3ed6edfbdf9f4"},e("div",{key:"08d98d4400774b3e90881cafdf70580fcf79cce2",class:"field",part:"field"},this.label&&e("label",{key:"4964890c0aefbd1a81af8344d3a74c8ab32dde37",class:"label",part:"label",htmlFor:"input"},this.label,this.required&&e("span",{key:"921369e87d6cc0af07bdc791defb816207cc3dc0",class:"required","aria-hidden":"true"},"*")),e("div",{key:"ec4d7fad20d686473bc9c5f56c9b0c0f69b5f0f5",class:{control:true,"control--invalid":Boolean(this.error)},part:"control"},i.map(((t,i)=>e("pf-tag",{key:t,part:"tag",variant:this.tagVariant,dismissible:!this.disabled,dismissLabel:`Remove ${t}`,onPfDismiss:()=>this.remove(i)},t))),e("input",{key:"1e065f32bb9e13cac1dcfa29c03e516aa5d785bb",id:"input",part:"input",class:"input",type:"text",autocomplete:"off",disabled:this.disabled||s,required:this.required&&i.length===0,placeholder:s?"":this.placeholder,"aria-invalid":this.error?"true":null,"aria-describedby":t,onKeyDown:this.onKeyDown,onPaste:this.onPaste,onBlur:t=>{const i=t.target;if(i.value.trim())this.addDraft(i.value)}})),this.description&&e("p",{key:"96700116a9bf9d23869c48bc1f0f1c23229a0813",class:"description",part:"description",id:"description"},this.description),this.error&&e("p",{key:"d846511a00c7e03a4fb5b8be25b01723c742e912",class:"error",part:"error",id:"error"},this.error)))}static get formAssociated(){return true}static get watchers(){return{name:[{syncFormState:0}],value:[{syncFormState:0}],error:[{syncFormState:0}],required:[{syncFormState:0}]}}};u.style=h();export{u as pf_tag_input};
2
- //# sourceMappingURL=p-23b1be9b.entry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["pfTagInputCss","PfTagInput","internals","name","value","label","description","error","placeholder","max","allowDuplicates","tagVariant","required","disabled","validate","pfChange","initialValue","componentWillLoad","this","syncFormState","tags","length","setFormValue","data","FormData","tag","append","applyControlValidity","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","field","input","parseValueList","el","shadowRoot","querySelector","options","commit","formatValueList","emit","values","addDraft","raw","result","addTag","added","refusal","remove","index","removeTagAt","focus","onKeyDown","event","target","key","Keys","Enter","trim","preventDefault","onPaste","pasted","splitPastedTags","clipboardData","getData","next","candidate","render","describedBy","composeDescribedBy","atMax","undefined","h","Host","class","part","htmlFor","control","Boolean","map","variant","dismissible","dismissLabel","onPfDismiss","id","type","autocomplete","onBlur"],"sources":["src/components/pf-tag-input/pf-tag-input.css?tag=pf-tag-input&encapsulation=shadow","src/components/pf-tag-input/pf-tag-input.tsx"],"sourcesContent":[":host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-1);\n}\n\n.label {\n color: var(--pf-taginput-text);\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-taginput-invalid-border);\n margin-inline-start: var(--space-1);\n}\n\n/*\n * The chips and the draft field share one box that looks like a single input,\n * so clicking anywhere in it lands on the field.\n */\n.control {\n align-items: center;\n background: var(--pf-taginput-bg);\n border: 1px solid var(--pf-taginput-border);\n border-radius: var(--radius-md);\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-1);\n padding: var(--space-1) var(--space-2);\n}\n\n.control:focus-within {\n border-color: var(--pf-taginput-focus-border);\n box-shadow: var(--pf-focus-ring);\n}\n\n.control--invalid {\n border-color: var(--pf-taginput-invalid-border);\n}\n\n.input {\n background: none;\n border: 0;\n color: var(--pf-taginput-text);\n /* Grows to fill the row's remainder, but never forces the box wider. */\n flex: 1 1 6ch;\n font-family: inherit;\n font-size: var(--font-size-sm);\n min-width: 6ch;\n outline: none;\n padding: var(--space-1);\n}\n\n.input::placeholder {\n color: var(--pf-taginput-placeholder);\n}\n\n.input:disabled {\n cursor: not-allowed;\n}\n\n.description {\n color: var(--pf-taginput-placeholder);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n\n.error {\n color: var(--pf-taginput-invalid-border);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n","import {\n addTag,\n composeDescribedBy,\n formatValueList,\n Keys,\n parseValueList,\n removeTagAt,\n splitPastedTags,\n} from '@pitchfork-ui/core';\n\nimport { applyControlValidity } from '../../form-validity';\nimport type { PfTagVariant } from '../pf-tag/pf-tag';\nimport {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n Watch,\n} from '@stencil/core';\n\n/**\n * A form-associated field that collects free-text tags.\n *\n * Unlike the other multi-value controls here the tags are not chosen from a\n * list, so there are no `pf-option` children — the chips are `pf-tag`\n * elements this component renders, and `pf-tag` already has the dismiss\n * button and the event for it.\n *\n * The rules are core's: trimming, the case-insensitive dedup (`React` and\n * `react` are one tag), the maximum, and `validate`. So is the paste split.\n * What stays here is what to do with the draft, which differs per refusal — a\n * duplicate clears it, because the tag asked for is already there, while\n * hitting the maximum leaves it so nothing is lost.\n *\n * Submits one entry per tag under one name, the same way `pf-multi-select`\n * does.\n *\n * @slot - nothing; the chips are rendered from `value`.\n * @part field - the wrapper around label, control and messages.\n * @part label - the label element.\n * @part control - the box holding the chips and the draft input.\n * @part tag - each chip.\n * @part input - the draft input.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-tag-input',\n styleUrl: 'pf-tag-input.css',\n formAssociated: true,\n shadow: true,\n})\nexport class PfTagInput {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n /** Submitted under this name, once per tag. Reflected. */\n @Prop({ reflect: true }) name?: string;\n\n /** The tags, comma-separated. Reflected, so HTML can set it. */\n @Prop({ mutable: true, reflect: true }) value = '';\n\n @Prop() label?: string;\n\n @Prop() description?: string;\n\n @Prop() error?: string;\n\n @Prop() placeholder = 'Add a tag…';\n\n /** Stop accepting tags once there are this many. */\n @Prop() max?: number;\n\n /** Accept the same tag twice. The comparison is case-insensitive. */\n @Prop() allowDuplicates = false;\n\n /**\n * Visual variant for the chips, passed through to `pf-tag`.\n *\n * The type is imported from `pf-tag` rather than restated, so the two\n * cannot drift apart — a second copy of the union would compile happily\n * while offering a variant `pf-tag` has never heard of.\n */\n @Prop() tagVariant: PfTagVariant = 'neutral';\n\n @Prop({ reflect: true }) required = false;\n\n @Prop({ reflect: true }) disabled = false;\n\n /**\n * Refuse a candidate tag. A property rather than an attribute, because a\n * function cannot be written in HTML — the generated bindings set props as\n * properties, so a framework consumer passes it like any other.\n */\n @Prop() validate?: (tag: string) => boolean;\n\n /** Fires when the tags change, with both representations. */\n @Event() pfChange!: EventEmitter<{ value: string; values: string[] }>;\n\n private initialValue = '';\n\n componentWillLoad() {\n this.initialValue = this.value ?? '';\n this.syncFormState();\n }\n\n /** See pf-multi-select: the name is built into the FormData, so watch it. */\n @Watch('name')\n @Watch('value')\n @Watch('error')\n @Watch('required')\n syncFormState() {\n const tags = this.tags();\n\n if (tags.length === 0 || !this.name) {\n this.internals.setFormValue(null);\n } else {\n const data = new FormData();\n for (const tag of tags) data.append(this.name, tag);\n this.internals.setFormValue(data);\n }\n\n applyControlValidity(this.internals, tags.length > 0, this.required, this.error);\n }\n\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n formResetCallback() {\n this.value = this.initialValue;\n const field = this.input;\n if (field) field.value = '';\n }\n\n private tags(): string[] {\n return parseValueList(this.value);\n }\n\n private get input() {\n return this.el.shadowRoot?.querySelector<HTMLInputElement>('[part=\"input\"]') ?? null;\n }\n\n private get options() {\n return { max: this.max, allowDuplicates: this.allowDuplicates, validate: this.validate };\n }\n\n private commit(tags: string[]) {\n this.value = formatValueList(tags);\n this.pfChange.emit({ value: this.value, values: tags });\n }\n\n /** Takes the draft as a tag, and decides what to do with the draft itself. */\n private addDraft(raw: string) {\n const result = addTag(this.tags(), raw, this.options);\n const field = this.input;\n\n if (result.added) {\n this.commit(result.tags);\n if (field) field.value = '';\n return;\n }\n\n // Only a duplicate consumes the draft; `max` leaves it so nothing is lost.\n if (result.refusal === 'duplicate' && field) field.value = '';\n }\n\n private remove(index: number) {\n if (this.disabled) return;\n this.commit(removeTagAt(this.tags(), index));\n this.input?.focus();\n }\n\n /**\n * Enter and comma commit; Backspace on an empty draft removes the last tag,\n * which is the gesture every tag field has.\n */\n private onKeyDown = (event: KeyboardEvent) => {\n if (this.disabled) return;\n const field = event.target as HTMLInputElement;\n\n if (event.key === Keys.Enter || event.key === ',') {\n // A bare comma with nothing typed is swallowed rather than committing an\n // empty tag; Enter is left alone so a form can still be submitted.\n if (field.value.trim()) {\n event.preventDefault();\n this.addDraft(field.value);\n } else if (event.key !== Keys.Enter) {\n event.preventDefault();\n }\n return;\n }\n\n if (event.key === 'Backspace' && field.value === '' && this.tags().length > 0) {\n event.preventDefault();\n this.remove(this.tags().length - 1);\n }\n };\n\n /**\n * A pasted list is folded, not added one at a time, so the maximum and the\n * dedup see each addition. The React component added them in a loop over\n * stale state and kept only the last — fixed there too, in the same change.\n */\n private onPaste = (event: ClipboardEvent) => {\n if (this.disabled) return;\n const pasted = splitPastedTags(event.clipboardData?.getData('text') ?? '');\n if (pasted.length === 0) return;\n\n event.preventDefault();\n let next = this.tags();\n for (const candidate of pasted) next = addTag(next, candidate, this.options).tags;\n\n this.commit(next);\n const field = this.input;\n if (field) field.value = '';\n };\n\n render() {\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n const tags = this.tags();\n const atMax = this.max !== undefined && tags.length >= this.max;\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {this.label && (\n <label class=\"label\" part=\"label\" htmlFor=\"input\">\n {this.label}\n {this.required && (\n <span class=\"required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div class={{ control: true, 'control--invalid': Boolean(this.error) }} part=\"control\">\n {tags.map((tag, index) => (\n <pf-tag\n key={tag}\n part=\"tag\"\n variant={this.tagVariant}\n dismissible={!this.disabled}\n dismissLabel={`Remove ${tag}`}\n onPfDismiss={() => this.remove(index)}\n >\n {tag}\n </pf-tag>\n ))}\n\n <input\n id=\"input\"\n part=\"input\"\n class=\"input\"\n type=\"text\"\n autocomplete=\"off\"\n disabled={this.disabled || atMax}\n required={this.required && tags.length === 0}\n placeholder={atMax ? '' : this.placeholder}\n aria-invalid={this.error ? 'true' : null}\n aria-describedby={describedBy}\n onKeyDown={this.onKeyDown}\n onPaste={this.onPaste}\n onBlur={(event) => {\n // Commit on blur, so a typed tag is not lost by clicking away.\n const field = event.target as HTMLInputElement;\n if (field.value.trim()) this.addDraft(field.value);\n }}\n />\n </div>\n\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,2 +0,0 @@
1
- import{r as e,c as t,a as i,h as r,H as n}from"./p-Bm6UxEit.js";import{c as s}from"./p-DfpCerXM.js";import{K as a}from"./p-g4FlTDZx.js";import{p as o,r as l,s as d,f as c,c as p}from"./p-DSXauhXX.js";import{a as u}from"./p-Cr6IXrUk.js";const f=()=>`:host{display:block}:host([hidden]){display:none}.field{display:grid;gap:var(--space-2)}.label{color:var(--pf-numberinput-field-label, var(--pf-field-label));font-size:var(--font-size-sm);font-weight:var(--font-weight-medium)}.required{color:var(--pf-field-required);margin-inline-start:var(--space-1)}.control{align-items:stretch;background:var(--pf-numberinput-bg);border:1px solid var(--pf-numberinput-border);border-radius:var(--radius-md);display:inline-flex;min-height:40px;overflow:hidden;transition:border var(--pf-transition-fast), box-shadow var(--pf-transition-fast);width:100%}.control:focus-within{border-color:var(--pf-numberinput-focus-border);box-shadow:var(--pf-numberinput-focus-ring, var(--pf-focus-ring))}.control--invalid{border-color:var(--pf-numberinput-invalid-border)}:host([disabled]) .control{background:var(--pf-control-bg-disabled);border-color:var(--pf-control-border-disabled);color:var(--pf-control-text-disabled);opacity:0.6}.input{background:transparent;border:none;color:var(--pf-numberinput-text);flex:1;font:inherit;min-width:0;outline:none;padding:0 var(--space-3);text-align:center;width:100%}.input::placeholder{color:var(--pf-numberinput-placeholder)}.input:disabled{cursor:not-allowed}.step{align-items:center;align-self:stretch;background:var(--pf-numberinput-step-bg);border:none;color:var(--pf-numberinput-step-text);cursor:pointer;display:inline-flex;flex-shrink:0;justify-content:center;padding:0;transition:background var(--pf-transition-fast), color var(--pf-transition-fast);width:40px}.step:hover:not(:disabled){background:var(--pf-numberinput-step-hover-bg);color:var(--pf-numberinput-step-hover-text)}.step:disabled{cursor:not-allowed;opacity:0.45}[part='decrement']{border-inline-end:1px solid var(--pf-numberinput-border)}[part='increment']{border-inline-start:1px solid var(--pf-numberinput-border)}.step pf-icon{font-size:16px}.description{color:var(--pf-numberinput-field-description, var(--pf-field-description));font-size:var(--font-size-sm);margin:0}.error{color:var(--pf-field-error);font-size:var(--font-size-sm);margin:0}@media (prefers-reduced-motion: reduce){.control,.step{transition:none}}`;const h=class{constructor(i){e(this,i);this.pfChange=t(this,"pfChange");if(i.$hostElement$["s-ei"]){this.internals=i.$hostElement$["s-ei"]}else{this.internals=i.$hostElement$.attachInternals();i.$hostElement$["s-ei"]=this.internals}}get el(){return i(this)}internals;name;value="";min;max;step=1;label;description;error;placeholder;required=false;disabled=false;decrementLabel="Decrease";incrementLabel="Increase";pfChange;draft=null;initialValue="";componentWillLoad(){this.initialValue=this.value??"";this.syncFormState()}syncFormState(){this.internals.setFormValue(this.value??"");u(this.internals,Boolean(this.value),this.required,this.error)}async checkValidity(){return this.internals.checkValidity()}async reportValidity(){return this.internals.reportValidity()}async getValidationMessage(){return this.internals.validationMessage}formResetCallback(){this.value=this.initialValue;this.draft=null}async stepBy(e){this.step_(e)}get bounds(){return{min:this.min===undefined?-Infinity:Number(this.min),max:this.max===undefined?Infinity:Number(this.max),step:Number(this.step)||1}}get current(){return o(this.value)}get atMin(){const{min:e}=this.bounds;return this.current!==null&&this.current<=e}get atMax(){const{max:e}=this.bounds;return this.current!==null&&this.current>=e}commit(e){const{min:t,max:i,step:r}=this.bounds;const n=e===null?"":String(l(p(e,t,i),r));if(n===this.value)return;this.value=n;this.pfChange.emit({value:n,number:o(n)})}step_(e){if(this.disabled)return;this.draft=null;this.commit(d(this.current,e,this.bounds))}onInput=e=>{const t=e.target.value;this.draft=t;const i=o(t);if(t.trim()===""){this.commit(null);return}if(i!==null)this.commit(i)};onBlur=()=>{this.draft=null};onKeyDown=e=>{if(this.disabled)return;const{min:t,max:i}=this.bounds;if(e.key===a.ArrowUp){e.preventDefault();this.step_(1)}else if(e.key===a.ArrowDown){e.preventDefault();this.step_(-1)}else if(e.key===a.Home&&Number.isFinite(t)){e.preventDefault();this.draft=null;this.commit(t)}else if(e.key===a.End&&Number.isFinite(i)){e.preventDefault();this.draft=null;this.commit(i)}};render(){const e=s(this.description&&"description",this.error&&"error");const{min:t,max:i}=this.bounds;const a=this.draft??c(this.current);return r(n,{key:"b873ad5d26191b9589a3f67432f911f57a3db2cc"},r("div",{key:"1fe3503ee61589e6cd9ebe683c937665b934fc8e",class:"field",part:"field"},this.label&&r("label",{key:"7d9da068ca611a068b89e5292238852f2d40ba53",class:"label",part:"label",htmlFor:"input"},this.label,this.required&&r("span",{key:"bfb6e221092438b3ccef19dfe811767f4d2f3a5d",class:"required","aria-hidden":"true"},"*")),r("div",{key:"7bb8c35312b4d30e1b09fefa78f752c6791a34f9",class:{control:true,"control--invalid":Boolean(this.error)},part:"control"},r("button",{key:"ff991dc6a65ca1fc5984e5b260b7b9c77def5d49",type:"button",class:"step",part:"decrement","aria-label":this.decrementLabel,disabled:this.disabled||this.atMin,tabindex:"-1",onMouseDown:e=>e.preventDefault(),onClick:()=>this.step_(-1)},r("pf-icon",{key:"4d65e8eda2958a1e9a7308a3b23f2f3bcf9083cf",name:"minus","aria-hidden":"true"})),r("input",{key:"4a7db9fb97f9cdf12c4228ff47079f2cecadf7d8",id:"input",part:"input",class:"input",type:"text",inputMode:"decimal",role:"spinbutton",name:this.name,value:a,placeholder:this.placeholder,required:this.required,disabled:this.disabled,autocomplete:"off","aria-invalid":this.error?"true":null,"aria-describedby":e,"aria-valuenow":this.current??null,"aria-valuemin":Number.isFinite(t)?t:null,"aria-valuemax":Number.isFinite(i)?i:null,onInput:this.onInput,onBlur:this.onBlur,onKeyDown:this.onKeyDown}),r("button",{key:"436e0a6557aef36b2bd59b7f0cee8d0a08636c53",type:"button",class:"step",part:"increment","aria-label":this.incrementLabel,disabled:this.disabled||this.atMax,tabindex:"-1",onMouseDown:e=>e.preventDefault(),onClick:()=>this.step_(1)},r("pf-icon",{key:"0ae5162f3d63f69c135cc9991c9d02aaf3ac86ea",name:"plus","aria-hidden":"true"}))),this.description&&r("p",{key:"6c958dd2bdeb22310d6c422d1757f4938687513c",class:"description",part:"description",id:"description"},this.description),this.error&&r("p",{key:"f8ea4d36f4941251e63cdfdc127fd08d3bb55ae4",class:"error",part:"error",id:"error"},this.error)))}static get delegatesFocus(){return true}static get formAssociated(){return true}static get watchers(){return{value:[{syncFormState:0}],error:[{syncFormState:0}],required:[{syncFormState:0}]}}};h.style=f();export{h as pf_number_input};
2
- //# sourceMappingURL=p-33857f80.entry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["pfNumberInputCss","PfNumberInput","internals","name","value","min","max","step","label","description","error","placeholder","required","disabled","decrementLabel","incrementLabel","pfChange","draft","initialValue","componentWillLoad","this","syncFormState","setFormValue","applyControlValidity","Boolean","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","stepBy","direction","step_","bounds","undefined","Infinity","Number","current","parseNumberValue","atMin","atMax","commit","next","String","roundToStep","clampNumber","emit","number","stepNumber","onInput","event","raw","target","parsed","trim","onBlur","onKeyDown","key","Keys","ArrowUp","preventDefault","ArrowDown","Home","isFinite","End","render","describedBy","composeDescribedBy","shown","formatNumberValue","h","Host","class","part","htmlFor","control","type","tabindex","onMouseDown","onClick","id","inputMode","role","autocomplete"],"sources":["src/components/pf-number-input/pf-number-input.css?tag=pf-number-input&encapsulation=shadow","src/components/pf-number-input/pf-number-input.tsx"],"sourcesContent":[":host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-2);\n}\n\n.label {\n color: var(--pf-numberinput-field-label, var(--pf-field-label));\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-field-required);\n margin-inline-start: var(--space-1);\n}\n\n.control {\n align-items: stretch;\n background: var(--pf-numberinput-bg);\n border: 1px solid var(--pf-numberinput-border);\n border-radius: var(--radius-md);\n display: inline-flex;\n min-height: 40px;\n overflow: hidden;\n transition:\n border var(--pf-transition-fast),\n box-shadow var(--pf-transition-fast);\n width: 100%;\n}\n\n.control:focus-within {\n border-color: var(--pf-numberinput-focus-border);\n box-shadow: var(--pf-numberinput-focus-ring, var(--pf-focus-ring));\n}\n\n.control--invalid {\n border-color: var(--pf-numberinput-invalid-border);\n}\n\n/*\n * `:host([disabled])` rather than the React component's\n * `:has(.input:disabled)`: the host carries the reflected attribute, which is\n * both simpler and the thing a consumer's own stylesheet can see.\n */\n:host([disabled]) .control {\n background: var(--pf-control-bg-disabled);\n border-color: var(--pf-control-border-disabled);\n color: var(--pf-control-text-disabled);\n opacity: 0.6;\n}\n\n.input {\n background: transparent;\n border: none;\n color: var(--pf-numberinput-text);\n flex: 1;\n font: inherit;\n min-width: 0;\n outline: none;\n padding: 0 var(--space-3);\n text-align: center;\n width: 100%;\n}\n\n.input::placeholder {\n color: var(--pf-numberinput-placeholder);\n}\n\n.input:disabled {\n cursor: not-allowed;\n}\n\n.step {\n align-items: center;\n align-self: stretch;\n background: var(--pf-numberinput-step-bg);\n border: none;\n color: var(--pf-numberinput-step-text);\n cursor: pointer;\n display: inline-flex;\n flex-shrink: 0;\n justify-content: center;\n padding: 0;\n transition:\n background var(--pf-transition-fast),\n color var(--pf-transition-fast);\n width: 40px;\n}\n\n.step:hover:not(:disabled) {\n background: var(--pf-numberinput-step-hover-bg);\n color: var(--pf-numberinput-step-hover-text);\n}\n\n.step:disabled {\n cursor: not-allowed;\n opacity: 0.45;\n}\n\n[part='decrement'] {\n border-inline-end: 1px solid var(--pf-numberinput-border);\n}\n\n[part='increment'] {\n border-inline-start: 1px solid var(--pf-numberinput-border);\n}\n\n.step pf-icon {\n font-size: 16px;\n}\n\n.description {\n color: var(--pf-numberinput-field-description, var(--pf-field-description));\n font-size: var(--font-size-sm);\n margin: 0;\n}\n\n.error {\n color: var(--pf-field-error);\n font-size: var(--font-size-sm);\n margin: 0;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .control,\n .step {\n transition: none;\n }\n}\n","import {\n clampNumber,\n composeDescribedBy,\n formatNumberValue,\n Keys,\n parseNumberValue,\n roundToStep,\n stepNumber,\n} from '@pitchfork-ui/core';\nimport {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\n\nimport { applyControlValidity } from '../../form-validity';\n\n/**\n * A form-associated stepper field.\n *\n * The value is a **string** rather than a number, because that is what an\n * attribute can carry and what a form submits; `pfChange` reports the parsed\n * number beside it, which is what a framework consumer wants. An empty string\n * is an empty field — not zero, which is a value someone chose.\n *\n * All of the arithmetic is core's, so this and the React `NumberInput` step,\n * round and clamp identically: ten steps of `0.1` reach exactly 1 in both.\n *\n * @part field - the wrapper around label, control and messages.\n * @part label - the label element.\n * @part control - the box holding the steppers and the input.\n * @part decrement - the step-down button.\n * @part input - the native input.\n * @part increment - the step-up button.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-number-input',\n styleUrl: 'pf-number-input.css',\n formAssociated: true,\n shadow: { delegatesFocus: true },\n})\nexport class PfNumberInput {\n @Element() el!: HTMLElement;\n\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Submitted under this name. Reflected, because a form-associated element\n * takes its submission name from the attribute, not this property.\n */\n @Prop({ reflect: true }) name?: string;\n\n /** The value, as a string. Empty means an empty field. */\n @Prop({ mutable: true }) value = '';\n\n /** The lowest value the field accepts. */\n @Prop() min?: number;\n\n /** The highest value the field accepts. */\n @Prop() max?: number;\n\n /** How far one step moves, and what the result is rounded to. */\n @Prop() step = 1;\n\n /** Visible label. Rendered in the same root as the input, so `for` works. */\n @Prop() label?: string;\n\n /** Hint text below the control. */\n @Prop() description?: string;\n\n /** Error message. Its presence is what marks the control invalid. */\n @Prop() error?: string;\n\n @Prop() placeholder?: string;\n\n @Prop({ reflect: true }) required = false;\n\n @Prop({ reflect: true }) disabled = false;\n\n /** The step-down button's accessible name. */\n @Prop() decrementLabel = 'Decrease';\n\n /** The step-up button's accessible name. */\n @Prop() incrementLabel = 'Increase';\n\n /** Fires when the value changes, with the parsed number beside the string. */\n @Event() pfChange!: EventEmitter<{ value: string; number: number | null }>;\n\n /**\n * What the input shows while it is being edited, which is not always the\n * value: a half-typed \"-\" or \"1.\" is neither a number nor a reason to throw\n * the keystroke away.\n */\n @State() draft: string | null = null;\n\n /** The value a form reset restores, which is the initial attribute. */\n private initialValue = '';\n\n componentWillLoad() {\n this.initialValue = this.value ?? '';\n this.syncFormState();\n }\n\n @Watch('value')\n @Watch('error')\n @Watch('required')\n syncFormState() {\n this.internals.setFormValue(this.value ?? '');\n applyControlValidity(this.internals, Boolean(this.value), this.required, this.error);\n }\n\n /** A form-associated custom element does not inherit this. */\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n /** As `checkValidity`, but also shows the browser's validation message. */\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n /** The message explaining why the control is invalid, or an empty string. */\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n /** A reset restores the value the field started with. */\n formResetCallback() {\n this.value = this.initialValue;\n this.draft = null;\n }\n\n /** Steps the value up or down, as the buttons and the arrows do. */\n @Method()\n async stepBy(direction: 1 | -1): Promise<void> {\n this.step_(direction);\n }\n\n private get bounds() {\n return {\n min: this.min === undefined ? -Infinity : Number(this.min),\n max: this.max === undefined ? Infinity : Number(this.max),\n step: Number(this.step) || 1,\n };\n }\n\n private get current(): number | null {\n return parseNumberValue(this.value);\n }\n\n private get atMin(): boolean {\n const { min } = this.bounds;\n return this.current !== null && this.current <= min;\n }\n\n private get atMax(): boolean {\n const { max } = this.bounds;\n return this.current !== null && this.current >= max;\n }\n\n private commit(next: number | null) {\n const { min, max, step } = this.bounds;\n const value = next === null ? '' : String(roundToStep(clampNumber(next, min, max), step));\n if (value === this.value) return;\n\n this.value = value;\n this.pfChange.emit({ value, number: parseNumberValue(value) });\n }\n\n private step_(direction: 1 | -1) {\n if (this.disabled) return;\n this.draft = null;\n this.commit(stepNumber(this.current, direction, this.bounds));\n }\n\n private onInput = (event: Event) => {\n const raw = (event.target as HTMLInputElement).value;\n /*\n * The draft is kept as typed and the value follows it, rather than the\n * input being rewritten from the value: clamping mid-keystroke would make\n * \"5\" unreachable in a field whose minimum is 50, and rounding would eat\n * the \".\" of \"1.5\" as it was typed.\n */\n this.draft = raw;\n const parsed = parseNumberValue(raw);\n if (raw.trim() === '') {\n this.commit(null);\n return;\n }\n if (parsed !== null) this.commit(parsed);\n };\n\n /** On blur the draft is given up, so the field shows its real value. */\n private onBlur = () => {\n this.draft = null;\n };\n\n private onKeyDown = (event: KeyboardEvent) => {\n if (this.disabled) return;\n const { min, max } = this.bounds;\n\n if (event.key === Keys.ArrowUp) {\n event.preventDefault();\n this.step_(1);\n } else if (event.key === Keys.ArrowDown) {\n event.preventDefault();\n this.step_(-1);\n } else if (event.key === Keys.Home && Number.isFinite(min)) {\n event.preventDefault();\n this.draft = null;\n this.commit(min);\n } else if (event.key === Keys.End && Number.isFinite(max)) {\n event.preventDefault();\n this.draft = null;\n this.commit(max);\n }\n };\n\n render() {\n // IDs are scoped to this shadow root, so they can be literal.\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n const { min, max } = this.bounds;\n const shown = this.draft ?? formatNumberValue(this.current);\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {this.label && (\n <label class=\"label\" part=\"label\" htmlFor=\"input\">\n {this.label}\n {this.required && (\n <span class=\"required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div class={{ control: true, 'control--invalid': Boolean(this.error) }} part=\"control\">\n {/*\n The steppers are out of the tab order and the arrows are on the\n input, which is the spinbutton pattern: a keyboard user steps\n without leaving the field. `mousedown` is prevented so a click\n does not take focus off it either.\n */}\n <button\n type=\"button\"\n class=\"step\"\n part=\"decrement\"\n aria-label={this.decrementLabel}\n disabled={this.disabled || this.atMin}\n tabindex=\"-1\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => this.step_(-1)}\n >\n <pf-icon name=\"minus\" aria-hidden=\"true\"></pf-icon>\n </button>\n\n <input\n id=\"input\"\n part=\"input\"\n class=\"input\"\n type=\"text\"\n inputMode=\"decimal\"\n role=\"spinbutton\"\n name={this.name}\n value={shown}\n placeholder={this.placeholder}\n required={this.required}\n disabled={this.disabled}\n autocomplete=\"off\"\n aria-invalid={this.error ? 'true' : null}\n aria-describedby={describedBy}\n aria-valuenow={this.current ?? null}\n aria-valuemin={Number.isFinite(min) ? min : null}\n aria-valuemax={Number.isFinite(max) ? max : null}\n onInput={this.onInput}\n onBlur={this.onBlur}\n onKeyDown={this.onKeyDown}\n />\n\n <button\n type=\"button\"\n class=\"step\"\n part=\"increment\"\n aria-label={this.incrementLabel}\n disabled={this.disabled || this.atMax}\n tabindex=\"-1\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => this.step_(1)}\n >\n <pf-icon name=\"plus\" aria-hidden=\"true\"></pf-icon>\n </button>\n </div>\n\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,2 +0,0 @@
1
- import{r as t,c as e,a as i,h as o,H as s}from"./p-Bm6UxEit.js";import{o as r,p as a}from"./p-CC7AyfOt.js";import{c as n}from"./p-DfpCerXM.js";import{q as c,m as h}from"./p-Dkd7BUB5.js";import{K as l}from"./p-g4FlTDZx.js";import{g as d,r as p}from"./p-CAz7-p8y.js";import{a as f}from"./p-Cr6IXrUk.js";const b=()=>`:host{display:block;--pf-option-text:var(--pf-combobox-text);--pf-option-text-disabled:var(--pf-combobox-placeholder);--pf-option-active-bg:var(--pf-combobox-option-active-bg);--pf-option-active-text:var(--pf-combobox-option-active-text)}:host([hidden]){display:none}.field{display:grid;gap:var(--space-1)}.label{color:var(--pf-combobox-text);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium)}.required{color:var(--pf-combobox-invalid-border);margin-inline-start:var(--space-1)}.control{align-items:center;background:var(--pf-combobox-bg);border:1px solid var(--pf-combobox-border);border-radius:var(--radius-md);display:flex;gap:var(--space-1);padding-inline-end:var(--space-2)}.control:focus-within{border-color:var(--pf-combobox-focus-border);box-shadow:var(--pf-focus-ring)}.control--invalid{border-color:var(--pf-combobox-invalid-border)}.input{background:none;border:0;color:var(--pf-combobox-text);flex:1;font-family:inherit;font-size:var(--font-size-sm);min-width:0;outline:none;padding:var(--space-2) var(--space-3)}.input::placeholder{color:var(--pf-combobox-placeholder)}.input:disabled{cursor:not-allowed;opacity:0.6}.clear,.chevron{align-items:center;color:var(--pf-combobox-placeholder);display:inline-flex;flex-shrink:0;justify-content:center}.clear{background:none;border:0;border-radius:var(--radius-sm);cursor:pointer;padding:var(--space-1)}.clear:hover{color:var(--pf-combobox-text)}.chevron{transition:transform var(--pf-transition-fast)}:host([open]) .chevron{transform:rotate(180deg)}@media (prefers-reduced-motion: reduce){.chevron{transition:none}}.description{color:var(--pf-combobox-placeholder);font-size:var(--font-size-xs);margin:0}.error{color:var(--pf-combobox-invalid-border);font-size:var(--font-size-xs);margin:0}.listbox{inset:auto;margin:0;background:var(--pf-combobox-menu-bg);border:1px solid var(--pf-combobox-menu-border);border-radius:var(--radius-md);box-shadow:var(--pf-elevation-popover-shadow);max-height:min(60vh, 320px);overflow-y:auto;padding:var(--space-1)}.listbox:popover-open{animation:pf-combobox-in var(--pf-transition-enter)}@keyframes pf-combobox-in{from{opacity:0;transform:translateY(-4px)}}@media (prefers-reduced-motion: reduce){.listbox:popover-open{animation:none}}.empty{color:var(--pf-combobox-placeholder);font-size:var(--font-size-sm);margin:0;padding:var(--space-3);text-align:center}`;const u={[l.ArrowDown]:"next",[l.ArrowUp]:"previous",[l.Home]:"first",[l.End]:"last"};const m=class{constructor(i){t(this,i);this.pfChange=e(this,"pfChange");this.pfOpenChange=e(this,"pfOpenChange");if(i.$hostElement$["s-ei"]){this.internals=i.$hostElement$["s-ei"]}else{this.internals=i.$hostElement$.attachInternals();i.$hostElement$["s-ei"]=this.internals}}get el(){return i(this)}internals;name;value="";open=false;label;description;error;placeholder="Search…";emptyMessage="No matches";required=false;disabled=false;clearable=true;clearLabel="Clear";pfChange;pfOpenChange;query="";matchCount=0;initialValue="";stopObserving;activeOption=null;componentWillLoad(){this.initialValue=this.value??"";this.syncFormState();this.query=this.selectedLabel();this.applyQuery()}componentDidRender(){this.syncActiveDescendant()}disconnectedCallback(){this.stopObserving?.()}syncFormState(){this.internals.setFormValue(this.value||null);f(this.internals,Boolean(this.value),this.required,this.error)}syncSelection(){for(const t of this.options()){t.selected=this.optionValue(t)===this.value&&this.value!==""}this.query=this.selectedLabel();this.applyQuery()}syncOpen(t,e){if(t)this.showListbox();else this.hideListbox();if(t!==e)this.pfOpenChange.emit({open:t})}async show(){if(!this.disabled)this.open=true}async hide(){this.open=false}async checkValidity(){return this.internals.checkValidity()}async reportValidity(){return this.internals.reportValidity()}async getValidationMessage(){return this.internals.validationMessage}formResetCallback(){this.value=this.initialValue;this.query=this.selectedLabel();this.applyQuery()}async refresh(){this.syncSelection()}onSlotChange=()=>{this.syncSelection()};options(){return Array.from(this.el.querySelectorAll("pf-option"))}visible(){return this.options().filter((t=>!t.hasAttribute("hidden")))}optionValue(t){return t.value??t.getAttribute("value")??""}selectedLabel(){const t=this.options().find((t=>this.optionValue(t)===this.value));return this.value&&t?t.textContent?.trim()??"":""}get listbox(){return this.el.shadowRoot?.querySelector('[part="listbox"]')??null}get input(){return this.el.shadowRoot?.querySelector('[part="input"]')??null}get control(){return this.el.shadowRoot?.querySelector('[part="control"]')??null}applyQuery(){const t=c(this.query,this.selectedLabel());const e=this.options();for(const i of e){const e=t||h({label:i.textContent?.trim()??""},this.query);if(e)i.removeAttribute("hidden");else i.setAttribute("hidden","")}const i=this.visible();this.matchCount=i.length;const o=i.find((t=>!t.hasAttribute("disabled")))??null;if(!this.activeOption||this.activeOption.hasAttribute("hidden"))this.setActive(o)}showListbox(){const t=this.listbox;if(this.disabled||!t||t.matches(":popover-open"))return;t.showPopover();this.stopObserving?.();this.stopObserving=r({getAnchor:()=>this.control,getFloating:()=>t,matchAnchorWidth:true,flip:true,onChange:({left:e,top:i,width:o,minWidth:s})=>{a(t,e,i);if(o!==undefined)t.style.width=`${o}px`;if(s!==undefined)t.style.minWidth=`${s}px`}});this.applyQuery()}hideListbox(){this.stopObserving?.();this.stopObserving=undefined;const t=this.listbox;if(t?.matches(":popover-open"))t.hidePopover()}onToggle=t=>{const e=t.newState==="open";if(this.open!==e)this.open=e;if(!e){this.query=this.selectedLabel();this.applyQuery();this.input?.focus()}};setActive(t){for(const e of this.options()){if(e!==t)e.active=false}if(t)t.active=true;this.activeOption=t;this.syncActiveDescendant();if(t&&typeof t.scrollIntoView==="function"){t.scrollIntoView({block:"nearest"})}}syncActiveDescendant(){const t=this.input;if(!t||!("ariaActiveDescendantElement"in t))return;t.ariaActiveDescendantElement=this.open?this.activeOption:null}commit(t){if(t.hasAttribute("disabled"))return;const e=this.optionValue(t);this.open=false;if(e!==this.value){this.value=e;this.pfChange.emit({value:e})}this.query=this.selectedLabel();this.applyQuery();this.input?.focus()}handleOptionSelect(t){t.stopPropagation();if(this.disabled)return;const e=this.options().find((e=>this.optionValue(e)===t.detail.value));if(e)this.commit(e)}move(t){const e=this.visible();const i=d(e,(t=>t.hasAttribute("disabled")));const o=this.activeOption?e.indexOf(this.activeOption):-1;const s=p(t,i,o);if(s!==-1)this.setActive(e[s]??null)}onInput=t=>{this.query=t.target.value;this.applyQuery();if(!this.open)this.open=true};clear=()=>{this.query="";if(this.value!==""){this.value="";this.pfChange.emit({value:""})}this.applyQuery();this.open=true;this.input?.focus()};onKeyDown=t=>{if(this.disabled)return;const e=u[t.key];if(e){t.preventDefault();if(!this.open)this.open=true;else this.move(e);return}if(t.key===l.Enter&&this.open&&this.activeOption){t.preventDefault();this.commit(this.activeOption)}};render(){const t=n(this.description&&"description",this.error&&"error");const e=this.clearable&&!this.disabled&&(this.query!==""||this.value!=="");return o(s,{key:"a8de74e291d2b9b200ecd25aa173a0b5d3b7b626"},o("div",{key:"90e0c5924b6bf0bc06cae69fa69d03d8a7839991",class:"field",part:"field"},this.label&&o("label",{key:"40c0f27b7320895673dfe5a222e5c9a9c177342e",class:"label",part:"label",htmlFor:"input"},this.label,this.required&&o("span",{key:"dd07ad670d93b1aff47c4ad879d021e5c01b4744",class:"required","aria-hidden":"true"},"*")),o("div",{key:"125a49726f50d094cd5b07055dac55a18ac5f730",class:{control:true,"control--invalid":Boolean(this.error)},part:"control"},o("input",{key:"f5af0e210b95aaf50f6aa26fea9923ecce23a9d9",id:"input",part:"input",class:"input",type:"text",role:"combobox",autocomplete:"off",disabled:this.disabled,required:this.required,placeholder:this.placeholder,value:this.query,"aria-autocomplete":"list","aria-expanded":this.open?"true":"false","aria-controls":"listbox","aria-invalid":this.error?"true":null,"aria-describedby":t,onInput:this.onInput,onKeyDown:this.onKeyDown,onClick:()=>{if(!this.disabled)this.open=true}}),e&&o("button",{key:"3de0deb6fa499c4f09a8135e8f437a0b8d800e2b",class:"clear",part:"clear",type:"button","aria-label":this.clearLabel,tabindex:-1,onMouseDown:t=>t.preventDefault(),onClick:this.clear},o("pf-icon",{key:"4690b5b9889c4fa42d9a517c44881dcc39a3ce6a",name:"circle-xmark"})),o("span",{key:"91d963abe51964b40952c20662cda34fe6bc8422",class:"chevron","aria-hidden":"true"},o("pf-icon",{key:"26d800a4907e4c043771cf88939a452140656cc2",name:"chevron-down"}))),this.description&&o("p",{key:"25aa3122181742855db9407918564609e5229b9d",class:"description",part:"description",id:"description"},this.description),this.error&&o("p",{key:"383cea1cb15a3d5007fffae49fa9ebe713d4c46e",class:"error",part:"error",id:"error"},this.error)),o("div",{key:"56960b3bba88d5699a8dc813050bdb726bafa905",id:"listbox",part:"listbox",class:"listbox",popover:"auto",role:"listbox","aria-label":this.label??this.placeholder,onToggle:this.onToggle},o("slot",{key:"746f17fc39239ee6d577fb1bd1a0e0ac8165081d",onSlotchange:this.onSlotChange}),this.matchCount===0&&o("p",{key:"58b33af6e2edd8f4b64d0f9ee7fc62004f219cf4",class:"empty",part:"empty"},this.emptyMessage)))}static get formAssociated(){return true}static get watchers(){return{value:[{syncFormState:0},{syncSelection:0}],error:[{syncFormState:0}],required:[{syncFormState:0}],open:[{syncOpen:0}]}}};m.style=b();export{m as pf_combobox};
2
- //# sourceMappingURL=p-47cabc33.entry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["pfComboboxCss","MOVES","Keys","ArrowDown","ArrowUp","Home","End","PfCombobox","internals","name","value","open","label","description","error","placeholder","emptyMessage","required","disabled","clearable","clearLabel","pfChange","pfOpenChange","query","matchCount","initialValue","stopObserving","activeOption","componentWillLoad","this","syncFormState","selectedLabel","applyQuery","componentDidRender","syncActiveDescendant","disconnectedCallback","setFormValue","applyControlValidity","Boolean","syncSelection","option","options","selected","optionValue","syncOpen","next","previous","showListbox","hideListbox","emit","show","hide","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","refresh","onSlotChange","Array","from","el","querySelectorAll","visible","filter","hasAttribute","getAttribute","chosen","find","textContent","trim","listbox","shadowRoot","querySelector","input","control","echoed","queryIsEchoedSelection","matches","matchesCommandQuery","removeAttribute","setAttribute","length","first","setActive","panel","showPopover","observeAnchoredPosition","getAnchor","getFloating","matchAnchorWidth","flip","onChange","left","top","width","minWidth","placePopover","undefined","style","hidePopover","onToggle","event","nowOpen","newState","focus","other","active","scrollIntoView","block","ariaActiveDescendantElement","commit","handleOptionSelect","stopPropagation","candidate","detail","move","action","enabledIndexes","getEnabledIndexes","current","indexOf","resolveListMove","onInput","target","clear","onKeyDown","key","preventDefault","Enter","render","describedBy","composeDescribedBy","showClear","h","Host","class","part","htmlFor","id","type","role","autocomplete","onClick","tabindex","onMouseDown","popover","onSlotchange"],"sources":["src/components/pf-combobox/pf-combobox.css?tag=pf-combobox&encapsulation=shadow","src/components/pf-combobox/pf-combobox.tsx"],"sourcesContent":["/*\n * The generic set pf-option reads, mapped to this control's own family — see\n * pf-option.css. The same option element is themed by whichever listbox it is\n * slotted into.\n */\n:host {\n display: block;\n --pf-option-text: var(--pf-combobox-text);\n --pf-option-text-disabled: var(--pf-combobox-placeholder);\n --pf-option-active-bg: var(--pf-combobox-option-active-bg);\n --pf-option-active-text: var(--pf-combobox-option-active-text);\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-1);\n}\n\n.label {\n color: var(--pf-combobox-text);\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-combobox-invalid-border);\n margin-inline-start: var(--space-1);\n}\n\n.control {\n align-items: center;\n background: var(--pf-combobox-bg);\n border: 1px solid var(--pf-combobox-border);\n border-radius: var(--radius-md);\n display: flex;\n gap: var(--space-1);\n padding-inline-end: var(--space-2);\n}\n\n.control:focus-within {\n border-color: var(--pf-combobox-focus-border);\n box-shadow: var(--pf-focus-ring);\n}\n\n.control--invalid {\n border-color: var(--pf-combobox-invalid-border);\n}\n\n.input {\n background: none;\n border: 0;\n color: var(--pf-combobox-text);\n flex: 1;\n font-family: inherit;\n font-size: var(--font-size-sm);\n min-width: 0;\n outline: none;\n padding: var(--space-2) var(--space-3);\n}\n\n.input::placeholder {\n color: var(--pf-combobox-placeholder);\n}\n\n.input:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.clear,\n.chevron {\n align-items: center;\n color: var(--pf-combobox-placeholder);\n display: inline-flex;\n flex-shrink: 0;\n justify-content: center;\n}\n\n.clear {\n background: none;\n border: 0;\n border-radius: var(--radius-sm);\n cursor: pointer;\n padding: var(--space-1);\n}\n\n.clear:hover {\n color: var(--pf-combobox-text);\n}\n\n.chevron {\n transition: transform var(--pf-transition-fast);\n}\n\n:host([open]) .chevron {\n transform: rotate(180deg);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .chevron {\n transition: none;\n }\n}\n\n.description {\n color: var(--pf-combobox-placeholder);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n\n.error {\n color: var(--pf-combobox-invalid-border);\n font-size: var(--font-size-xs);\n margin: 0;\n}\n\n/* See src/place-popover.ts: the UA stylesheet centres a popover otherwise. */\n.listbox {\n inset: auto;\n margin: 0;\n background: var(--pf-combobox-menu-bg);\n border: 1px solid var(--pf-combobox-menu-border);\n border-radius: var(--radius-md);\n box-shadow: var(--pf-elevation-popover-shadow);\n max-height: min(60vh, 320px);\n overflow-y: auto;\n padding: var(--space-1);\n}\n\n.listbox:popover-open {\n animation: pf-combobox-in var(--pf-transition-enter);\n}\n\n/* Its own copy: @keyframes do not cross a shadow boundary. */\n@keyframes pf-combobox-in {\n from {\n opacity: 0;\n transform: translateY(-4px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .listbox:popover-open {\n animation: none;\n }\n}\n\n.empty {\n color: var(--pf-combobox-placeholder);\n font-size: var(--font-size-sm);\n margin: 0;\n padding: var(--space-3);\n text-align: center;\n}\n","import {\n composeDescribedBy,\n getEnabledIndexes,\n Keys,\n matchesCommandQuery,\n observeAnchoredPosition,\n queryIsEchoedSelection,\n resolveListMove,\n type ListNavigationAction,\n} from '@pitchfork-ui/core';\n\nimport { applyControlValidity } from '../../form-validity';\nimport { placePopover } from '../../place-popover';\nimport {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Listen,\n Method,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\n\nconst MOVES: Record<string, ListNavigationAction> = {\n [Keys.ArrowDown]: 'next',\n [Keys.ArrowUp]: 'previous',\n [Keys.Home]: 'first',\n [Keys.End]: 'last',\n};\n\n/**\n * A form-associated combobox: an editable field that filters `pf-option`\n * children.\n *\n * It shares `pf-option` with `pf-select`, which is why the option reads a\n * generic `--pf-option-*` set that each container maps to its own family —\n * the same arrangement as `pf-menu-item` between the two menus.\n *\n * Filtering is core's `matchesCommandQuery`, and so is the rule that a query\n * which is only the chosen label echoed back does not filter: without it,\n * reopening the list to change your mind would show the one answer you already\n * had. Both shared with the React component, which is now rewired to them.\n *\n * Two things the React `Combobox` does not do, both gaps rather than choices:\n * Home and End, and arrows that wrap rather than stop at the ends — which is\n * what `pf-select` does, and one design system should not have two arrow\n * behaviours in neighbouring controls.\n *\n * @slot - the `pf-option` children.\n * @part field - the wrapper around label, control and messages.\n * @part label - the label element.\n * @part control - the box holding the input, clear button and chevron.\n * @part input - the editable field.\n * @part clear - the clear button.\n * @part listbox - the floating listbox the options are slotted into.\n * @part empty - the message shown when nothing matches.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-combobox',\n styleUrl: 'pf-combobox.css',\n formAssociated: true,\n shadow: true,\n})\nexport class PfCombobox {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n /** Submitted under this name. Reflected; the submission reads the attribute. */\n @Prop({ reflect: true }) name?: string;\n\n /** The chosen option's value, or empty. */\n @Prop({ mutable: true, reflect: true }) value = '';\n\n /** Whether the listbox is showing. Reflected for the stylesheet. */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n @Prop() label?: string;\n\n @Prop() description?: string;\n\n @Prop() error?: string;\n\n @Prop() placeholder = 'Search…';\n\n /** Shown when the query matches nothing. */\n @Prop() emptyMessage = 'No matches';\n\n @Prop({ reflect: true }) required = false;\n\n @Prop({ reflect: true }) disabled = false;\n\n /** Offer a button that empties the field. */\n @Prop() clearable = true;\n\n /** Accessible name for that button. */\n @Prop() clearLabel = 'Clear';\n\n /** Fires when the chosen value changes. */\n @Event() pfChange!: EventEmitter<{ value: string }>;\n\n /** Fires whenever the listbox opens or closes, whoever caused it. */\n @Event() pfOpenChange!: EventEmitter<{ open: boolean }>;\n\n /** What the field holds, which is not the value until an option is chosen. */\n @State() query = '';\n\n @State() matchCount = 0;\n\n private initialValue = '';\n private stopObserving?: () => void;\n private activeOption: HTMLElement | null = null;\n\n componentWillLoad() {\n this.initialValue = this.value ?? '';\n this.syncFormState();\n this.query = this.selectedLabel();\n this.applyQuery();\n }\n\n componentDidRender() {\n this.syncActiveDescendant();\n }\n\n disconnectedCallback() {\n this.stopObserving?.();\n }\n\n @Watch('value')\n @Watch('error')\n @Watch('required')\n syncFormState() {\n this.internals.setFormValue(this.value || null);\n applyControlValidity(this.internals, Boolean(this.value), this.required, this.error);\n }\n\n /** A value set from outside puts its label in the field and marks the option. */\n @Watch('value')\n syncSelection() {\n for (const option of this.options()) {\n (option as HTMLElement & { selected: boolean }).selected =\n this.optionValue(option) === this.value && this.value !== '';\n }\n this.query = this.selectedLabel();\n this.applyQuery();\n }\n\n @Watch('open')\n syncOpen(next: boolean, previous: boolean) {\n if (next) this.showListbox();\n else this.hideListbox();\n if (next !== previous) this.pfOpenChange.emit({ open: next });\n }\n\n @Method()\n async show(): Promise<void> {\n if (!this.disabled) this.open = true;\n }\n\n @Method()\n async hide(): Promise<void> {\n this.open = false;\n }\n\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n formResetCallback() {\n this.value = this.initialValue;\n this.query = this.selectedLabel();\n this.applyQuery();\n }\n\n /** Re-reads the options, for a label edited in place (no `slotchange` fires). */\n @Method()\n async refresh(): Promise<void> {\n this.syncSelection();\n }\n\n private onSlotChange = () => {\n this.syncSelection();\n };\n\n private options(): HTMLElement[] {\n return Array.from(this.el.querySelectorAll<HTMLElement>('pf-option'));\n }\n\n private visible(): HTMLElement[] {\n return this.options().filter((option) => !option.hasAttribute('hidden'));\n }\n\n /** The property, never the attribute: a binding may only have set the former. */\n private optionValue(option: HTMLElement): string {\n return (option as HTMLElement & { value?: string }).value ?? option.getAttribute('value') ?? '';\n }\n\n private selectedLabel(): string {\n const chosen = this.options().find((option) => this.optionValue(option) === this.value);\n return this.value && chosen ? (chosen.textContent?.trim() ?? '') : '';\n }\n\n private get listbox() {\n return this.el.shadowRoot?.querySelector<HTMLElement>('[part=\"listbox\"]') ?? null;\n }\n\n private get input() {\n return this.el.shadowRoot?.querySelector<HTMLInputElement>('[part=\"input\"]') ?? null;\n }\n\n private get control() {\n return this.el.shadowRoot?.querySelector<HTMLElement>('[part=\"control\"]') ?? null;\n }\n\n /**\n * Hides the options the query excludes.\n *\n * `hidden` plus `:host([hidden]) { display: none }` on the option, because\n * the attribute alone loses to the option's own `display: block`.\n */\n private applyQuery() {\n const echoed = queryIsEchoedSelection(this.query, this.selectedLabel());\n const options = this.options();\n\n for (const option of options) {\n const matches =\n echoed || matchesCommandQuery({ label: option.textContent?.trim() ?? '' }, this.query);\n if (matches) option.removeAttribute('hidden');\n else option.setAttribute('hidden', '');\n }\n\n const visible = this.visible();\n this.matchCount = visible.length;\n\n // A new query starts at the top of what is left.\n const first = visible.find((option) => !option.hasAttribute('disabled')) ?? null;\n if (!this.activeOption || this.activeOption.hasAttribute('hidden')) this.setActive(first);\n }\n\n private showListbox() {\n const panel = this.listbox;\n if (this.disabled || !panel || panel.matches(':popover-open')) return;\n\n panel.showPopover();\n this.stopObserving?.();\n this.stopObserving = observeAnchoredPosition({\n getAnchor: () => this.control,\n getFloating: () => panel,\n matchAnchorWidth: true,\n flip: true,\n onChange: ({ left, top, width, minWidth }) => {\n placePopover(panel, left, top);\n if (width !== undefined) panel.style.width = `${width}px`;\n if (minWidth !== undefined) panel.style.minWidth = `${minWidth}px`;\n },\n });\n\n this.applyQuery();\n }\n\n private hideListbox() {\n this.stopObserving?.();\n this.stopObserving = undefined;\n const panel = this.listbox;\n if (panel?.matches(':popover-open')) panel.hidePopover();\n }\n\n /**\n * A browser-driven close — light dismiss or Escape — reverts the field to\n * the chosen label, so a half-typed query never lingers over a different\n * value. Focus goes back to the input rather than the trigger, because here\n * the input *is* the control.\n */\n private onToggle = (event: ToggleEvent) => {\n const nowOpen = event.newState === 'open';\n if (this.open !== nowOpen) this.open = nowOpen;\n if (!nowOpen) {\n this.query = this.selectedLabel();\n this.applyQuery();\n this.input?.focus();\n }\n };\n\n private setActive(option: HTMLElement | null) {\n for (const other of this.options()) {\n if (other !== option) (other as HTMLElement & { active: boolean }).active = false;\n }\n if (option) (option as HTMLElement & { active: boolean }).active = true;\n\n this.activeOption = option;\n this.syncActiveDescendant();\n if (option && typeof option.scrollIntoView === 'function') {\n option.scrollIntoView({ block: 'nearest' });\n }\n }\n\n /**\n * Set as an element, not an IDREF: the input is in this shadow root and the\n * options are slotted light DOM, and a cross-root IDREF is absent from the\n * accessibility tree — measured. Feature-detected, because where element\n * reflection is missing there is no cross-root equivalent.\n */\n private syncActiveDescendant() {\n const input = this.input;\n if (!input || !('ariaActiveDescendantElement' in input)) return;\n (\n input as unknown as { ariaActiveDescendantElement: Element | null }\n ).ariaActiveDescendantElement = this.open ? this.activeOption : null;\n }\n\n private commit(option: HTMLElement) {\n if (option.hasAttribute('disabled')) return;\n\n const next = this.optionValue(option);\n this.open = false;\n\n if (next !== this.value) {\n this.value = next;\n this.pfChange.emit({ value: next });\n }\n\n // Set after the value, so it is the chosen label rather than the query.\n this.query = this.selectedLabel();\n this.applyQuery();\n this.input?.focus();\n }\n\n @Listen('pfOptionSelect')\n handleOptionSelect(event: CustomEvent<{ value: string }>) {\n event.stopPropagation();\n if (this.disabled) return;\n\n const option = this.options().find(\n (candidate) => this.optionValue(candidate) === event.detail.value,\n );\n if (option) this.commit(option);\n }\n\n private move(action: ListNavigationAction) {\n const visible = this.visible();\n const enabledIndexes = getEnabledIndexes(visible, (option) => option.hasAttribute('disabled'));\n const current = this.activeOption ? visible.indexOf(this.activeOption) : -1;\n const next = resolveListMove(action, enabledIndexes, current);\n if (next !== -1) this.setActive(visible[next] ?? null);\n }\n\n private onInput = (event: Event) => {\n this.query = (event.target as HTMLInputElement).value;\n this.applyQuery();\n if (!this.open) this.open = true;\n };\n\n private clear = () => {\n this.query = '';\n if (this.value !== '') {\n this.value = '';\n this.pfChange.emit({ value: '' });\n }\n this.applyQuery();\n this.open = true;\n this.input?.focus();\n };\n\n private onKeyDown = (event: KeyboardEvent) => {\n if (this.disabled) return;\n\n const move = MOVES[event.key];\n if (move) {\n event.preventDefault();\n if (!this.open) this.open = true;\n else this.move(move);\n return;\n }\n\n /*\n * Enter only commits while the listbox is open. Closed, it is left alone\n * so a combobox inside a form still submits it.\n */\n if (event.key === Keys.Enter && this.open && this.activeOption) {\n event.preventDefault();\n this.commit(this.activeOption);\n }\n\n // Escape is the browser's: `popover=\"auto\"` closes, and `onToggle` reverts.\n };\n\n render() {\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n const showClear = this.clearable && !this.disabled && (this.query !== '' || this.value !== '');\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {this.label && (\n <label class=\"label\" part=\"label\" htmlFor=\"input\">\n {this.label}\n {this.required && (\n <span class=\"required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n\n <div class={{ control: true, 'control--invalid': Boolean(this.error) }} part=\"control\">\n <input\n id=\"input\"\n part=\"input\"\n class=\"input\"\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n disabled={this.disabled}\n required={this.required}\n placeholder={this.placeholder}\n value={this.query}\n aria-autocomplete=\"list\"\n aria-expanded={this.open ? 'true' : 'false'}\n /* Same shadow root as the listbox, so this IDREF resolves. */\n aria-controls=\"listbox\"\n aria-invalid={this.error ? 'true' : null}\n aria-describedby={describedBy}\n onInput={this.onInput}\n onKeyDown={this.onKeyDown}\n onClick={() => {\n if (!this.disabled) this.open = true;\n }}\n />\n\n {showClear && (\n <button\n class=\"clear\"\n part=\"clear\"\n type=\"button\"\n aria-label={this.clearLabel}\n /* Out of the tab order, so it never interrupts the keyboard flow. */\n tabindex={-1}\n onMouseDown={(event) => event.preventDefault()}\n onClick={this.clear}\n >\n <pf-icon name=\"circle-xmark\"></pf-icon>\n </button>\n )}\n\n <span class=\"chevron\" aria-hidden=\"true\">\n <pf-icon name=\"chevron-down\"></pf-icon>\n </span>\n </div>\n\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n\n <div\n id=\"listbox\"\n part=\"listbox\"\n class=\"listbox\"\n popover=\"auto\"\n role=\"listbox\"\n aria-label={this.label ?? this.placeholder}\n onToggle={this.onToggle}\n >\n <slot onSlotchange={this.onSlotChange} />\n {this.matchCount === 0 && (\n <p class=\"empty\" part=\"empty\">\n {this.emptyMessage}\n </p>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,2 +0,0 @@
1
- import{r,c as e,h as i,H as s}from"./p-Bm6UxEit.js";import{c as a}from"./p-DfpCerXM.js";import{n as t,a as d,b as l}from"./p-BA6CMosJ.js";import{a as o}from"./p-Cr6IXrUk.js";const n=()=>`:host{display:block}:host([hidden]){display:none}.field{display:grid;gap:var(--space-2)}.label{color:var(--pf-slider-field-label, var(--pf-field-label));font-size:var(--font-size-sm);font-weight:var(--font-weight-medium)}.required{color:var(--pf-field-required);margin-inline-start:var(--space-1)}.description{color:var(--pf-slider-field-description, var(--pf-field-description));font-size:var(--font-size-sm);margin:0}.error{color:var(--pf-slider-field-error, var(--pf-field-error));font-size:var(--font-size-sm);margin:0}.header{align-items:center;display:flex;justify-content:space-between}.value{color:var(--pf-slider-text-muted);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium)}.slider{appearance:none;background:linear-gradient( to right, var(--pf-slider-action) 0, var(--pf-slider-action) var(--pf-slider-progress, 0%), var(--pf-slider-border) var(--pf-slider-progress, 0%), var(--pf-slider-border) 100% );border-radius:var(--radius-full);cursor:pointer;height:var(--pf-slider-track-height);width:100%}.slider:focus{outline:none}.slider:focus-visible{box-shadow:var(--pf-slider-focus-ring, var(--pf-focus-ring))}.slider::-webkit-slider-thumb{appearance:none;background:var(--pf-slider-bg);border:2px solid var(--pf-slider-action);border-radius:50%;box-shadow:var(--pf-slider-control-thumb-outline-shadow, var(--pf-control-thumb-outline-shadow));height:var(--pf-slider-thumb-size);margin-top:calc((var(--pf-slider-track-height) - var(--pf-slider-thumb-size)) / 2);width:var(--pf-slider-thumb-size)}.slider::-moz-range-thumb{background:var(--pf-slider-bg);border:2px solid var(--pf-slider-action);border-radius:50%;box-shadow:var(--pf-slider-control-thumb-outline-shadow, var(--pf-control-thumb-outline-shadow));height:var(--pf-slider-thumb-size);width:var(--pf-slider-thumb-size)}.slider::-moz-range-track{background:transparent;border-radius:var(--radius-full);height:var(--pf-slider-track-height)}.slider:disabled{cursor:not-allowed;opacity:0.55}.slider--invalid{background:linear-gradient( to right, var(--pf-slider-danger-fill) 0, var(--pf-slider-danger-fill) var(--pf-slider-progress, 0%), var(--pf-slider-border) var(--pf-slider-progress, 0%), var(--pf-slider-border) 100% )}.slider--invalid::-webkit-slider-thumb{border-color:var(--pf-slider-danger-fill)}.slider--invalid::-moz-range-thumb{border-color:var(--pf-slider-danger-fill)}`;const p=class{constructor(i){r(this,i);this.pfInput=e(this,"pfInput");this.pfChange=e(this,"pfChange");if(i.$hostElement$["s-ei"]){this.internals=i.$hostElement$["s-ei"]}else{this.internals=i.$hostElement$.attachInternals();i.$hostElement$["s-ei"]=this.internals}}internals;name;value=0;min=0;max=100;step=1;label;description;error;showValue=true;disabled=false;pfInput;pfChange;initialValue=0;componentWillLoad(){this.initialValue=this.value;this.syncFormState()}syncFormState(){this.internals.setFormValue(`${this.current}`);o(this.internals,true,false,this.error)}async checkValidity(){return this.internals.checkValidity()}async reportValidity(){return this.internals.reportValidity()}async getValidationMessage(){return this.internals.validationMessage}formResetCallback(){this.value=this.initialValue}get range(){return t(Number(this.min),Number(this.max),Number(this.step))}get current(){const{min:r,max:e}=this.range;return d(Number(this.value),r,e)}onInput=r=>{this.value=Number(r.target.value);this.pfInput.emit({value:this.value})};onChange=()=>{this.pfChange.emit({value:this.current})};render(){const{min:r,max:e,step:t}=this.range;const d=this.current;const o=a(this.description&&"description",this.error&&"error");return i(s,{key:"aa9f73bc61fc164df6b960827337c57c89f3e041"},i("div",{key:"6de203487f260a1025c2a49abeef29f3a9a1e250",class:"field",part:"field"},(this.label||this.showValue)&&i("div",{key:"c02c8be4fff2bb3eafbb45c8d19c777d79f984a4",class:"header",part:"header"},this.label?i("label",{class:"label",part:"label",htmlFor:"input"},this.label):i("span",null),this.showValue&&i("span",{key:"6638b3e9b626493e92c4dd76428a0ba2637956d6",class:"value",part:"value","aria-hidden":"true"},Math.round(d))),i("input",{key:"03a97800d5dabc7d17e6f1cd91b9884485cafb42",id:"input",part:"input",class:{slider:true,"slider--invalid":Boolean(this.error)},type:"range",name:this.name,value:`${d}`,min:`${r}`,max:`${e}`,step:`${t}`,disabled:this.disabled,"aria-invalid":this.error?"true":null,"aria-describedby":o,onInput:this.onInput,onChange:this.onChange,style:{"--pf-slider-progress":`${l(d,r,e)}%`}}),this.description&&i("p",{key:"0338224959bff19c234bfe07b8bf83027d85b17d",class:"description",part:"description",id:"description"},this.description),this.error&&i("p",{key:"f469ebcbb86d81d933c0b66f578f8990d2a4b9a5",class:"error",part:"error",id:"error"},this.error)))}static get delegatesFocus(){return true}static get formAssociated(){return true}static get watchers(){return{value:[{syncFormState:0}],error:[{syncFormState:0}],min:[{syncFormState:0}],max:[{syncFormState:0}]}}};p.style=n();export{p as pf_slider};
2
- //# sourceMappingURL=p-48b2d3f7.entry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["pfSliderCss","PfSlider","internals","name","value","min","max","step","label","description","error","showValue","disabled","pfInput","pfChange","initialValue","componentWillLoad","this","syncFormState","setFormValue","current","applyControlValidity","checkValidity","reportValidity","getValidationMessage","validationMessage","formResetCallback","range","normalizeRange","Number","clampToRange","onInput","event","target","emit","onChange","render","describedBy","composeDescribedBy","h","Host","key","class","part","htmlFor","Math","round","id","slider","Boolean","type","style","getRangePercent"],"sources":["src/components/pf-slider/pf-slider.css?tag=pf-slider&encapsulation=shadow","src/components/pf-slider/pf-slider.tsx"],"sourcesContent":[":host {\n display: block;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.field {\n display: grid;\n gap: var(--space-2);\n}\n\n.label {\n color: var(--pf-slider-field-label, var(--pf-field-label));\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.required {\n color: var(--pf-field-required);\n margin-inline-start: var(--space-1);\n}\n\n.description {\n color: var(--pf-slider-field-description, var(--pf-field-description));\n font-size: var(--font-size-sm);\n margin: 0;\n}\n\n.error {\n color: var(--pf-slider-field-error, var(--pf-field-error));\n font-size: var(--font-size-sm);\n margin: 0;\n}\n\n.header {\n align-items: center;\n display: flex;\n justify-content: space-between;\n}\n\n.value {\n color: var(--pf-slider-text-muted);\n font-size: var(--font-size-sm);\n font-weight: var(--font-weight-medium);\n}\n\n.slider {\n appearance: none;\n background: linear-gradient(\n to right,\n var(--pf-slider-action) 0,\n var(--pf-slider-action) var(--pf-slider-progress, 0%),\n var(--pf-slider-border) var(--pf-slider-progress, 0%),\n var(--pf-slider-border) 100%\n );\n border-radius: var(--radius-full);\n cursor: pointer;\n height: var(--pf-slider-track-height);\n width: 100%;\n}\n\n.slider:focus {\n outline: none;\n}\n\n.slider:focus-visible {\n box-shadow: var(--pf-slider-focus-ring, var(--pf-focus-ring));\n}\n\n.slider::-webkit-slider-thumb {\n appearance: none;\n background: var(--pf-slider-bg);\n border: 2px solid var(--pf-slider-action);\n border-radius: 50%;\n box-shadow: var(--pf-slider-control-thumb-outline-shadow, var(--pf-control-thumb-outline-shadow));\n height: var(--pf-slider-thumb-size);\n margin-top: calc((var(--pf-slider-track-height) - var(--pf-slider-thumb-size)) / 2);\n width: var(--pf-slider-thumb-size);\n}\n\n.slider::-moz-range-thumb {\n background: var(--pf-slider-bg);\n border: 2px solid var(--pf-slider-action);\n border-radius: 50%;\n box-shadow: var(--pf-slider-control-thumb-outline-shadow, var(--pf-control-thumb-outline-shadow));\n height: var(--pf-slider-thumb-size);\n width: var(--pf-slider-thumb-size);\n}\n\n.slider::-moz-range-track {\n background: transparent;\n border-radius: var(--radius-full);\n height: var(--pf-slider-track-height);\n}\n\n.slider:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n}\n\n.slider--invalid {\n background: linear-gradient(\n to right,\n var(--pf-slider-danger-fill) 0,\n var(--pf-slider-danger-fill) var(--pf-slider-progress, 0%),\n var(--pf-slider-border) var(--pf-slider-progress, 0%),\n var(--pf-slider-border) 100%\n );\n}\n\n.slider--invalid::-webkit-slider-thumb {\n border-color: var(--pf-slider-danger-fill);\n}\n\n.slider--invalid::-moz-range-thumb {\n border-color: var(--pf-slider-danger-fill);\n}\n","import {\n clampToRange,\n composeDescribedBy,\n getRangePercent,\n normalizeRange,\n} from '@pitchfork-ui/core';\nimport {\n AttachInternals,\n Component,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n Watch,\n} from '@stencil/core';\n\nimport { applyControlValidity } from '../../form-validity';\n\n/**\n * A form-associated range slider.\n *\n * A native `<input type=\"range\">`, as the React component is — the drag, the\n * keyboard stepping and the touch handling are all the browser's, and nothing\n * here reimplements them.\n *\n * @part field - the wrapper around header, control and messages.\n * @part header - the row holding the label and the readout.\n * @part label - the label element.\n * @part value - the numeric readout.\n * @part input - the native range input.\n * @part description - the hint text below the control.\n * @part error - the error message below the control.\n */\n@Component({\n tag: 'pf-slider',\n styleUrl: 'pf-slider.css',\n formAssociated: true,\n shadow: { delegatesFocus: true },\n})\nexport class PfSlider {\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Submitted under this name. Reflected, because a form-associated element\n * takes its submission name from the attribute, not this property.\n */\n @Prop({ reflect: true }) name?: string;\n\n /** The control's value. */\n @Prop({ mutable: true }) value = 0;\n\n @Prop() min = 0;\n\n @Prop() max = 100;\n\n @Prop() step = 1;\n\n /** Visible label, rendered in the same root so `for` actually associates. */\n @Prop() label?: string;\n\n /** Hint text below the control. */\n @Prop() description?: string;\n\n /** Error message. Its presence is what marks the control invalid. */\n @Prop() error?: string;\n\n /** Show the current value beside the label. Reflected for the stylesheet. */\n @Prop({ reflect: true }) showValue = true;\n\n @Prop({ reflect: true }) disabled = false;\n\n /** Fires as the user drags, like the native `input` event. */\n @Event() pfInput!: EventEmitter<{ value: number }>;\n\n /** Fires when the value is committed, like the native `change` event. */\n @Event() pfChange!: EventEmitter<{ value: number }>;\n\n /** The value a form reset restores, which is the initial attribute. */\n private initialValue = 0;\n\n componentWillLoad() {\n this.initialValue = this.value;\n this.syncFormState();\n }\n\n @Watch('value')\n @Watch('error')\n @Watch('min')\n @Watch('max')\n syncFormState() {\n this.internals.setFormValue(`${this.current}`);\n /*\n * A slider always has a value — it cannot be empty the way a text field\n * can — so `required` would never fail and the element does not offer it.\n * Only an explicit error can make this control invalid.\n */\n applyControlValidity(this.internals, true, false, this.error);\n }\n\n /** A form-associated custom element does not inherit this. */\n @Method()\n async checkValidity(): Promise<boolean> {\n return this.internals.checkValidity();\n }\n\n /** As `checkValidity`, but also shows the browser's validation message. */\n @Method()\n async reportValidity(): Promise<boolean> {\n return this.internals.reportValidity();\n }\n\n /** The message explaining why the control is invalid, or an empty string. */\n @Method()\n async getValidationMessage(): Promise<string> {\n return this.internals.validationMessage;\n }\n\n /** A reset restores the value the control started with. */\n formResetCallback() {\n this.value = this.initialValue;\n }\n\n /** The bounds, with a non-finite or inverted range made drawable. */\n private get range() {\n return normalizeRange(Number(this.min), Number(this.max), Number(this.step));\n }\n\n /** The value as rendered: always inside the bounds. */\n private get current() {\n const { min, max } = this.range;\n return clampToRange(Number(this.value), min, max);\n }\n\n private onInput = (event: Event) => {\n this.value = Number((event.target as HTMLInputElement).value);\n this.pfInput.emit({ value: this.value });\n };\n\n private onChange = () => {\n this.pfChange.emit({ value: this.current });\n };\n\n render() {\n const { min, max, step } = this.range;\n const current = this.current;\n const describedBy = composeDescribedBy(\n this.description && 'description',\n this.error && 'error',\n );\n\n return (\n <Host>\n <div class=\"field\" part=\"field\">\n {(this.label || this.showValue) && (\n <div class=\"header\" part=\"header\">\n {this.label ? (\n <label class=\"label\" part=\"label\" htmlFor=\"input\">\n {this.label}\n </label>\n ) : (\n <span />\n )}\n {this.showValue && (\n // aria-hidden: the input already reports its value to\n // assistive technology through the range role.\n <span class=\"value\" part=\"value\" aria-hidden=\"true\">\n {Math.round(current)}\n </span>\n )}\n </div>\n )}\n\n <input\n id=\"input\"\n part=\"input\"\n class={{ slider: true, 'slider--invalid': Boolean(this.error) }}\n type=\"range\"\n name={this.name}\n value={`${current}`}\n min={`${min}`}\n max={`${max}`}\n step={`${step}`}\n disabled={this.disabled}\n aria-invalid={this.error ? 'true' : null}\n aria-describedby={describedBy}\n onInput={this.onInput}\n onChange={this.onChange}\n style={{ '--pf-slider-progress': `${getRangePercent(current, min, max)}%` }}\n />\n\n {this.description && (\n <p class=\"description\" part=\"description\" id=\"description\">\n {this.description}\n </p>\n )}\n {this.error && (\n <p class=\"error\" part=\"error\" id=\"error\">\n {this.error}\n </p>\n )}\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"8KAAA,MAAMA,EAAc,IAAM,22E,MCyCbC,EAAQ,M,0PACAC,UAMMC,KAGAC,MAAQ,EAEzBC,IAAM,EAENC,IAAM,IAENC,KAAO,EAGPC,MAGAC,YAGAC,MAGiBC,UAAY,KAEZC,SAAW,MAG3BC,QAGAC,SAGDC,aAAe,EAEvB,iBAAAC,GACEC,KAAKF,aAAeE,KAAKb,MACzBa,KAAKC,e,CAOP,aAAAA,GACED,KAAKf,UAAUiB,aAAa,GAAGF,KAAKG,WAMpCC,EAAqBJ,KAAKf,UAAW,KAAM,MAAOe,KAAKP,M,CAKzD,mBAAMY,GACJ,OAAOL,KAAKf,UAAUoB,e,CAKxB,oBAAMC,GACJ,OAAON,KAAKf,UAAUqB,gB,CAKxB,0BAAMC,GACJ,OAAOP,KAAKf,UAAUuB,iB,CAIxB,iBAAAC,GACET,KAAKb,MAAQa,KAAKF,Y,CAIpB,SAAYY,GACV,OAAOC,EAAeC,OAAOZ,KAAKZ,KAAMwB,OAAOZ,KAAKX,KAAMuB,OAAOZ,KAAKV,M,CAIxE,WAAYa,GACV,MAAMf,IAAEA,EAAGC,IAAEA,GAAQW,KAAKU,MAC1B,OAAOG,EAAaD,OAAOZ,KAAKb,OAAQC,EAAKC,E,CAGvCyB,QAAWC,IACjBf,KAAKb,MAAQyB,OAAQG,EAAMC,OAA4B7B,OACvDa,KAAKJ,QAAQqB,KAAK,CAAE9B,MAAOa,KAAKb,OAAQ,EAGlC+B,SAAW,KACjBlB,KAAKH,SAASoB,KAAK,CAAE9B,MAAOa,KAAKG,SAAU,EAG7C,MAAAgB,GACE,MAAM/B,IAAEA,EAAGC,IAAEA,EAAGC,KAAEA,GAASU,KAAKU,MAChC,MAAMP,EAAUH,KAAKG,QACrB,MAAMiB,EAAcC,EAClBrB,KAAKR,aAAe,cACpBQ,KAAKP,OAAS,SAGhB,OACE6B,EAACC,EAAI,CAAAC,IAAA,4CACHF,EAAA,OAAAE,IAAA,2CAAKC,MAAM,QAAQC,KAAK,UACpB1B,KAAKT,OAASS,KAAKN,YACnB4B,EAAA,OAAAE,IAAA,2CAAKC,MAAM,SAASC,KAAK,UACtB1B,KAAKT,MACJ+B,EAAA,SAAOG,MAAM,QAAQC,KAAK,QAAQC,QAAQ,SACvC3B,KAAKT,OAGR+B,EAAA,aAEDtB,KAAKN,WAGJ4B,EAAA,QAAAE,IAAA,2CAAMC,MAAM,QAAQC,KAAK,QAAO,cAAa,QAC1CE,KAAKC,MAAM1B,KAMpBmB,EAAA,SAAAE,IAAA,2CACEM,GAAG,QACHJ,KAAK,QACLD,MAAO,CAAEM,OAAQ,KAAM,kBAAmBC,QAAQhC,KAAKP,QACvDwC,KAAK,QACL/C,KAAMc,KAAKd,KACXC,MAAO,GAAGgB,IACVf,IAAK,GAAGA,IACRC,IAAK,GAAGA,IACRC,KAAM,GAAGA,IACTK,SAAUK,KAAKL,SAAQ,eACTK,KAAKP,MAAQ,OAAS,KAAI,mBACtB2B,EAClBN,QAASd,KAAKc,QACdI,SAAUlB,KAAKkB,SACfgB,MAAO,CAAE,uBAAwB,GAAGC,EAAgBhC,EAASf,EAAKC,SAGnEW,KAAKR,aACJ8B,EAAA,KAAAE,IAAA,2CAAGC,MAAM,cAAcC,KAAK,cAAcI,GAAG,eAC1C9B,KAAKR,aAGTQ,KAAKP,OACJ6B,EAAA,KAAAE,IAAA,2CAAGC,MAAM,QAAQC,KAAK,QAAQI,GAAG,SAC9B9B,KAAKP,Q","ignoreList":[]}
@@ -1,2 +0,0 @@
1
- import{r as e,c as t,a as i,h as r,H as n}from"./p-Bm6UxEit.js";import{o,p as a}from"./p-CC7AyfOt.js";import{c as s}from"./p-DfpCerXM.js";import{K as l}from"./p-g4FlTDZx.js";import{a as c}from"./p-Cr6IXrUk.js";var p=e=>String(e).padStart(2,"0");function d(e){const t=/^(\d{1,2}):(\d{2})$/.exec((e??"").trim());if(!t)return{hour:null,minute:null};const i=Number(t[1]);const r=Number(t[2]);if(i>23||r>59)return{hour:null,minute:null};return{hour:i,minute:r}}function u(e){if(e.hour===null||e.minute===null)return"";return`${p(e.hour)}:${p(e.minute)}`}function h(e,t){if(e.hour===null||e.minute===null)return"";if(t===24)return`${p(e.hour)}:${p(e.minute)}`;return`${m(e.hour)}:${p(e.minute)} ${f(e.hour)}`}function f(e){return e<12?"AM":"PM"}function m(e){const t=e%12;return t===0?12:t}function b(e,t){const i=e%12;return t==="PM"?i+12:i}function g(e,t=1){const i=Math.max(1,Math.floor(t));const r=Math.ceil(e/i);return Array.from({length:r},((e,t)=>t*i))}function v(e){return e===24?g(24):g(12).map((e=>e+1))}const y=()=>`:host{display:block}:host([hidden]){display:none}.field{display:grid;gap:var(--space-1)}.label{color:var(--pf-timepicker-text);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium)}.required{color:var(--pf-timepicker-invalid-border);margin-inline-start:var(--space-1)}.trigger{align-items:center;background:var(--pf-timepicker-bg);border:1px solid var(--pf-timepicker-border);border-radius:var(--radius-md);color:var(--pf-timepicker-text);cursor:pointer;display:flex;font-family:inherit;font-size:var(--font-size-sm);gap:var(--space-2);justify-content:space-between;padding:var(--space-2) var(--space-3);text-align:start;width:100%}.trigger:focus-visible{border-color:var(--pf-timepicker-focus-border);box-shadow:var(--pf-focus-ring);outline:none}.trigger:disabled{cursor:not-allowed;opacity:0.6}.trigger--invalid{border-color:var(--pf-timepicker-invalid-border)}.value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.value--placeholder{color:var(--pf-timepicker-placeholder)}.description{color:var(--pf-timepicker-text-muted);font-size:var(--font-size-xs);margin:0}.error{color:var(--pf-timepicker-invalid-border);font-size:var(--font-size-xs);margin:0}.panel{inset:auto;margin:0;background:var(--pf-timepicker-menu-bg);border:1px solid var(--pf-timepicker-menu-border);border-radius:var(--radius-md);box-shadow:var(--pf-elevation-popover-shadow);display:flex;gap:var(--space-1);padding:var(--space-1)}.panel:popover-open{animation:pf-time-picker-in var(--pf-transition-enter)}@keyframes pf-time-picker-in{from{opacity:0;transform:translateY(-4px)}}@media (prefers-reduced-motion: reduce){.panel:popover-open{animation:none}}.column{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow-y:auto;scrollbar-width:thin}.column:focus-visible{outline:none}.option{background:none;border:0;border-radius:var(--radius-sm);color:var(--pf-timepicker-text);cursor:pointer;font-family:inherit;font-size:var(--font-size-sm);font-variant-numeric:tabular-nums;padding:var(--space-1) var(--space-3);text-align:center}.option:hover{background:var(--pf-timepicker-option-hover-bg)}.option:focus-visible{box-shadow:var(--pf-focus-ring);outline:none}.option--selected{background:var(--pf-timepicker-option-active-bg);color:var(--pf-timepicker-option-active-text)}`;const k=class{constructor(i){e(this,i);this.pfChange=t(this,"pfChange");this.pfOpenChange=t(this,"pfOpenChange");if(i.$hostElement$["s-ei"]){this.internals=i.$hostElement$["s-ei"]}else{this.internals=i.$hostElement$.attachInternals();i.$hostElement$["s-ei"]=this.internals}}get el(){return i(this)}internals;name;value="";open=false;hourCycle=24;minuteStep=1;label;description;error;placeholder="Select time";required=false;disabled=false;pfChange;pfOpenChange;initialValue="";stopObserving;componentWillLoad(){this.initialValue=this.value??"";this.syncFormState()}componentDidRender(){if(this.open)this.scrollSelectedIntoView()}disconnectedCallback(){this.stopObserving?.()}syncFormState(){this.internals.setFormValue(this.value||null);c(this.internals,Boolean(this.value),this.required,this.error)}syncOpen(e,t){if(e)this.showPanel();else this.hidePanel();if(e!==t)this.pfOpenChange.emit({open:e})}async show(){if(!this.disabled)this.open=true}async hide(){this.open=false}async checkValidity(){return this.internals.checkValidity()}async reportValidity(){return this.internals.reportValidity()}async getValidationMessage(){return this.internals.validationMessage}formResetCallback(){this.value=this.initialValue}get cycle(){return Number(this.hourCycle)===12?12:24}get panel(){return this.el.shadowRoot?.querySelector('[part="panel"]')??null}get trigger(){return this.el.shadowRoot?.querySelector('[part="trigger"]')??null}get parts(){return d(this.value)}showPanel(){const e=this.panel;if(this.disabled||!e||e.matches(":popover-open"))return;e.showPopover();this.stopObserving?.();this.stopObserving=o({getAnchor:()=>this.trigger,getFloating:()=>e,align:"start",matchAnchorWidth:false,flip:true,onChange:({left:t,top:i})=>a(e,t,i)});this.scrollSelectedIntoView();e.querySelector('[data-selected="true"]')?.focus()}hidePanel(){this.stopObserving?.();this.stopObserving=undefined;const e=this.panel;if(e?.matches(":popover-open"))e.hidePopover()}scrollSelectedIntoView(){for(const e of Array.from(this.panel?.querySelectorAll('[data-selected="true"]')??[])){if(typeof e.scrollIntoView==="function"){e.scrollIntoView({block:"center"})}}}onToggle=e=>{const t=e.newState==="open";if(this.open!==t)this.open=t;if(!t)this.trigger?.focus()};commit(e){const t=u(e);if(!t||t===this.value)return;this.value=t;this.pfChange.emit({value:t})}selectHour(e){const t=this.cycle===24?e:b(e,this.selectedMeridiem()??"AM");this.commit({hour:t,minute:this.parts.minute??0})}selectMinute(e){this.commit({hour:this.parts.hour??0,minute:e})}selectMeridiem(e){const{hour:t,minute:i}=this.parts;this.commit({hour:b(m(t??0),e),minute:i??0})}selectedMeridiem(){const{hour:e}=this.parts;return e===null?null:f(e)}onColumnKeyDown=e=>{if(e.key!==l.ArrowDown&&e.key!==l.ArrowUp)return;const t=e.currentTarget;const i=Array.from(t.querySelectorAll("button"));const r=i.indexOf(this.el.shadowRoot?.activeElement);if(r===-1)return;e.preventDefault();const n=e.key===l.ArrowDown?r+1:r-1;i[Math.min(Math.max(n,0),i.length-1)]?.focus()};renderColumn(e,t){return r("div",{class:"column",part:"column",role:"listbox","aria-label":e,tabindex:-1,onKeyDown:this.onColumnKeyDown},t.map((e=>r("button",{key:e.key,type:"button",part:"option",class:{option:true,"option--selected":e.selected},role:"option","aria-selected":e.selected?"true":"false","data-selected":e.selected?"true":"false",onClick:e.onSelect},e.label))))}render(){const e=s(this.description&&"description",this.error&&"error");const{hour:t,minute:i}=this.parts;const o=h(this.parts,this.cycle);const a=t===null?null:this.cycle===24?t:m(t);const l=this.selectedMeridiem();return r(n,{key:"8397a5200df46b5834039d4356dfa21b8ff04900"},r("div",{key:"5b28cd916ea6fb07080b7ccb953cb46f3f50e2a1",class:"field",part:"field"},this.label&&r("label",{key:"dca55c09008da4d20087f89e9574332ed5750c05",class:"label",part:"label",htmlFor:"trigger"},this.label,this.required&&r("span",{key:"85dc9a7dde71ff2b8a73cacffb432a006c2244ab",class:"required","aria-hidden":"true"},"*")),r("button",{key:"e0860a424c00c771a7f384f210c570707596dd42",id:"trigger",part:"trigger",class:{trigger:true,"trigger--invalid":Boolean(this.error)},type:"button",disabled:this.disabled,"aria-haspopup":"dialog","aria-expanded":this.open?"true":"false","aria-controls":"panel","aria-invalid":this.error?"true":null,"aria-required":this.required?"true":null,"aria-describedby":e,onClick:()=>{if(!this.disabled)this.open=!this.open}},r("span",{key:"03c67a53cf957fc1f3d18ae291cf6216b6fce11f",class:{value:true,"value--placeholder":!o}},o||this.placeholder),r("pf-icon",{key:"72f2cf8f61d3b547436edc0f9080ce141f989f46",name:"clock"})),this.description&&r("p",{key:"b891c75c8942c32d920aaab2a82476f3ff5879ab",class:"description",part:"description",id:"description"},this.description),this.error&&r("p",{key:"64b4eae8a178da68308e5c641ad3144b29373339",class:"error",part:"error",id:"error"},this.error)),r("div",{key:"c29b038ea9d75b0ecac1f4f79b2e915e827b5859",id:"panel",part:"panel",class:"panel",popover:"auto",role:"dialog","aria-label":"Choose a time",onToggle:this.onToggle},this.renderColumn("Hour",v(this.cycle).map((e=>({key:`h-${e}`,label:p(e),selected:a===e,onSelect:()=>this.selectHour(e)})))),this.renderColumn("Minute",g(60,this.minuteStep).map((e=>({key:`m-${e}`,label:p(e),selected:i===e,onSelect:()=>this.selectMinute(e)})))),this.cycle===12&&this.renderColumn("AM or PM",["AM","PM"].map((e=>({key:e,label:e,selected:l===e,onSelect:()=>this.selectMeridiem(e)}))))))}static get formAssociated(){return true}static get watchers(){return{value:[{syncFormState:0}],error:[{syncFormState:0}],required:[{syncFormState:0}],open:[{syncOpen:0}]}}};k.style=y();export{k as pf_time_picker};
2
- //# sourceMappingURL=p-5064d2dd.entry.js.map