@pearpages/pulp-react 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/README.md +14 -0
  2. package/dist/accordion.js +1 -1
  3. package/dist/alert.css +18 -0
  4. package/dist/alert.css.map +1 -1
  5. package/dist/alert.js +4 -4
  6. package/dist/avatar.css +46 -0
  7. package/dist/avatar.css.map +1 -0
  8. package/dist/avatar.d.ts +41 -0
  9. package/dist/avatar.js +5 -0
  10. package/dist/avatar.js.map +1 -0
  11. package/dist/badge.css +37 -0
  12. package/dist/badge.css.map +1 -1
  13. package/dist/badge.d.ts +22 -5
  14. package/dist/badge.js +2 -1
  15. package/dist/button.css +18 -0
  16. package/dist/button.css.map +1 -1
  17. package/dist/button.d.ts +11 -2
  18. package/dist/button.js +2 -2
  19. package/dist/calendar.js +1 -1
  20. package/dist/card.js +2 -2
  21. package/dist/checkbox.js +4 -4
  22. package/dist/chip.css +95 -0
  23. package/dist/chip.css.map +1 -0
  24. package/dist/chip.d.ts +43 -0
  25. package/dist/chip.js +4 -0
  26. package/dist/chip.js.map +1 -0
  27. package/dist/{chunk-N6E2E2OY.js → chunk-2NVC3C7K.js} +3 -3
  28. package/dist/{chunk-N6E2E2OY.js.map → chunk-2NVC3C7K.js.map} +1 -1
  29. package/dist/{chunk-MF66ICX6.js → chunk-56RSH7GQ.js} +3 -3
  30. package/dist/{chunk-MF66ICX6.js.map → chunk-56RSH7GQ.js.map} +1 -1
  31. package/dist/chunk-5TYCIBLW.js +27 -0
  32. package/dist/chunk-5TYCIBLW.js.map +1 -0
  33. package/dist/chunk-7O6FTCZL.js +101 -0
  34. package/dist/chunk-7O6FTCZL.js.map +1 -0
  35. package/dist/{chunk-N4C3NQIN.js → chunk-A7TMFEQ2.js} +3 -3
  36. package/dist/{chunk-N4C3NQIN.js.map → chunk-A7TMFEQ2.js.map} +1 -1
  37. package/dist/{chunk-2NSQPN7S.js → chunk-AZAI4OVR.js} +3 -3
  38. package/dist/{chunk-2NSQPN7S.js.map → chunk-AZAI4OVR.js.map} +1 -1
  39. package/dist/{chunk-DVZ46GQN.js → chunk-CLE2QGCU.js} +3 -3
  40. package/dist/{chunk-DVZ46GQN.js.map → chunk-CLE2QGCU.js.map} +1 -1
  41. package/dist/{chunk-5TTYVQ6Q.js → chunk-DE67ECD7.js} +5 -3
  42. package/dist/chunk-DE67ECD7.js.map +1 -0
  43. package/dist/{chunk-BAPNIZDV.js → chunk-F2YI5N4L.js} +3 -3
  44. package/dist/chunk-F2YI5N4L.js.map +1 -0
  45. package/dist/{chunk-U3N3G2UA.js → chunk-FFCEY76B.js} +10 -5
  46. package/dist/chunk-FFCEY76B.js.map +1 -0
  47. package/dist/{chunk-XWPXW46D.js → chunk-GWTHITZO.js} +3 -3
  48. package/dist/{chunk-XWPXW46D.js.map → chunk-GWTHITZO.js.map} +1 -1
  49. package/dist/chunk-HDC2IQV2.js +34 -0
  50. package/dist/chunk-HDC2IQV2.js.map +1 -0
  51. package/dist/{chunk-VQN5DQP6.js → chunk-HKNIEQ2V.js} +4 -4
  52. package/dist/{chunk-VQN5DQP6.js.map → chunk-HKNIEQ2V.js.map} +1 -1
  53. package/dist/{chunk-LA3YBXCR.js → chunk-HPQ462R5.js} +3 -3
  54. package/dist/{chunk-LA3YBXCR.js.map → chunk-HPQ462R5.js.map} +1 -1
  55. package/dist/chunk-KSLKNWWM.js +28 -0
  56. package/dist/chunk-KSLKNWWM.js.map +1 -0
  57. package/dist/chunk-OKA2PLDV.js +85 -0
  58. package/dist/chunk-OKA2PLDV.js.map +1 -0
  59. package/dist/{chunk-6BIEW4WJ.js → chunk-Q6SYKNZ5.js} +3 -3
  60. package/dist/{chunk-6BIEW4WJ.js.map → chunk-Q6SYKNZ5.js.map} +1 -1
  61. package/dist/chunk-QID6YYFF.js +33 -0
  62. package/dist/chunk-QID6YYFF.js.map +1 -0
  63. package/dist/{chunk-ZVDN3GRI.js → chunk-QJG5ILK5.js} +3 -3
  64. package/dist/{chunk-ZVDN3GRI.js.map → chunk-QJG5ILK5.js.map} +1 -1
  65. package/dist/chunk-QXHSA4QD.js +43 -0
  66. package/dist/chunk-QXHSA4QD.js.map +1 -0
  67. package/dist/chunk-S632WN4W.js +106 -0
  68. package/dist/chunk-S632WN4W.js.map +1 -0
  69. package/dist/{chunk-OFFFRIJG.js → chunk-SDIK6VSC.js} +3 -3
  70. package/dist/{chunk-OFFFRIJG.js.map → chunk-SDIK6VSC.js.map} +1 -1
  71. package/dist/{chunk-M5VL22MY.js → chunk-SXMORGSG.js} +3 -3
  72. package/dist/{chunk-M5VL22MY.js.map → chunk-SXMORGSG.js.map} +1 -1
  73. package/dist/{chunk-Z6SS4G4V.js → chunk-UMK4D234.js} +3 -3
  74. package/dist/{chunk-Z6SS4G4V.js.map → chunk-UMK4D234.js.map} +1 -1
  75. package/dist/{chunk-5PYLJQJX.js → chunk-VS2HPJIX.js} +3 -3
  76. package/dist/{chunk-5PYLJQJX.js.map → chunk-VS2HPJIX.js.map} +1 -1
  77. package/dist/{chunk-NOUUOH4R.js → chunk-WDIFWMKE.js} +3 -3
  78. package/dist/chunk-WDIFWMKE.js.map +1 -0
  79. package/dist/chunk-Y7KC2FDU.js +88 -0
  80. package/dist/chunk-Y7KC2FDU.js.map +1 -0
  81. package/dist/{chunk-OFKSU77Y.js → chunk-ZEVQQQOA.js} +3 -3
  82. package/dist/{chunk-OFKSU77Y.js.map → chunk-ZEVQQQOA.js.map} +1 -1
  83. package/dist/combobox.css +3 -0
  84. package/dist/combobox.css.map +1 -1
  85. package/dist/combobox.js +2 -2
  86. package/dist/component-manifest.json +679 -8
  87. package/dist/date-picker.js +1 -1
  88. package/dist/dialog.js +1 -1
  89. package/dist/divider.css +37 -0
  90. package/dist/divider.css.map +1 -0
  91. package/dist/divider.d.ts +35 -0
  92. package/dist/divider.js +4 -0
  93. package/dist/divider.js.map +1 -0
  94. package/dist/empty-state.css +175 -0
  95. package/dist/empty-state.css.map +1 -0
  96. package/dist/empty-state.d.ts +40 -0
  97. package/dist/empty-state.js +7 -0
  98. package/dist/empty-state.js.map +1 -0
  99. package/dist/field.js +2 -2
  100. package/dist/icon-button.css +18 -0
  101. package/dist/icon-button.css.map +1 -1
  102. package/dist/icon-button.js +3 -3
  103. package/dist/index.css +489 -0
  104. package/dist/index.css.map +1 -1
  105. package/dist/index.d.ts +8 -2
  106. package/dist/index.js +38 -32
  107. package/dist/link.css +35 -0
  108. package/dist/link.css.map +1 -0
  109. package/dist/link.d.ts +37 -0
  110. package/dist/link.js +5 -0
  111. package/dist/link.js.map +1 -0
  112. package/dist/listbox.js +1 -1
  113. package/dist/menu.js +2 -2
  114. package/dist/pagination.css +18 -0
  115. package/dist/pagination.css.map +1 -1
  116. package/dist/pagination.js +4 -4
  117. package/dist/picker.css +3 -0
  118. package/dist/picker.css.map +1 -1
  119. package/dist/picker.js +2 -2
  120. package/dist/popover.js +2 -2
  121. package/dist/radio.js +3 -3
  122. package/dist/segmented-control.css +111 -0
  123. package/dist/segmented-control.css.map +1 -0
  124. package/dist/segmented-control.d.ts +90 -0
  125. package/dist/segmented-control.js +5 -0
  126. package/dist/segmented-control.js.map +1 -0
  127. package/dist/select.js +3 -3
  128. package/dist/sheet.css +28 -0
  129. package/dist/sheet.css.map +1 -1
  130. package/dist/sheet.d.ts +9 -2
  131. package/dist/sheet.js +1 -1
  132. package/dist/slider.js +1 -1
  133. package/dist/switch.js +4 -4
  134. package/dist/table.js +1 -1
  135. package/dist/tabs.js +1 -1
  136. package/dist/text-field.css +63 -0
  137. package/dist/text-field.css.map +1 -1
  138. package/dist/text-field.d.ts +15 -2
  139. package/dist/text-field.js +3 -3
  140. package/dist/textarea.js +3 -3
  141. package/dist/toast.css +18 -0
  142. package/dist/toast.css.map +1 -1
  143. package/dist/toast.d.ts +21 -3
  144. package/dist/toast.js +5 -5
  145. package/dist/tooltip.js +2 -2
  146. package/package.json +36 -6
  147. package/dist/chunk-5TTYVQ6Q.js.map +0 -1
  148. package/dist/chunk-737GQSOB.js +0 -19
  149. package/dist/chunk-737GQSOB.js.map +0 -1
  150. package/dist/chunk-BAPNIZDV.js.map +0 -1
  151. package/dist/chunk-IFIQLIA3.js +0 -48
  152. package/dist/chunk-IFIQLIA3.js.map +0 -1
  153. package/dist/chunk-NOUUOH4R.js.map +0 -1
  154. package/dist/chunk-TJJBCS3N.js +0 -28
  155. package/dist/chunk-TJJBCS3N.js.map +0 -1
  156. package/dist/chunk-U3N3G2UA.js.map +0 -1
@@ -0,0 +1,5 @@
1
+ "use client";export { SegmentedControl } from './chunk-Y7KC2FDU.js';
2
+ import './chunk-QJG5ILK5.js';
3
+ import './chunk-MI4QUKQS.js';
4
+ //# sourceMappingURL=segmented-control.js.map
5
+ //# sourceMappingURL=segmented-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"segmented-control.js"}
package/dist/select.js CHANGED
@@ -1,6 +1,6 @@
1
- export { Select } from './chunk-OFKSU77Y.js';
2
- import './chunk-M5VL22MY.js';
3
- import './chunk-ZVDN3GRI.js';
1
+ "use client";export { Select } from './chunk-ZEVQQQOA.js';
2
+ import './chunk-SXMORGSG.js';
3
+ import './chunk-QJG5ILK5.js';
4
4
  import './chunk-MI4QUKQS.js';
5
5
  //# sourceMappingURL=select.js.map
6
6
  //# sourceMappingURL=select.js.map
package/dist/sheet.css CHANGED
@@ -69,5 +69,33 @@
69
69
  --modal-height-sheet: var(--sheet-height);
70
70
  --modal-animation-translate-sheet: var(--sheet-motion-translate);
71
71
  }
72
+ .Sheet_content[data-draggable] {
73
+ translate: 0 var(--_drag, 0);
74
+ transition: translate var(--sheet-handle-snap-duration) var(--motion-easing-standard);
75
+ &[data-dragging] {
76
+ transition: none;
77
+ }
78
+ }
79
+ .Sheet_handle {
80
+ display: grid;
81
+ flex: none;
82
+ place-items: center;
83
+ block-size: var(--sheet-handle-hit-height);
84
+ cursor: grab;
85
+ touch-action: none;
86
+ &::before {
87
+ inline-size: var(--sheet-handle-width);
88
+ block-size: var(--sheet-handle-height);
89
+ border-radius: var(--sheet-handle-radius);
90
+ background: var(--sheet-handle-bg);
91
+ content: "";
92
+ }
93
+ [data-dragging] > & {
94
+ cursor: grabbing;
95
+ }
96
+ @media (prefers-reduced-motion: reduce) {
97
+ display: none;
98
+ }
99
+ }
72
100
  }
73
101
  /*# sourceMappingURL=sheet.css.map */
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dialog/Dialog.module.css","../src/sheet/Sheet.module.css"],"sourcesContent":["/*\n * The vendor (@pearpages/modals) reads --modal-* custom properties. This class\n * goes on the portal element pulp owns, so every dialog inherits pulp's\n * --dialog-* tokens and the vendor's :root defaults never apply.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .root {\n --modal-bg: var(--dialog-surface);\n --modal-surface-elevated: var(--dialog-surface);\n --modal-surface-subtle: var(--dialog-surface-subtle);\n --modal-color: var(--dialog-fg);\n --modal-text-secondary: var(--dialog-fg-muted);\n --modal-text-muted: var(--dialog-fg-muted);\n --modal-backdrop-bg: var(--dialog-backdrop);\n --modal-border-primary-color: var(--dialog-border);\n --modal-border-hover-color: var(--dialog-border-hover);\n --modal-border-focus-color: var(--dialog-focus);\n --modal-border-accent-color: var(--dialog-border);\n --modal-radius: var(--dialog-radius);\n --modal-radius-md: var(--dialog-radius);\n --modal-radius-sm: var(--radius-control);\n --modal-button-radius: var(--radius-control);\n --modal-shadow: var(--dialog-shadow);\n --modal-padding: var(--dialog-padding);\n --modal-spacing-xs: var(--space-1);\n --modal-spacing-sm: var(--space-2);\n --modal-spacing-md: var(--dialog-gap);\n --modal-spacing-lg: var(--space-4);\n --modal-spacing-xl: var(--space-5);\n --modal-font-family: var(--dialog-font-family);\n --modal-font-family-mono: var(--font-family-mono);\n --modal-font-size-title: var(--dialog-title-font-size);\n --modal-font-size-title-mobile: var(--dialog-title-font-size);\n --modal-font-weight-title: var(--dialog-title-font-weight);\n --modal-font-size-description: var(--dialog-description-font-size);\n --modal-font-size-description-mobile: var(--dialog-description-font-size);\n --modal-font-size-button: var(--font-size-sm);\n --modal-close-bg: var(--dialog-close-bg);\n --modal-close-hover-bg: var(--dialog-close-bg-hover);\n --modal-close-text: var(--dialog-close-fg);\n --modal-close-hover-text: var(--dialog-close-fg-hover);\n --modal-interactive-hover: var(--color-action-secondary-hover);\n --modal-interactive-active: var(--color-action-secondary-hover);\n --modal-interactive-focus: var(--color-action-primary-quiet);\n --modal-transition-duration: var(--dialog-motion-duration);\n --modal-transition-easing: var(--dialog-motion-easing);\n --modal-outline-width: var(--focus-ring-width);\n --modal-outline-offset: var(--focus-ring-offset);\n --modal-button-focus-color: var(--dialog-focus);\n --modal-button-primary-bg: var(--color-action-primary);\n --modal-button-primary-border: var(--color-action-primary);\n --modal-button-primary-color: var(--color-text-on-action);\n --modal-button-primary-hover-bg: var(--color-action-primary-hover);\n --modal-button-primary-hover-border: var(--color-action-primary-hover);\n --modal-button-primary-active-bg: var(--color-action-primary-active);\n --modal-button-primary-active-border: var(--color-action-primary-active);\n --modal-button-secondary-bg: var(--color-action-secondary);\n --modal-button-secondary-border: var(--color-border-default);\n --modal-button-secondary-color: var(--color-text-default);\n --modal-button-secondary-hover-bg: var(--color-action-secondary-hover);\n --modal-button-secondary-hover-border: var(--color-border-strong);\n --modal-button-secondary-active-bg: var(--color-action-secondary-hover);\n --modal-button-secondary-active-border: var(--color-border-strong);\n }\n}\n","/*\n * The vendor (@pearpages/modals) docks the dialog and sizes it from three variables it declares on\n * :root. This class sits on the dialog element itself, so its own declarations beat the inherited\n * :root defaults whatever the cascade layer or import order: no specificity fight with the\n * vendor's unlayered rules, which only *read* these. Colour, type and motion timing come from\n * Dialog's mapping on the portal root.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .content {\n --modal-width-sheet: var(--sheet-width);\n --modal-height-sheet: var(--sheet-height);\n --modal-animation-translate-sheet: var(--sheet-motion-translate);\n }\n}\n"],"mappings":";AAMA;AAEA;AACE,GAACA;AACC,gBAAY,IAAI;AAChB,8BAA0B,IAAI;AAC9B,4BAAwB,IAAI;AAC5B,mBAAe,IAAI;AACnB,4BAAwB,IAAI;AAC5B,wBAAoB,IAAI;AACxB,yBAAqB,IAAI;AACzB,kCAA8B,IAAI;AAClC,gCAA4B,IAAI;AAChC,gCAA4B,IAAI;AAChC,iCAA6B,IAAI;AACjC,oBAAgB,IAAI;AACpB,uBAAmB,IAAI;AACvB,uBAAmB,IAAI;AACvB,2BAAuB,IAAI;AAC3B,oBAAgB,IAAI;AACpB,qBAAiB,IAAI;AACrB,wBAAoB,IAAI;AACxB,wBAAoB,IAAI;AACxB,wBAAoB,IAAI;AACxB,wBAAoB,IAAI;AACxB,wBAAoB,IAAI;AACxB,yBAAqB,IAAI;AACzB,8BAA0B,IAAI;AAC9B,6BAAyB,IAAI;AAC7B,oCAAgC,IAAI;AACpC,+BAA2B,IAAI;AAC/B,mCAA+B,IAAI;AACnC,0CAAsC,IAAI;AAC1C,8BAA0B,IAAI;AAC9B,sBAAkB,IAAI;AACtB,4BAAwB,IAAI;AAC5B,wBAAoB,IAAI;AACxB,8BAA0B,IAAI;AAC9B,+BAA2B,IAAI;AAC/B,gCAA4B,IAAI;AAChC,+BAA2B,IAAI;AAC/B,iCAA6B,IAAI;AACjC,+BAA2B,IAAI;AAC/B,2BAAuB,IAAI;AAC3B,4BAAwB,IAAI;AAC5B,gCAA4B,IAAI;AAChC,+BAA2B,IAAI;AAC/B,mCAA+B,IAAI;AACnC,kCAA8B,IAAI;AAClC,qCAAiC,IAAI;AACrC,yCAAqC,IAAI;AACzC,sCAAkC,IAAI;AACtC,0CAAsC,IAAI;AAC1C,iCAA6B,IAAI;AACjC,qCAAiC,IAAI;AACrC,oCAAgC,IAAI;AACpC,uCAAmC,IAAI;AACvC,2CAAuC,IAAI;AAC3C,wCAAoC,IAAI;AACxC,4CAAwC,IAAI;AAC9C;AACF;;;AC3DA;AAEA;AACE,GAACC;AACC,yBAAqB,IAAI;AACzB,0BAAsB,IAAI;AAC1B,uCAAmC,IAAI;AACzC;AACF;","names":["root","content"]}
1
+ {"version":3,"sources":["../src/dialog/Dialog.module.css","../src/sheet/Sheet.module.css"],"sourcesContent":["/*\n * The vendor (@pearpages/modals) reads --modal-* custom properties. This class\n * goes on the portal element pulp owns, so every dialog inherits pulp's\n * --dialog-* tokens and the vendor's :root defaults never apply.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .root {\n --modal-bg: var(--dialog-surface);\n --modal-surface-elevated: var(--dialog-surface);\n --modal-surface-subtle: var(--dialog-surface-subtle);\n --modal-color: var(--dialog-fg);\n --modal-text-secondary: var(--dialog-fg-muted);\n --modal-text-muted: var(--dialog-fg-muted);\n --modal-backdrop-bg: var(--dialog-backdrop);\n --modal-border-primary-color: var(--dialog-border);\n --modal-border-hover-color: var(--dialog-border-hover);\n --modal-border-focus-color: var(--dialog-focus);\n --modal-border-accent-color: var(--dialog-border);\n --modal-radius: var(--dialog-radius);\n --modal-radius-md: var(--dialog-radius);\n --modal-radius-sm: var(--radius-control);\n --modal-button-radius: var(--radius-control);\n --modal-shadow: var(--dialog-shadow);\n --modal-padding: var(--dialog-padding);\n --modal-spacing-xs: var(--space-1);\n --modal-spacing-sm: var(--space-2);\n --modal-spacing-md: var(--dialog-gap);\n --modal-spacing-lg: var(--space-4);\n --modal-spacing-xl: var(--space-5);\n --modal-font-family: var(--dialog-font-family);\n --modal-font-family-mono: var(--font-family-mono);\n --modal-font-size-title: var(--dialog-title-font-size);\n --modal-font-size-title-mobile: var(--dialog-title-font-size);\n --modal-font-weight-title: var(--dialog-title-font-weight);\n --modal-font-size-description: var(--dialog-description-font-size);\n --modal-font-size-description-mobile: var(--dialog-description-font-size);\n --modal-font-size-button: var(--font-size-sm);\n --modal-close-bg: var(--dialog-close-bg);\n --modal-close-hover-bg: var(--dialog-close-bg-hover);\n --modal-close-text: var(--dialog-close-fg);\n --modal-close-hover-text: var(--dialog-close-fg-hover);\n --modal-interactive-hover: var(--color-action-secondary-hover);\n --modal-interactive-active: var(--color-action-secondary-hover);\n --modal-interactive-focus: var(--color-action-primary-quiet);\n --modal-transition-duration: var(--dialog-motion-duration);\n --modal-transition-easing: var(--dialog-motion-easing);\n --modal-outline-width: var(--focus-ring-width);\n --modal-outline-offset: var(--focus-ring-offset);\n --modal-button-focus-color: var(--dialog-focus);\n --modal-button-primary-bg: var(--color-action-primary);\n --modal-button-primary-border: var(--color-action-primary);\n --modal-button-primary-color: var(--color-text-on-action);\n --modal-button-primary-hover-bg: var(--color-action-primary-hover);\n --modal-button-primary-hover-border: var(--color-action-primary-hover);\n --modal-button-primary-active-bg: var(--color-action-primary-active);\n --modal-button-primary-active-border: var(--color-action-primary-active);\n --modal-button-secondary-bg: var(--color-action-secondary);\n --modal-button-secondary-border: var(--color-border-default);\n --modal-button-secondary-color: var(--color-text-default);\n --modal-button-secondary-hover-bg: var(--color-action-secondary-hover);\n --modal-button-secondary-hover-border: var(--color-border-strong);\n --modal-button-secondary-active-bg: var(--color-action-secondary-hover);\n --modal-button-secondary-active-border: var(--color-border-strong);\n }\n}\n","/*\n * The vendor (@pearpages/modals) docks the dialog and sizes it from three variables it declares on\n * :root. This class sits on the dialog element itself, so its own declarations beat the inherited\n * :root defaults whatever the cascade layer or import order: no specificity fight with the\n * vendor's unlayered rules, which only *read* these. Colour, type and motion timing come from\n * Dialog's mapping on the portal root.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .content {\n --modal-width-sheet: var(--sheet-width);\n --modal-height-sheet: var(--sheet-height);\n --modal-animation-translate-sheet: var(--sheet-motion-translate);\n }\n\n /*\n * Drag to dismiss (bottom sheets). The vendor moves the sheet with `transform`; the drag uses\n * the separate `translate` property, so the two never fight. --_drag is set by the handle while\n * the pointer is down: the one per-instance value, like Progress's --_value.\n */\n .content[data-draggable] {\n translate: 0 var(--_drag, 0);\n transition: translate var(--sheet-handle-snap-duration) var(--motion-easing-standard);\n\n &[data-dragging] {\n transition: none;\n }\n }\n\n .handle {\n display: grid;\n flex: none;\n place-items: center;\n block-size: var(--sheet-handle-hit-height);\n cursor: grab;\n touch-action: none;\n\n &::before {\n inline-size: var(--sheet-handle-width);\n block-size: var(--sheet-handle-height);\n border-radius: var(--sheet-handle-radius);\n background: var(--sheet-handle-bg);\n content: \"\";\n }\n\n [data-dragging] > & {\n cursor: grabbing;\n }\n\n /* Following the finger is motion: without it there is no handle to offer. */\n @media (prefers-reduced-motion: reduce) {\n display: none;\n }\n }\n}\n"],"mappings":";AAMA;AAEA;AACE,GAACA;AACC,gBAAY,IAAI;AAChB,8BAA0B,IAAI;AAC9B,4BAAwB,IAAI;AAC5B,mBAAe,IAAI;AACnB,4BAAwB,IAAI;AAC5B,wBAAoB,IAAI;AACxB,yBAAqB,IAAI;AACzB,kCAA8B,IAAI;AAClC,gCAA4B,IAAI;AAChC,gCAA4B,IAAI;AAChC,iCAA6B,IAAI;AACjC,oBAAgB,IAAI;AACpB,uBAAmB,IAAI;AACvB,uBAAmB,IAAI;AACvB,2BAAuB,IAAI;AAC3B,oBAAgB,IAAI;AACpB,qBAAiB,IAAI;AACrB,wBAAoB,IAAI;AACxB,wBAAoB,IAAI;AACxB,wBAAoB,IAAI;AACxB,wBAAoB,IAAI;AACxB,wBAAoB,IAAI;AACxB,yBAAqB,IAAI;AACzB,8BAA0B,IAAI;AAC9B,6BAAyB,IAAI;AAC7B,oCAAgC,IAAI;AACpC,+BAA2B,IAAI;AAC/B,mCAA+B,IAAI;AACnC,0CAAsC,IAAI;AAC1C,8BAA0B,IAAI;AAC9B,sBAAkB,IAAI;AACtB,4BAAwB,IAAI;AAC5B,wBAAoB,IAAI;AACxB,8BAA0B,IAAI;AAC9B,+BAA2B,IAAI;AAC/B,gCAA4B,IAAI;AAChC,+BAA2B,IAAI;AAC/B,iCAA6B,IAAI;AACjC,+BAA2B,IAAI;AAC/B,2BAAuB,IAAI;AAC3B,4BAAwB,IAAI;AAC5B,gCAA4B,IAAI;AAChC,+BAA2B,IAAI;AAC/B,mCAA+B,IAAI;AACnC,kCAA8B,IAAI;AAClC,qCAAiC,IAAI;AACrC,yCAAqC,IAAI;AACzC,sCAAkC,IAAI;AACtC,0CAAsC,IAAI;AAC1C,iCAA6B,IAAI;AACjC,qCAAiC,IAAI;AACrC,oCAAgC,IAAI;AACpC,uCAAmC,IAAI;AACvC,2CAAuC,IAAI;AAC3C,wCAAoC,IAAI;AACxC,4CAAwC,IAAI;AAC9C;AACF;;;AC3DA;AAEA;AACE,GAACC;AACC,yBAAqB,IAAI;AACzB,0BAAsB,IAAI;AAC1B,uCAAmC,IAAI;AACzC;AAOA,GAXCA,aAWO,CAAC;AACP,eAAW,EAAE,IAAI,OAAO,EAAE;AAC1B,gBAAY,UAAU,IAAI,8BAA8B,IAAI;AAE5D,KAAC,CAAC;AACA,kBAAY;AACd;AACF;AAEA,GAACC;AACC,aAAS;AACT,UAAM;AACN,iBAAa;AACb,gBAAY,IAAI;AAChB,YAAQ;AACR,kBAAc;AAEd,KAAC;AACC,mBAAa,IAAI;AACjB,kBAAY,IAAI;AAChB,qBAAe,IAAI;AACnB,kBAAY,IAAI;AAChB,eAAS;AACX;AAEA,KAAC,eAAe,EAAE;AAChB,cAAQ;AACV;AAGA,YAAO,wBAAyB;AAC9B,eAAS;AACX;AACF;AACF;","names":["root","content","handle"]}
package/dist/sheet.d.ts CHANGED
@@ -14,6 +14,13 @@ interface SheetContentProps extends Omit<ComponentProps<typeof Dialog.Content>,
14
14
  * @default 'end'
15
15
  */
16
16
  placement?: SheetPlacement;
17
+ /**
18
+ * `placement="bottom"` only: a grab handle at the top of the sheet that can be dragged down to
19
+ * close it (past a quarter of the sheet's height, or with a flick). Pointer and touch only, and
20
+ * off under `prefers-reduced-motion`; Escape, the backdrop and `Sheet.Close` are unchanged.
21
+ * @default true
22
+ */
23
+ dragToDismiss?: boolean;
17
24
  }
18
25
  /**
19
26
  * A dialog docked to an edge of the viewport: a side panel for detail or settings that keeps the
@@ -28,7 +35,7 @@ interface SheetContentProps extends Omit<ComponentProps<typeof Dialog.Content>,
28
35
  *
29
36
  * @status experimental
30
37
  * @category Overlays
31
- * @accessibility Dialog's: `role="dialog"` with `aria-modal`, named by `Sheet.Title` and described by `Sheet.Description`; focus moves in on open, is trapped, and returns to the trigger on close; Escape and the backdrop dismiss it; the page behind is inert. Docking changes the layout only, never the semantics.
38
+ * @accessibility The drag handle of a bottom sheet is a pointer and touch shortcut, hidden from assistive technology and not focusable: it adds no keyboard stop, and closing by keyboard stays Escape or `Sheet.Close`, so always render a `Sheet.Close` in a sheet that can be dragged. Otherwise Dialog's: `role="dialog"` with `aria-modal`, named by `Sheet.Title` and described by `Sheet.Description`; focus moves in on open, is trapped, and returns to the trigger on close; Escape and the backdrop dismiss it; the page behind is inert. Docking changes the layout only, never the semantics.
32
39
  * @do Always render a `Sheet.Title`.
33
40
  * @do Dock to `end` for detail and settings beside the page, and to `bottom` for choices on a narrow screen.
34
41
  * @dont Use it for a short confirmation; a centred Dialog reads as more urgent and takes less room.
@@ -50,7 +57,7 @@ declare namespace Sheet {
50
57
  * The docked dialog element. Dialog's `Content`, with `placement` and the class that maps pulp's
51
58
  * `--sheet-*` tokens onto the vendor's sheet variables.
52
59
  */
53
- declare function SheetContent({ placement, className, ...rest }: SheetContentProps): react.JSX.Element;
60
+ declare function SheetContent({ placement, dragToDismiss, className, children, ...rest }: SheetContentProps): react.JSX.Element;
54
61
  declare namespace SheetContent {
55
62
  var displayName: string;
56
63
  }
package/dist/sheet.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Sheet } from './chunk-TJJBCS3N.js';
1
+ "use client";export { Sheet } from './chunk-7O6FTCZL.js';
2
2
  import './chunk-55QUKGK2.js';
3
3
  import './chunk-MI4QUKQS.js';
4
4
  //# sourceMappingURL=sheet.js.map
package/dist/slider.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Slider } from './chunk-YBECKOVP.js';
1
+ "use client";export { Slider } from './chunk-YBECKOVP.js';
2
2
  import './chunk-DGIXNUNI.js';
3
3
  import './chunk-MI4QUKQS.js';
4
4
  //# sourceMappingURL=slider.js.map
package/dist/switch.js CHANGED
@@ -1,7 +1,7 @@
1
- export { Switch } from './chunk-DVZ46GQN.js';
2
- import './chunk-6BIEW4WJ.js';
3
- import './chunk-M5VL22MY.js';
4
- import './chunk-ZVDN3GRI.js';
1
+ "use client";export { Switch } from './chunk-CLE2QGCU.js';
2
+ import './chunk-Q6SYKNZ5.js';
3
+ import './chunk-SXMORGSG.js';
4
+ import './chunk-QJG5ILK5.js';
5
5
  import './chunk-MI4QUKQS.js';
6
6
  //# sourceMappingURL=switch.js.map
7
7
  //# sourceMappingURL=switch.js.map
package/dist/table.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Table } from './chunk-XGWFTFGR.js';
1
+ "use client";export { Table } from './chunk-XGWFTFGR.js';
2
2
  import './chunk-CZBCGLEM.js';
3
3
  import './chunk-IB5UUE3S.js';
4
4
  import './chunk-MI4QUKQS.js';
package/dist/tabs.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Tabs } from './chunk-2IYYES7V.js';
1
+ "use client";export { Tabs } from './chunk-2IYYES7V.js';
2
2
  import './chunk-I5OZ63W7.js';
3
3
  import './chunk-MI4QUKQS.js';
4
4
  //# sourceMappingURL=tabs.js.map
@@ -73,5 +73,68 @@
73
73
  .TextField_field[data-invalid] .TextField_input {
74
74
  border-color: var(--text-field-border-invalid);
75
75
  }
76
+ .TextField_hiddenLabel {
77
+ position: absolute;
78
+ inline-size: var(--size-hairline);
79
+ block-size: var(--size-hairline);
80
+ overflow: hidden;
81
+ clip-path: inset(50%);
82
+ white-space: nowrap;
83
+ }
84
+ .TextField_control {
85
+ --_slot: var(--text-field-height-md);
86
+ display: grid;
87
+ position: relative;
88
+ align-items: center;
89
+ .TextField_field[data-size=sm] & {
90
+ --_slot: var(--text-field-height-sm);
91
+ }
92
+ .TextField_field[data-size=lg] & {
93
+ --_slot: var(--text-field-height-lg);
94
+ }
95
+ }
96
+ .TextField_inControl {
97
+ grid-area: 1 / 1;
98
+ inline-size: 100%;
99
+ &::-webkit-search-cancel-button {
100
+ display: none;
101
+ }
102
+ }
103
+ .TextField_control[data-icon] .TextField_inControl {
104
+ padding-inline-start: calc(var(--text-field-padding-inline) + 1em + var(--text-field-icon-gap));
105
+ }
106
+ .TextField_control[data-clearable] .TextField_inControl {
107
+ padding-inline-end: var(--_slot);
108
+ }
109
+ .TextField_icon {
110
+ display: inline-flex;
111
+ grid-area: 1 / 1;
112
+ justify-self: start;
113
+ margin-inline-start: var(--text-field-padding-inline);
114
+ color: var(--text-field-icon-fg);
115
+ pointer-events: none;
116
+ }
117
+ .TextField_clear {
118
+ display: inline-flex;
119
+ grid-area: 1 / 1;
120
+ align-items: center;
121
+ justify-content: center;
122
+ justify-self: end;
123
+ inline-size: var(--_slot);
124
+ block-size: var(--_slot);
125
+ padding: 0;
126
+ border: 0;
127
+ border-radius: var(--text-field-radius);
128
+ background: transparent;
129
+ color: var(--text-field-icon-fg);
130
+ cursor: pointer;
131
+ &:hover {
132
+ color: var(--text-field-icon-fg-hover);
133
+ }
134
+ &:focus-visible {
135
+ outline: var(--text-field-focus-ring-width) solid var(--text-field-focus-ring);
136
+ outline-offset: calc(-1 * var(--text-field-focus-ring-width));
137
+ }
138
+ }
76
139
  }
77
140
  /*# sourceMappingURL=text-field.css.map */
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/field/Field.module.css","../src/text-field/TextField.module.css"],"sourcesContent":["/* Every value is a token (--field-*). The control itself brings its own styles. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .field {\n display: flex;\n flex-direction: column;\n gap: var(--field-gap);\n }\n\n .label {\n font-size: var(--field-label-font-size);\n font-weight: var(--field-label-font-weight);\n color: var(--field-label-fg);\n }\n\n .required {\n margin-inline-start: var(--field-required-gap);\n color: var(--field-required-fg);\n }\n\n .description {\n margin: 0;\n font-size: var(--field-description-font-size);\n color: var(--field-description-fg);\n }\n\n .error {\n margin: 0;\n font-size: var(--field-error-font-size);\n color: var(--field-error-fg);\n }\n}\n","/*\n * The input's own styles (--text-field-*). Label, description and error come\n * from Field. State lives on the wrapper as data attributes and on the input\n * as native pseudo-classes.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .field {\n font-family: var(--text-field-font-family);\n }\n\n .input {\n min-block-size: var(--text-field-height-md);\n padding-block: 0;\n padding-inline: var(--text-field-padding-inline);\n border: 1px solid var(--text-field-border-default);\n border-radius: var(--text-field-radius);\n background-color: var(--text-field-bg);\n color: var(--text-field-fg);\n font-size: var(--text-field-font-size-md);\n transition:\n border-color var(--text-field-motion-duration) var(--motion-easing-standard),\n background-color var(--text-field-motion-duration) var(--motion-easing-standard);\n\n &::placeholder {\n color: var(--text-field-placeholder);\n }\n\n &:focus-visible {\n border-color: var(--text-field-border-focus);\n outline: var(--text-field-focus-ring-width) solid var(--text-field-focus-ring);\n outline-offset: var(--text-field-focus-ring-offset);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &:read-only:not(:disabled) {\n background-color: var(--color-surface-sunken);\n }\n\n &:hover:not(:disabled, :focus-visible) {\n border-color: var(--text-field-border-hover);\n }\n }\n\n .field[data-size=\"sm\"] .input {\n min-block-size: var(--text-field-height-sm);\n font-size: var(--text-field-font-size-sm);\n }\n\n .field[data-size=\"lg\"] .input {\n min-block-size: var(--text-field-height-lg);\n font-size: var(--text-field-font-size-lg);\n }\n\n .field[data-invalid] .input {\n border-color: var(--text-field-border-invalid);\n }\n}\n"],"mappings":";AAEA;AAEA;AACE,GAACA;AACC,aAAS;AACT,oBAAgB;AAChB,SAAK,IAAI;AACX;AAEA,GAACC;AACC,eAAW,IAAI;AACf,iBAAa,IAAI;AACjB,WAAO,IAAI;AACb;AAEA,GAACC;AACC,yBAAqB,IAAI;AACzB,WAAO,IAAI;AACb;AAEA,GAACC;AACC,YAAQ;AACR,eAAW,IAAI;AACf,WAAO,IAAI;AACb;AAEA,GAACC;AACC,YAAQ;AACR,eAAW,IAAI;AACf,WAAO,IAAI;AACb;AACF;;;AC3BA;AAEA;AACE,GAACC;AACC,iBAAa,IAAI;AACnB;AAEA,GAACC;AACC,oBAAgB,IAAI;AACpB,mBAAe;AACf,oBAAgB,IAAI;AACpB,YAAQ,IAAI,MAAM,IAAI;AACtB,mBAAe,IAAI;AACnB,sBAAkB,IAAI;AACtB,WAAO,IAAI;AACX,eAAW,IAAI;AACf,gBACE,aAAa,IAAI,8BAA8B,IAAI,yBAAyB,EAC5E,iBAAiB,IAAI,8BAA8B,IAAI;AAEzD,KAAC;AACC,aAAO,IAAI;AACb;AAEA,KAAC;AACC,oBAAc,IAAI;AAClB,eAAS,IAAI,+BAA+B,MAAM,IAAI;AACtD,sBAAgB,IAAI;AACtB;AAEA,KAAC;AACC,cAAQ;AACR,eAAS;AACX;AAEA,KAAC,UAAU,KAAK;AACd,wBAAkB,IAAI;AACxB;AAEA,KAAC,MAAM,KAAK,WAAW;AACrB,oBAAc,IAAI;AACpB;AACF;AAEA,GAzCCD,eAyCK,CAAC,cAAgB,CArCtBC;AAsCC,oBAAgB,IAAI;AACpB,eAAW,IAAI;AACjB;AAEA,GA9CCD,eA8CK,CAAC,cAAgB,CA1CtBC;AA2CC,oBAAgB,IAAI;AACpB,eAAW,IAAI;AACjB;AAEA,GAnDCD,eAmDK,CAAC,cAAc,CA/CpBC;AAgDC,kBAAc,IAAI;AACpB;AACF;","names":["field","label","required","description","error","field","input"]}
1
+ {"version":3,"sources":["../src/field/Field.module.css","../src/text-field/TextField.module.css"],"sourcesContent":["/* Every value is a token (--field-*). The control itself brings its own styles. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .field {\n display: flex;\n flex-direction: column;\n gap: var(--field-gap);\n }\n\n .label {\n font-size: var(--field-label-font-size);\n font-weight: var(--field-label-font-weight);\n color: var(--field-label-fg);\n }\n\n .required {\n margin-inline-start: var(--field-required-gap);\n color: var(--field-required-fg);\n }\n\n .description {\n margin: 0;\n font-size: var(--field-description-font-size);\n color: var(--field-description-fg);\n }\n\n .error {\n margin: 0;\n font-size: var(--field-error-font-size);\n color: var(--field-error-fg);\n }\n}\n","/*\n * The input's own styles (--text-field-*). Label, description and error come\n * from Field. State lives on the wrapper as data attributes and on the input\n * as native pseudo-classes.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .field {\n font-family: var(--text-field-font-family);\n }\n\n .input {\n min-block-size: var(--text-field-height-md);\n padding-block: 0;\n padding-inline: var(--text-field-padding-inline);\n border: 1px solid var(--text-field-border-default);\n border-radius: var(--text-field-radius);\n background-color: var(--text-field-bg);\n color: var(--text-field-fg);\n font-size: var(--text-field-font-size-md);\n transition:\n border-color var(--text-field-motion-duration) var(--motion-easing-standard),\n background-color var(--text-field-motion-duration) var(--motion-easing-standard);\n\n &::placeholder {\n color: var(--text-field-placeholder);\n }\n\n &:focus-visible {\n border-color: var(--text-field-border-focus);\n outline: var(--text-field-focus-ring-width) solid var(--text-field-focus-ring);\n outline-offset: var(--text-field-focus-ring-offset);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &:read-only:not(:disabled) {\n background-color: var(--color-surface-sunken);\n }\n\n &:hover:not(:disabled, :focus-visible) {\n border-color: var(--text-field-border-hover);\n }\n }\n\n .field[data-size=\"sm\"] .input {\n min-block-size: var(--text-field-height-sm);\n font-size: var(--text-field-font-size-sm);\n }\n\n .field[data-size=\"lg\"] .input {\n min-block-size: var(--text-field-height-lg);\n font-size: var(--text-field-font-size-lg);\n }\n\n .field[data-invalid] .input {\n border-color: var(--text-field-border-invalid);\n }\n\n .hiddenLabel {\n position: absolute;\n inline-size: var(--size-hairline);\n block-size: var(--size-hairline);\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n }\n\n /* Only when there is an icon or a clear button: the input keeps its own box, they sit over its padding. */\n .control {\n --_slot: var(--text-field-height-md);\n\n display: grid;\n position: relative;\n align-items: center;\n\n .field[data-size=\"sm\"] & {\n --_slot: var(--text-field-height-sm);\n }\n\n .field[data-size=\"lg\"] & {\n --_slot: var(--text-field-height-lg);\n }\n\n }\n\n /* The input inside .control: a class of its own, so these rules do not race the .input states above. */\n .inControl {\n grid-area: 1 / 1;\n inline-size: 100%;\n\n /* The browser's own clear control would be a second, unnamed one. */\n &::-webkit-search-cancel-button {\n display: none;\n }\n }\n\n .control[data-icon] .inControl {\n padding-inline-start: calc(var(--text-field-padding-inline) + 1em + var(--text-field-icon-gap));\n }\n\n .control[data-clearable] .inControl {\n padding-inline-end: var(--_slot);\n }\n\n .icon {\n display: inline-flex;\n grid-area: 1 / 1;\n justify-self: start;\n margin-inline-start: var(--text-field-padding-inline);\n color: var(--text-field-icon-fg);\n pointer-events: none;\n }\n\n .clear {\n display: inline-flex;\n grid-area: 1 / 1;\n align-items: center;\n justify-content: center;\n justify-self: end;\n inline-size: var(--_slot);\n block-size: var(--_slot);\n padding: 0;\n border: 0;\n border-radius: var(--text-field-radius);\n background: transparent;\n color: var(--text-field-icon-fg);\n cursor: pointer;\n\n &:hover {\n color: var(--text-field-icon-fg-hover);\n }\n\n &:focus-visible {\n outline: var(--text-field-focus-ring-width) solid var(--text-field-focus-ring);\n outline-offset: calc(-1 * var(--text-field-focus-ring-width));\n }\n }\n}\n"],"mappings":";AAEA;AAEA;AACE,GAACA;AACC,aAAS;AACT,oBAAgB;AAChB,SAAK,IAAI;AACX;AAEA,GAACC;AACC,eAAW,IAAI;AACf,iBAAa,IAAI;AACjB,WAAO,IAAI;AACb;AAEA,GAACC;AACC,yBAAqB,IAAI;AACzB,WAAO,IAAI;AACb;AAEA,GAACC;AACC,YAAQ;AACR,eAAW,IAAI;AACf,WAAO,IAAI;AACb;AAEA,GAACC;AACC,YAAQ;AACR,eAAW,IAAI;AACf,WAAO,IAAI;AACb;AACF;;;AC3BA;AAEA;AACE,GAACC;AACC,iBAAa,IAAI;AACnB;AAEA,GAACC;AACC,oBAAgB,IAAI;AACpB,mBAAe;AACf,oBAAgB,IAAI;AACpB,YAAQ,IAAI,MAAM,IAAI;AACtB,mBAAe,IAAI;AACnB,sBAAkB,IAAI;AACtB,WAAO,IAAI;AACX,eAAW,IAAI;AACf,gBACE,aAAa,IAAI,8BAA8B,IAAI,yBAAyB,EAC5E,iBAAiB,IAAI,8BAA8B,IAAI;AAEzD,KAAC;AACC,aAAO,IAAI;AACb;AAEA,KAAC;AACC,oBAAc,IAAI;AAClB,eAAS,IAAI,+BAA+B,MAAM,IAAI;AACtD,sBAAgB,IAAI;AACtB;AAEA,KAAC;AACC,cAAQ;AACR,eAAS;AACX;AAEA,KAAC,UAAU,KAAK;AACd,wBAAkB,IAAI;AACxB;AAEA,KAAC,MAAM,KAAK,WAAW;AACrB,oBAAc,IAAI;AACpB;AACF;AAEA,GAzCCD,eAyCK,CAAC,cAAgB,CArCtBC;AAsCC,oBAAgB,IAAI;AACpB,eAAW,IAAI;AACjB;AAEA,GA9CCD,eA8CK,CAAC,cAAgB,CA1CtBC;AA2CC,oBAAgB,IAAI;AACpB,eAAW,IAAI;AACjB;AAEA,GAnDCD,eAmDK,CAAC,cAAc,CA/CpBC;AAgDC,kBAAc,IAAI;AACpB;AAEA,GAACC;AACC,cAAU;AACV,iBAAa,IAAI;AACjB,gBAAY,IAAI;AAChB,cAAU;AACV,eAAW,MAAM;AACjB,iBAAa;AACf;AAGA,GAACC;AACC,aAAS,IAAI;AAEb,aAAS;AACT,cAAU;AACV,iBAAa;AAEb,KAxEDH,eAwEO,CAAC,cAAgB;AACrB,eAAS,IAAI;AACf;AAEA,KA5EDA,eA4EO,CAAC,cAAgB;AACrB,eAAS,IAAI;AACf;AAEF;AAGA,GAACI;AACC,eAAW,EAAE,EAAE;AACf,iBAAa;AAGb,KAAC;AACC,eAAS;AACX;AACF;AAEA,GA5BCD,iBA4BO,CAAC,WAAW,CAVnBC;AAWC,0BAAsB,KAAK,IAAI,6BAA6B,EAAE,IAAI,EAAE,IAAI;AAC1E;AAEA,GAhCCD,iBAgCO,CAAC,gBAAgB,CAdxBC;AAeC,wBAAoB,IAAI;AAC1B;AAEA,GAACC;AACC,aAAS;AACT,eAAW,EAAE,EAAE;AACf,kBAAc;AACd,yBAAqB,IAAI;AACzB,WAAO,IAAI;AACX,oBAAgB;AAClB;AAEA,GAACC;AACC,aAAS;AACT,eAAW,EAAE,EAAE;AACf,iBAAa;AACb,qBAAiB;AACjB,kBAAc;AACd,iBAAa,IAAI;AACjB,gBAAY,IAAI;AAChB,aAAS;AACT,YAAQ;AACR,mBAAe,IAAI;AACnB,gBAAY;AACZ,WAAO,IAAI;AACX,YAAQ;AAER,KAAC;AACC,aAAO,IAAI;AACb;AAEA,KAAC;AACC,eAAS,IAAI,+BAA+B,MAAM,IAAI;AACtD,sBAAgB,KAAK,GAAG,EAAE,IAAI;AAChC;AACF;AACF;","names":["field","label","required","description","error","field","input","hiddenLabel","control","inControl","icon","clear"]}
@@ -12,6 +12,18 @@ interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'si
12
12
  * `data-invalid`) and the message is announced as an alert.
13
13
  */
14
14
  error?: ReactNode;
15
+ /** Keeps the label for assistive technology only. For a search box that a heading or its place in the page already names. @default false */
16
+ hideLabel?: boolean;
17
+ /** A decorative glyph inside the field, before the text. `type="search"` gets the Search glyph unless you pass another (or `null`). */
18
+ iconStart?: ReactNode;
19
+ /**
20
+ * Adds a clear button that appears once the field has a value. Called when it
21
+ * is pressed and when Escape is pressed with a value. Controlled: set your
22
+ * value to `''` here. Uncontrolled: the input is emptied for you.
23
+ */
24
+ onClear?: () => void;
25
+ /** The clear button's name, for other languages. @default 'Clear' */
26
+ clearLabel?: string;
15
27
  /** @default 'md' */
16
28
  size?: TextFieldSize;
17
29
  /** The `<input>` element. */
@@ -29,13 +41,14 @@ interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'si
29
41
  *
30
42
  * @status stable
31
43
  * @category Forms
32
- * @accessibility A native text `input` wired through Field: `label[for]`, `aria-describedby` for description and error, `aria-invalid` and `aria-required`. Everything the browser gives a native input (autofill, IME, forms) applies.
44
+ * @accessibility A native text `input` wired through Field: `label[for]`, `aria-describedby` for description and error, `aria-invalid` and `aria-required`. Everything the browser gives a native input (autofill, IME, forms) applies. `hideLabel` hides the label visually, never from assistive technology. The leading icon is decorative. The clear button is a real `button` named by `clearLabel`, after the input in the tab order, present only while there is a value; pressing it (or Escape in the field) empties the field and leaves focus in the input. `type="search"` gives the input the `searchbox` role; wrap the form in `<search>` or `role="search"` yourself when it is the page's search.
33
45
  * @do Always pass `label`; use a visible one.
34
46
  * Prefer `error` text that says how to fix the value.
47
+ * @do For a search box: `type="search"`, `hideLabel` if a heading names it, and `onClear`.
35
48
  * @dont Use `placeholder` as the label.
36
49
  * Use it for multi-line text; use Textarea.
37
50
  */
38
- declare function TextField({ label, description, error, size, required, disabled, readOnly, id, className, ref, 'aria-describedby': describedBy, ...rest }: TextFieldProps): react.JSX.Element;
51
+ declare function TextField({ label, description, error, hideLabel, iconStart, onClear, clearLabel, size, type, value, defaultValue, onChange, onKeyDown, required, disabled, readOnly, id, className, ref, 'aria-describedby': describedBy, ...rest }: TextFieldProps): react.JSX.Element;
39
52
  declare namespace TextField {
40
53
  var displayName: string;
41
54
  }
@@ -1,6 +1,6 @@
1
- export { TextField } from './chunk-IFIQLIA3.js';
2
- import './chunk-M5VL22MY.js';
3
- import './chunk-ZVDN3GRI.js';
1
+ "use client";export { TextField } from './chunk-S632WN4W.js';
2
+ import './chunk-SXMORGSG.js';
3
+ import './chunk-QJG5ILK5.js';
4
4
  import './chunk-MI4QUKQS.js';
5
5
  //# sourceMappingURL=text-field.js.map
6
6
  //# sourceMappingURL=text-field.js.map
package/dist/textarea.js CHANGED
@@ -1,6 +1,6 @@
1
- export { Textarea } from './chunk-5PYLJQJX.js';
2
- import './chunk-M5VL22MY.js';
3
- import './chunk-ZVDN3GRI.js';
1
+ "use client";export { Textarea } from './chunk-VS2HPJIX.js';
2
+ import './chunk-SXMORGSG.js';
3
+ import './chunk-QJG5ILK5.js';
4
4
  import './chunk-MI4QUKQS.js';
5
5
  //# sourceMappingURL=textarea.js.map
6
6
  //# sourceMappingURL=textarea.js.map
package/dist/toast.css CHANGED
@@ -160,6 +160,24 @@
160
160
  }
161
161
  }
162
162
  }
163
+ .Button_button[data-tone=danger] {
164
+ &[data-variant=primary] {
165
+ background-color: var(--button-danger-bg);
166
+ color: var(--button-danger-fg);
167
+ &:hover:not(:disabled, [aria-disabled=true]) {
168
+ background-color: var(--button-danger-bg-hover);
169
+ }
170
+ &:active:not(:disabled, [aria-disabled=true]) {
171
+ background-color: var(--button-danger-bg-active);
172
+ }
173
+ }
174
+ &:is([data-variant=secondary], [data-variant=ghost]) {
175
+ color: var(--button-danger-text);
176
+ &:hover:not(:disabled, [aria-disabled=true]) {
177
+ background-color: var(--button-danger-quiet-bg-hover);
178
+ }
179
+ }
180
+ }
163
181
  .Button_label {
164
182
  display: inline-block;
165
183
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/icon/Icon.module.css","../src/visually-hidden/VisuallyHidden.module.css","../src/spinner/Spinner.module.css","../src/button/Button.module.css","../src/icon-button/IconButton.module.css","../src/alert/Alert.module.css","../src/toast/Toast.module.css"],"sourcesContent":["/* Every value is a token (--icon-*). The child SVG fills the box; colour is currentColor. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .icon {\n display: inline-flex;\n flex: none;\n inline-size: 1em;\n block-size: 1em;\n font-size: var(--icon-size-md);\n vertical-align: middle;\n\n &[data-size=\"sm\"] { font-size: var(--icon-size-sm); }\n &[data-size=\"lg\"] { font-size: var(--icon-size-lg); }\n &[data-size=\"inherit\"] { font-size: inherit; }\n\n & > * {\n inline-size: 100%;\n block-size: 100%;\n }\n }\n}\n","/* The clip-path technique: present in the accessibility tree, absent from the layout. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .root {\n position: absolute;\n inline-size: var(--visually-hidden-size);\n block-size: var(--visually-hidden-size);\n padding: 0;\n margin: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n}\n","/* Every value is a token (--spinner-*). The ring is a border with one coloured side. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .spinner {\n --_size: var(--spinner-size-md);\n --_track: var(--spinner-track);\n --_indicator: var(--spinner-indicator);\n\n display: inline-flex;\n flex: none;\n inline-size: var(--_size);\n block-size: var(--_size);\n vertical-align: middle;\n\n &[data-size=\"sm\"] { --_size: var(--spinner-size-sm); }\n &[data-size=\"lg\"] { --_size: var(--spinner-size-lg); }\n &[data-size=\"inherit\"] { --_size: 1em; }\n\n &[data-tone=\"inherit\"] {\n --_track: transparent;\n --_indicator: currentcolor;\n }\n }\n\n .ring {\n inline-size: 100%;\n block-size: 100%;\n border: var(--spinner-width) solid var(--_track);\n border-block-start-color: var(--_indicator);\n border-radius: var(--radius-full);\n animation: spin var(--spinner-duration) linear infinite;\n }\n\n @keyframes spin {\n to {\n rotate: 1turn;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .ring {\n animation: none;\n }\n }\n}\n","/*\n * Every value is a token. State is expressed through data attributes so the\n * styling hooks survive a change of styling tool, and so tests and agents can\n * read state off the DOM.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--button-gap);\n min-block-size: var(--button-height-md);\n padding-block: 0;\n padding-inline: var(--button-padding-inline-md);\n border: 1px solid transparent;\n border-radius: var(--button-radius);\n font-family: var(--button-font-family);\n font-size: var(--button-font-size-md);\n font-weight: var(--button-font-weight);\n line-height: 1;\n text-decoration: none;\n white-space: nowrap;\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n transition:\n background-color var(--button-motion-duration) var(--motion-easing-standard),\n border-color var(--button-motion-duration) var(--motion-easing-standard),\n color var(--button-motion-duration) var(--motion-easing-standard);\n\n &:focus-visible {\n outline: var(--button-focus-ring-width) solid var(--button-focus-ring);\n outline-offset: var(--button-focus-ring-offset);\n }\n\n &:disabled,\n &[aria-disabled=\"true\"] {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &[data-loading] {\n cursor: progress;\n }\n\n &[data-size=\"sm\"] {\n min-block-size: var(--button-height-sm);\n padding-inline: var(--button-padding-inline-sm);\n font-size: var(--button-font-size-sm);\n }\n\n &[data-size=\"lg\"] {\n min-block-size: var(--button-height-lg);\n padding-inline: var(--button-padding-inline-lg);\n font-size: var(--button-font-size-lg);\n }\n\n &[data-variant=\"primary\"] {\n background-color: var(--button-primary-bg);\n color: var(--button-primary-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-primary-bg-hover);\n }\n\n &:active:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-primary-bg-active);\n }\n }\n\n &[data-variant=\"secondary\"] {\n background-color: var(--button-secondary-bg);\n border-color: var(--button-secondary-border);\n color: var(--button-secondary-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-secondary-bg-hover);\n }\n }\n\n &[data-variant=\"ghost\"] {\n background-color: transparent;\n color: var(--button-ghost-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-ghost-bg-hover);\n }\n }\n }\n\n .label {\n display: inline-block;\n }\n}\n","/* Squares a Button. Selectors carry the data attribute so they outrank Button's own size rules. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .iconButton[data-icon-only] {\n gap: 0;\n inline-size: var(--icon-button-size-md);\n padding-inline: 0;\n\n &[data-size=\"sm\"] { inline-size: var(--icon-button-size-sm); }\n &[data-size=\"lg\"] { inline-size: var(--icon-button-size-lg); }\n }\n}\n","/* Every value is a token (--alert-*). Tone resolves into private custom properties. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .alert {\n --_bg: var(--alert-info-bg);\n --_accent: var(--alert-info-accent);\n --_title: var(--alert-info-title);\n\n display: flex;\n align-items: flex-start;\n gap: var(--alert-gap);\n padding: var(--alert-padding);\n border: var(--alert-border-width) solid var(--_accent);\n border-inline-start-width: var(--alert-accent-width);\n border-radius: var(--alert-radius);\n background-color: var(--_bg);\n color: var(--alert-fg);\n font-size: var(--alert-font-size);\n\n &[data-tone=\"info\"] {\n --_bg: var(--alert-info-bg);\n --_accent: var(--alert-info-accent);\n --_title: var(--alert-info-title);\n }\n\n &[data-tone=\"success\"] {\n --_bg: var(--alert-success-bg);\n --_accent: var(--alert-success-accent);\n --_title: var(--alert-success-title);\n }\n\n &[data-tone=\"warning\"] {\n --_bg: var(--alert-warning-bg);\n --_accent: var(--alert-warning-accent);\n --_title: var(--alert-warning-title);\n }\n\n &[data-tone=\"error\"] {\n --_bg: var(--alert-error-bg);\n --_accent: var(--alert-error-accent);\n --_title: var(--alert-error-title);\n }\n }\n\n .icon {\n flex: none;\n color: var(--_accent);\n }\n\n .body {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: var(--space-1);\n min-inline-size: 0;\n }\n\n .title {\n margin: 0;\n color: var(--_title);\n font-weight: var(--alert-title-font-weight);\n }\n\n .content {\n overflow-wrap: anywhere;\n }\n\n .action {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-2);\n margin-block-start: var(--space-1);\n }\n\n .dismiss {\n flex: none;\n margin-block: calc(-1 * var(--space-1));\n margin-inline-end: calc(-1 * var(--space-2));\n }\n}\n","/* Every value is a token (--toast-*). The region is fixed; placement is a data attribute. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .region {\n --_top: auto;\n --_end: var(--toast-offset);\n --_bottom: var(--toast-offset);\n --_start: auto;\n\n position: fixed;\n z-index: var(--toast-layer);\n inset: var(--_top) var(--_end) var(--_bottom) var(--_start);\n inline-size: min(var(--toast-width), 100vw);\n padding: 0;\n pointer-events: none;\n\n &[data-placement=\"top-end\"] {\n --_top: var(--toast-offset);\n --_bottom: auto;\n }\n\n &[data-placement=\"top-center\"] {\n --_top: var(--toast-offset);\n --_bottom: auto;\n --_start: 0;\n --_end: 0;\n\n margin-inline: auto;\n }\n }\n\n .list {\n display: flex;\n flex-direction: column;\n gap: var(--toast-gap);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .item {\n pointer-events: auto;\n animation: enter var(--toast-motion-duration) var(--motion-easing-standard);\n }\n\n .toast {\n border-radius: var(--toast-radius);\n box-shadow: var(--toast-shadow);\n }\n\n @keyframes enter {\n from {\n opacity: 0;\n translate: 0 var(--space-2);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .item {\n animation: none;\n }\n }\n}\n"],"mappings":"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","names":["icon","root","spinner","ring","spin","button","label","iconButton","alert","icon","body","title","content","action","dismiss","region","list","item","toast","enter"]}
1
+ {"version":3,"sources":["../src/icon/Icon.module.css","../src/visually-hidden/VisuallyHidden.module.css","../src/spinner/Spinner.module.css","../src/button/Button.module.css","../src/icon-button/IconButton.module.css","../src/alert/Alert.module.css","../src/toast/Toast.module.css"],"sourcesContent":["/* Every value is a token (--icon-*). The child SVG fills the box; colour is currentColor. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .icon {\n display: inline-flex;\n flex: none;\n inline-size: 1em;\n block-size: 1em;\n font-size: var(--icon-size-md);\n vertical-align: middle;\n\n &[data-size=\"sm\"] { font-size: var(--icon-size-sm); }\n &[data-size=\"lg\"] { font-size: var(--icon-size-lg); }\n &[data-size=\"inherit\"] { font-size: inherit; }\n\n & > * {\n inline-size: 100%;\n block-size: 100%;\n }\n }\n}\n","/* The clip-path technique: present in the accessibility tree, absent from the layout. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .root {\n position: absolute;\n inline-size: var(--visually-hidden-size);\n block-size: var(--visually-hidden-size);\n padding: 0;\n margin: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n}\n","/* Every value is a token (--spinner-*). The ring is a border with one coloured side. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .spinner {\n --_size: var(--spinner-size-md);\n --_track: var(--spinner-track);\n --_indicator: var(--spinner-indicator);\n\n display: inline-flex;\n flex: none;\n inline-size: var(--_size);\n block-size: var(--_size);\n vertical-align: middle;\n\n &[data-size=\"sm\"] { --_size: var(--spinner-size-sm); }\n &[data-size=\"lg\"] { --_size: var(--spinner-size-lg); }\n &[data-size=\"inherit\"] { --_size: 1em; }\n\n &[data-tone=\"inherit\"] {\n --_track: transparent;\n --_indicator: currentcolor;\n }\n }\n\n .ring {\n inline-size: 100%;\n block-size: 100%;\n border: var(--spinner-width) solid var(--_track);\n border-block-start-color: var(--_indicator);\n border-radius: var(--radius-full);\n animation: spin var(--spinner-duration) linear infinite;\n }\n\n @keyframes spin {\n to {\n rotate: 1turn;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .ring {\n animation: none;\n }\n }\n}\n","/*\n * Every value is a token. State is expressed through data attributes so the\n * styling hooks survive a change of styling tool, and so tests and agents can\n * read state off the DOM.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--button-gap);\n min-block-size: var(--button-height-md);\n padding-block: 0;\n padding-inline: var(--button-padding-inline-md);\n border: 1px solid transparent;\n border-radius: var(--button-radius);\n font-family: var(--button-font-family);\n font-size: var(--button-font-size-md);\n font-weight: var(--button-font-weight);\n line-height: 1;\n text-decoration: none;\n white-space: nowrap;\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n transition:\n background-color var(--button-motion-duration) var(--motion-easing-standard),\n border-color var(--button-motion-duration) var(--motion-easing-standard),\n color var(--button-motion-duration) var(--motion-easing-standard);\n\n &:focus-visible {\n outline: var(--button-focus-ring-width) solid var(--button-focus-ring);\n outline-offset: var(--button-focus-ring-offset);\n }\n\n &:disabled,\n &[aria-disabled=\"true\"] {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &[data-loading] {\n cursor: progress;\n }\n\n &[data-size=\"sm\"] {\n min-block-size: var(--button-height-sm);\n padding-inline: var(--button-padding-inline-sm);\n font-size: var(--button-font-size-sm);\n }\n\n &[data-size=\"lg\"] {\n min-block-size: var(--button-height-lg);\n padding-inline: var(--button-padding-inline-lg);\n font-size: var(--button-font-size-lg);\n }\n\n &[data-variant=\"primary\"] {\n background-color: var(--button-primary-bg);\n color: var(--button-primary-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-primary-bg-hover);\n }\n\n &:active:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-primary-bg-active);\n }\n }\n\n &[data-variant=\"secondary\"] {\n background-color: var(--button-secondary-bg);\n border-color: var(--button-secondary-border);\n color: var(--button-secondary-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-secondary-bg-hover);\n }\n }\n\n &[data-variant=\"ghost\"] {\n background-color: transparent;\n color: var(--button-ghost-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-ghost-bg-hover);\n }\n }\n }\n\n /* tone=\"danger\", after the variants so it wins at equal specificity plus one attribute. */\n .button[data-tone=\"danger\"] {\n &[data-variant=\"primary\"] {\n background-color: var(--button-danger-bg);\n color: var(--button-danger-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-danger-bg-hover);\n }\n\n &:active:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-danger-bg-active);\n }\n }\n\n &:is([data-variant=\"secondary\"], [data-variant=\"ghost\"]) {\n color: var(--button-danger-text);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-danger-quiet-bg-hover);\n }\n }\n }\n\n .label {\n display: inline-block;\n }\n}\n","/* Squares a Button. Selectors carry the data attribute so they outrank Button's own size rules. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .iconButton[data-icon-only] {\n gap: 0;\n inline-size: var(--icon-button-size-md);\n padding-inline: 0;\n\n &[data-size=\"sm\"] { inline-size: var(--icon-button-size-sm); }\n &[data-size=\"lg\"] { inline-size: var(--icon-button-size-lg); }\n }\n}\n","/* Every value is a token (--alert-*). Tone resolves into private custom properties. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .alert {\n --_bg: var(--alert-info-bg);\n --_accent: var(--alert-info-accent);\n --_title: var(--alert-info-title);\n\n display: flex;\n align-items: flex-start;\n gap: var(--alert-gap);\n padding: var(--alert-padding);\n border: var(--alert-border-width) solid var(--_accent);\n border-inline-start-width: var(--alert-accent-width);\n border-radius: var(--alert-radius);\n background-color: var(--_bg);\n color: var(--alert-fg);\n font-size: var(--alert-font-size);\n\n &[data-tone=\"info\"] {\n --_bg: var(--alert-info-bg);\n --_accent: var(--alert-info-accent);\n --_title: var(--alert-info-title);\n }\n\n &[data-tone=\"success\"] {\n --_bg: var(--alert-success-bg);\n --_accent: var(--alert-success-accent);\n --_title: var(--alert-success-title);\n }\n\n &[data-tone=\"warning\"] {\n --_bg: var(--alert-warning-bg);\n --_accent: var(--alert-warning-accent);\n --_title: var(--alert-warning-title);\n }\n\n &[data-tone=\"error\"] {\n --_bg: var(--alert-error-bg);\n --_accent: var(--alert-error-accent);\n --_title: var(--alert-error-title);\n }\n }\n\n .icon {\n flex: none;\n color: var(--_accent);\n }\n\n .body {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: var(--space-1);\n min-inline-size: 0;\n }\n\n .title {\n margin: 0;\n color: var(--_title);\n font-weight: var(--alert-title-font-weight);\n }\n\n .content {\n overflow-wrap: anywhere;\n }\n\n .action {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-2);\n margin-block-start: var(--space-1);\n }\n\n .dismiss {\n flex: none;\n margin-block: calc(-1 * var(--space-1));\n margin-inline-end: calc(-1 * var(--space-2));\n }\n}\n","/* Every value is a token (--toast-*). The region is fixed; placement is a data attribute. */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .region {\n --_top: auto;\n --_end: var(--toast-offset);\n --_bottom: var(--toast-offset);\n --_start: auto;\n\n position: fixed;\n z-index: var(--toast-layer);\n inset: var(--_top) var(--_end) var(--_bottom) var(--_start);\n inline-size: min(var(--toast-width), 100vw);\n padding: 0;\n pointer-events: none;\n\n &[data-placement=\"top-end\"] {\n --_top: var(--toast-offset);\n --_bottom: auto;\n }\n\n &[data-placement=\"top-center\"] {\n --_top: var(--toast-offset);\n --_bottom: auto;\n --_start: 0;\n --_end: 0;\n\n margin-inline: auto;\n }\n }\n\n .list {\n display: flex;\n flex-direction: column;\n gap: var(--toast-gap);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .item {\n pointer-events: auto;\n animation: enter var(--toast-motion-duration) var(--motion-easing-standard);\n }\n\n .toast {\n border-radius: var(--toast-radius);\n box-shadow: var(--toast-shadow);\n }\n\n @keyframes enter {\n from {\n opacity: 0;\n translate: 0 var(--space-2);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .item {\n animation: none;\n }\n }\n}\n"],"mappings":"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","names":["icon","root","spinner","ring","spin","button","label","iconButton","alert","icon","body","title","content","action","dismiss","region","list","item","toast","enter"]}
package/dist/toast.d.ts CHANGED
@@ -19,6 +19,7 @@ interface ToastProviderProps {
19
19
  * region; `useToast()` adds notifications to it. Timers pause while the
20
20
  * region is hovered or holds focus, Escape dismisses the focused toast, and
21
21
  * error toasts stay until dismissed. Each toast is an Alert.
22
+ * `toast.undo(message, onUndo)` is the shorthand for a reversible action.
22
23
  *
23
24
  * @status stable
24
25
  * @category Feedback
@@ -40,21 +41,38 @@ interface ToastOptions {
40
41
  tone?: AlertTone;
41
42
  /** Milliseconds before auto-dismiss; `Infinity` keeps it until dismissed. Errors default to `Infinity`. */
42
43
  duration?: number;
44
+ /** One button inside the toast. Pressing it runs `onClick` and dismisses the toast. It never takes focus. */
43
45
  action?: {
44
46
  label: string;
45
47
  onClick: () => void;
46
48
  };
47
49
  }
50
+ interface ToastUndoOptions extends Pick<ToastOptions, 'description' | 'tone'> {
51
+ /** The button's label, for other languages. @default 'Undo' */
52
+ label?: string;
53
+ /** Longer than an ordinary toast by default (8 s): there is something to read, decide and reach. */
54
+ duration?: number;
55
+ }
56
+ interface ToastFunction {
57
+ /** Shows a toast and returns its id. */
58
+ (options: ToastOptions): string;
59
+ /**
60
+ * The named case for a reversible action: "Place removed" with an Undo
61
+ * button. Pressing it runs `onUndo` and dismisses; letting it time out
62
+ * does nothing, so do the work first and undo it on request.
63
+ */
64
+ undo: (message: ReactNode, onUndo: () => void, options?: ToastUndoOptions) => string;
65
+ }
48
66
  interface ToastItem extends ToastOptions {
49
67
  id: string;
50
68
  }
51
69
  interface ToastContextValue {
52
- /** Shows a toast and returns its id. */
53
- toast: (options: ToastOptions) => string;
70
+ /** Shows a toast and returns its id. `toast.undo(message, onUndo)` is the reversible-action shorthand. */
71
+ toast: ToastFunction;
54
72
  dismiss: (id: string) => void;
55
73
  dismissAll: () => void;
56
74
  }
57
75
  /** The toast API. Must be used inside `ToastProvider`. */
58
76
  declare function useToast(): ToastContextValue;
59
77
 
60
- export { type ToastContextValue, type ToastItem, type ToastOptions, type ToastPlacement, ToastProvider, type ToastProviderProps, useToast };
78
+ export { type ToastContextValue, type ToastFunction, type ToastItem, type ToastOptions, type ToastPlacement, ToastProvider, type ToastProviderProps, type ToastUndoOptions, useToast };
package/dist/toast.js CHANGED
@@ -1,11 +1,11 @@
1
- export { ToastProvider, useToast } from './chunk-U3N3G2UA.js';
2
- import './chunk-N4C3NQIN.js';
3
- import './chunk-MF66ICX6.js';
4
- import './chunk-5TTYVQ6Q.js';
1
+ "use client";export { ToastProvider, useToast } from './chunk-FFCEY76B.js';
2
+ import './chunk-A7TMFEQ2.js';
3
+ import './chunk-56RSH7GQ.js';
4
+ import './chunk-DE67ECD7.js';
5
5
  import './chunk-ZL5MMRLG.js';
6
- import './chunk-ZVDN3GRI.js';
7
6
  import './chunk-IB5UUE3S.js';
8
7
  import './chunk-O5LII5XP.js';
8
+ import './chunk-QJG5ILK5.js';
9
9
  import './chunk-MI4QUKQS.js';
10
10
  //# sourceMappingURL=toast.js.map
11
11
  //# sourceMappingURL=toast.js.map
package/dist/tooltip.js CHANGED
@@ -1,5 +1,5 @@
1
- export { Tooltip } from './chunk-XWPXW46D.js';
1
+ "use client";export { Tooltip } from './chunk-GWTHITZO.js';
2
2
  import './chunk-U6QRAD73.js';
3
- import './chunk-ZVDN3GRI.js';
3
+ import './chunk-QJG5ILK5.js';
4
4
  //# sourceMappingURL=tooltip.js.map
5
5
  //# sourceMappingURL=tooltip.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pearpages/pulp-react",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "pulp React components. Accessible, token-driven, CSS modules, one entry per component.",
5
5
  "license": "MIT",
6
6
  "author": "Pere Pages <hello@pearpages.com> (https://pearpages.com)",
@@ -23,6 +23,30 @@
23
23
  "types": "./dist/index.d.ts",
24
24
  "import": "./dist/index.js"
25
25
  },
26
+ "./empty-state": {
27
+ "types": "./dist/empty-state.d.ts",
28
+ "import": "./dist/empty-state.js"
29
+ },
30
+ "./segmented-control": {
31
+ "types": "./dist/segmented-control.d.ts",
32
+ "import": "./dist/segmented-control.js"
33
+ },
34
+ "./chip": {
35
+ "types": "./dist/chip.d.ts",
36
+ "import": "./dist/chip.js"
37
+ },
38
+ "./avatar": {
39
+ "types": "./dist/avatar.d.ts",
40
+ "import": "./dist/avatar.js"
41
+ },
42
+ "./link": {
43
+ "types": "./dist/link.d.ts",
44
+ "import": "./dist/link.js"
45
+ },
46
+ "./divider": {
47
+ "types": "./dist/divider.d.ts",
48
+ "import": "./dist/divider.js"
49
+ },
26
50
  "./sheet": {
27
51
  "types": "./dist/sheet.d.ts",
28
52
  "import": "./dist/sheet.js"
@@ -172,6 +196,12 @@
172
196
  "import": "./dist/button.js"
173
197
  },
174
198
  "./styles.css": "./dist/index.css",
199
+ "./empty-state.css": "./dist/empty-state.css",
200
+ "./segmented-control.css": "./dist/segmented-control.css",
201
+ "./chip.css": "./dist/chip.css",
202
+ "./avatar.css": "./dist/avatar.css",
203
+ "./link.css": "./dist/link.css",
204
+ "./divider.css": "./dist/divider.css",
175
205
  "./sheet.css": "./dist/sheet.css",
176
206
  "./pagination.css": "./dist/pagination.css",
177
207
  "./table.css": "./dist/table.css",
@@ -215,7 +245,7 @@
215
245
  "peerDependencies": {
216
246
  "react": "^19.0.0",
217
247
  "react-dom": "^19.0.0",
218
- "@pearpages/pulp-tokens": "^0.2.1"
248
+ "@pearpages/pulp-tokens": "^0.3.0"
219
249
  },
220
250
  "devDependencies": {
221
251
  "@arethetypeswrong/cli": "^0.18.5",
@@ -237,7 +267,7 @@
237
267
  "typescript": "^5.9.3",
238
268
  "vitest": "^4.1.11",
239
269
  "vitest-axe": "^0.1.0",
240
- "@pearpages/pulp-tokens": "0.2.1"
270
+ "@pearpages/pulp-tokens": "0.3.0"
241
271
  },
242
272
  "peerDependenciesMeta": {
243
273
  "@pearpages/pulp-tokens": {
@@ -249,10 +279,10 @@
249
279
  "@internationalized/date": "^3.12.4",
250
280
  "@pearpages/modals": "^0.3.0",
251
281
  "react-aria-components": "^1.21.1",
252
- "@pearpages/pulp-icons": "^0.1.0"
282
+ "@pearpages/pulp-icons": "^0.2.0"
253
283
  },
254
284
  "scripts": {
255
- "build": "tsup && node scripts/manifest.mjs",
285
+ "build": "tsup && node scripts/client-entries.mjs && node scripts/manifest.mjs",
256
286
  "dev": "tsup --watch",
257
287
  "typecheck": "tsc --noEmit",
258
288
  "test": "vitest",
@@ -260,7 +290,7 @@
260
290
  "test:dist": "vitest run --config vitest.dist.config.ts",
261
291
  "manifest": "node scripts/manifest.mjs",
262
292
  "scaffold": "node scripts/scaffold-component.mjs",
263
- "check:package": "publint && attw --pack . --profile esm-only --exclude-entrypoints styles.css button.css text-field.css card.css tabs.css dialog.css text.css heading.css icon.css visually-hidden.css stack.css inline.css field.css icon-button.css checkbox.css switch.css radio.css textarea.css select.css spinner.css badge.css alert.css toast.css progress.css skeleton.css tooltip.css popover.css accordion.css menu.css combobox.css listbox.css picker.css calendar.css date-picker.css slider.css table.css pagination.css sheet.css component-manifest.json",
293
+ "check:package": "publint && attw --pack . --profile esm-only --exclude-entrypoints styles.css button.css text-field.css card.css tabs.css dialog.css text.css heading.css icon.css visually-hidden.css stack.css inline.css field.css icon-button.css checkbox.css switch.css radio.css textarea.css select.css spinner.css badge.css alert.css toast.css progress.css skeleton.css tooltip.css popover.css accordion.css menu.css combobox.css listbox.css picker.css calendar.css date-picker.css slider.css table.css pagination.css sheet.css divider.css link.css avatar.css chip.css segmented-control.css empty-state.css component-manifest.json",
264
294
  "check:size": "size-limit"
265
295
  }
266
296
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/button/Button.module.css","../src/button/Button.tsx"],"names":["button","label"],"mappings":"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","file":"chunk-5TTYVQ6Q.js","sourcesContent":["/*\n * Every value is a token. State is expressed through data attributes so the\n * styling hooks survive a change of styling tool, and so tests and agents can\n * read state off the DOM.\n */\n\n@layer reset, tokens, vendor, base, components, utilities;\n\n@layer components {\n .button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--button-gap);\n min-block-size: var(--button-height-md);\n padding-block: 0;\n padding-inline: var(--button-padding-inline-md);\n border: 1px solid transparent;\n border-radius: var(--button-radius);\n font-family: var(--button-font-family);\n font-size: var(--button-font-size-md);\n font-weight: var(--button-font-weight);\n line-height: 1;\n text-decoration: none;\n white-space: nowrap;\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n transition:\n background-color var(--button-motion-duration) var(--motion-easing-standard),\n border-color var(--button-motion-duration) var(--motion-easing-standard),\n color var(--button-motion-duration) var(--motion-easing-standard);\n\n &:focus-visible {\n outline: var(--button-focus-ring-width) solid var(--button-focus-ring);\n outline-offset: var(--button-focus-ring-offset);\n }\n\n &:disabled,\n &[aria-disabled=\"true\"] {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &[data-loading] {\n cursor: progress;\n }\n\n &[data-size=\"sm\"] {\n min-block-size: var(--button-height-sm);\n padding-inline: var(--button-padding-inline-sm);\n font-size: var(--button-font-size-sm);\n }\n\n &[data-size=\"lg\"] {\n min-block-size: var(--button-height-lg);\n padding-inline: var(--button-padding-inline-lg);\n font-size: var(--button-font-size-lg);\n }\n\n &[data-variant=\"primary\"] {\n background-color: var(--button-primary-bg);\n color: var(--button-primary-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-primary-bg-hover);\n }\n\n &:active:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-primary-bg-active);\n }\n }\n\n &[data-variant=\"secondary\"] {\n background-color: var(--button-secondary-bg);\n border-color: var(--button-secondary-border);\n color: var(--button-secondary-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-secondary-bg-hover);\n }\n }\n\n &[data-variant=\"ghost\"] {\n background-color: transparent;\n color: var(--button-ghost-fg);\n\n &:hover:not(:disabled, [aria-disabled=\"true\"]) {\n background-color: var(--button-ghost-bg-hover);\n }\n }\n }\n\n .label {\n display: inline-block;\n }\n}\n","import { Children, isValidElement, type ButtonHTMLAttributes, type MouseEvent, type ReactNode, type Ref } from 'react';\nimport { Icon } from '../icon';\nimport { renderAsChild } from '../internal/asChild';\nimport { Spinner } from '../spinner';\nimport { classes } from '../internal/classes';\nimport styles from './Button.module.css';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\n\nexport interface ButtonProps<E extends HTMLElement = HTMLButtonElement> extends ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Visual emphasis. One `primary` per view; `secondary` for the rest;\n * `ghost` for actions that sit inside other content.\n * @default 'primary'\n */\n variant?: ButtonVariant;\n /** @default 'md' */\n size?: ButtonSize;\n /**\n * Shows a spinner, sets `aria-busy` and `aria-disabled`, and blocks\n * activation. The element stays focusable so focus is not lost mid-action,\n * and the label stays in place so the button keeps its width.\n * @default false\n */\n loading?: boolean;\n /** Decorative element before the label. Hidden from assistive technology. */\n iconStart?: ReactNode;\n /** Decorative element after the label. Hidden from assistive technology. */\n iconEnd?: ReactNode;\n /**\n * Render the single child element instead of a `<button>`, merging the\n * button's props into it. Use it to style a router `<Link>` or an `<a>` as a\n * button. Disabled and loading states then use `aria-disabled`, and the\n * child's own `onClick` does not run while the control is inert.\n * @default false\n */\n asChild?: boolean;\n /**\n * The rendered element. With `asChild` that is the child's element, so pass\n * the type parameter: `<Button<HTMLAnchorElement> asChild ref={anchorRef}>`.\n */\n ref?: Ref<E>;\n children: ReactNode;\n}\n\nconst BLOCK = (event: MouseEvent) => event.preventDefault();\n\nconst DEV = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';\n\n/** True when some text exists anywhere in the children tree. */\nfunction hasText(node: ReactNode): boolean {\n return Children.toArray(node).some((child) => {\n if (typeof child === 'string') return child.trim().length > 0;\n if (typeof child === 'number') return true;\n if (isValidElement<{ children?: ReactNode }>(child)) return hasText(child.props.children);\n return false;\n });\n}\n\n/**\n * The one action component. Variants map to emphasis, not colour: one\n * `primary` per view, `secondary` for the rest, `ghost` inside other content.\n * Every value comes from `--button-*` tokens, so a brand restyles it without\n * touching the component. State is exposed as `data-variant`, `data-size` and\n * `data-loading` for styling, tests and agents alike.\n *\n * @status stable\n * @category Actions\n * @accessibility A native `button` (or the child element with `asChild`). `loading` sets `aria-disabled` and `aria-busy` and keeps focus; only `disabled` removes it from the tab order. Icon-only use warns in development: use IconButton, which requires a name.\n * @do One `primary` per view.\n * Use `asChild` for links that look like buttons, keeping the `a` semantics.\n * @dont Use `loading` on a button that is not the one that started the work.\n * Rely on colour to tell variants apart; the label carries the meaning.\n */\nexport function Button<E extends HTMLElement = HTMLButtonElement>({\n variant = 'primary',\n size = 'md',\n loading = false,\n iconStart,\n iconEnd,\n asChild = false,\n className,\n disabled = false,\n type,\n onClick,\n ref,\n children,\n ...rest\n}: ButtonProps<E>) {\n // Inert: must not activate. `disabled` on a real <button> also removes it\n // from the tab order, which is right for \"disabled\" and wrong for \"loading\":\n // the element the user just pressed must keep focus. So loading (and every\n // asChild state) uses aria-disabled and blocks activation in the handler.\n const inert = disabled || loading;\n const nativeDisabled = !asChild && disabled;\n\n if (DEV && !hasText(asChild ? (children as { props?: { children?: ReactNode } }).props?.children : children)) {\n if (!rest['aria-label'] && !rest['aria-labelledby']) {\n console.warn('Button: no text content and no aria-label. Icon-only buttons need an accessible name.');\n }\n }\n\n const props = {\n ...rest,\n ref,\n className: classes(styles.button, className),\n 'data-variant': variant,\n 'data-size': size,\n 'data-loading': loading ? '' : undefined,\n 'aria-busy': loading || undefined,\n disabled: nativeDisabled || undefined,\n 'aria-disabled': inert && !nativeDisabled ? true : undefined,\n type: asChild ? undefined : (type ?? 'button'),\n onClick: inert ? BLOCK : onClick,\n };\n\n const decorate = (label: ReactNode) => (\n <>\n {loading && <Spinner decorative size=\"inherit\" tone=\"inherit\" />}\n {iconStart && <Icon size=\"inherit\">{iconStart}</Icon>}\n <span className={styles.label}>{label}</span>\n {iconEnd && <Icon size=\"inherit\">{iconEnd}</Icon>}\n </>\n );\n\n if (asChild) {\n const child = children as { props?: { children?: ReactNode } };\n // The helper merges the forwarded ref with the child's; nothing reads it.\n // eslint-disable-next-line react-hooks/refs -- forwarded, not read\n return renderAsChild('Button', children, { ...props, children: decorate(child.props?.children) }, {\n // An inert control must not run the child's handler either.\n replace: inert ? ['onClick'] : [],\n });\n }\n\n return <button {...(props as ButtonHTMLAttributes<HTMLButtonElement>)}>{decorate(children)}</button>;\n}\n\nButton.displayName = 'Button';\n"]}