pulse_view_components 0.3.0 → 0.4.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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -1
  3. data/README.md +26 -0
  4. data/app/assets/builds/js/pulse_view_components.js +3 -3
  5. data/app/assets/builds/js/pulse_view_components.js.map +1 -1
  6. data/app/assets/builds/pulse_view_components.css +2 -1
  7. data/app/assets/stylesheets/pulse_view_components/application.tailwind.css +44 -4
  8. data/app/assets/stylesheets/pulse_view_components/tokens.primitives.css +68 -0
  9. data/app/assets/stylesheets/pulse_view_components/tokens.system.css +95 -0
  10. data/app/components/pulse/action_list/divider.rb +13 -4
  11. data/app/components/pulse/action_list/form_wrapper.rb +2 -0
  12. data/app/components/pulse/action_list/heading.html.slim +7 -0
  13. data/app/components/pulse/action_list/heading.rb +2 -0
  14. data/app/components/pulse/action_list/item.html.slim +6 -6
  15. data/app/components/pulse/action_list/item.rb +11 -9
  16. data/app/components/pulse/action_list.css +109 -82
  17. data/app/components/pulse/action_list.html.slim +11 -0
  18. data/app/components/pulse/action_list.rb +5 -0
  19. data/app/components/pulse/badge.rb +20 -16
  20. data/app/components/pulse/base_component.rb +25 -1
  21. data/app/components/pulse/blank_slate.rb +4 -2
  22. data/app/components/pulse/border_box/header.rb +5 -3
  23. data/app/components/pulse/border_box.rb +21 -17
  24. data/app/components/pulse/box.rb +2 -0
  25. data/app/components/pulse/breadcrumb_item.rb +3 -1
  26. data/app/components/pulse/breadcrumbs.html.slim +2 -2
  27. data/app/components/pulse/breadcrumbs.rb +2 -0
  28. data/app/components/pulse/button.rb +28 -25
  29. data/app/components/pulse/component.rb +2 -1
  30. data/app/components/pulse/conditional_wrapper.rb +2 -0
  31. data/app/components/pulse/content.rb +2 -0
  32. data/app/components/pulse/counter.css +3 -3
  33. data/app/components/pulse/counter.rb +4 -0
  34. data/app/components/pulse/flash.rb +10 -6
  35. data/app/components/pulse/forms/error_explanation.html.slim +3 -3
  36. data/app/components/pulse/forms/error_explanation.rb +30 -13
  37. data/app/components/pulse/forms/error_explanation.yml +4 -0
  38. data/app/components/pulse/icon.rb +2 -0
  39. data/app/components/pulse/label.rb +5 -3
  40. data/app/components/pulse/layout.css +53 -52
  41. data/app/components/pulse/layout.rb +14 -6
  42. data/app/components/pulse/link.rb +10 -8
  43. data/app/components/pulse/modal.html.slim +20 -20
  44. data/app/components/pulse/modal.rb +10 -8
  45. data/app/components/pulse/modal_controller.js +3 -3
  46. data/app/components/pulse/nav_link.html.slim +7 -7
  47. data/app/components/pulse/nav_link.rb +4 -2
  48. data/app/components/pulse/nav_list/heading.rb +3 -1
  49. data/app/components/pulse/nav_list/item.html.slim +8 -0
  50. data/app/components/pulse/nav_list/item.rb +2 -2
  51. data/app/components/pulse/nav_list.rb +5 -0
  52. data/app/components/pulse/popover.html.slim +1 -1
  53. data/app/components/pulse/popover.rb +65 -26
  54. data/app/components/pulse/progress_bar.html.slim +2 -2
  55. data/app/components/pulse/progress_bar.rb +5 -3
  56. data/app/components/pulse/table/cell.html.slim +2 -2
  57. data/app/components/pulse/table/cell.rb +14 -10
  58. data/app/components/pulse/table/column.rb +2 -0
  59. data/app/components/pulse/table.html.slim +3 -3
  60. data/app/components/pulse/table.rb +19 -16
  61. data/app/components/pulse/text.rb +26 -24
  62. data/app/components/pulse/toast.html.slim +8 -8
  63. data/app/components/pulse/toast.rb +25 -23
  64. data/app/lib/pulse/status.rb +48 -0
  65. data/lib/pulse/view_components/version.rb +1 -1
  66. data/previews/foundations/colors_preview/palettes.html.slim +12 -0
  67. data/previews/foundations/colors_preview/semantic.html.slim +16 -0
  68. data/previews/foundations/colors_preview.rb +55 -0
  69. data/previews/pulse/action_list_preview.rb +77 -0
  70. data/previews/pulse/border_box_preview.rb +1 -1
  71. data/previews/pulse/counter_preview.rb +1 -1
  72. data/previews/pulse/flash_preview.rb +1 -1
  73. data/previews/pulse/forms/error_explanation_preview.rb +49 -0
  74. data/previews/pulse/layout_preview.rb +5 -5
  75. data/previews/pulse/nav_list_preview.rb +1 -1
  76. data/previews/pulse/popover_preview.rb +48 -22
  77. data/previews/pulse/progress_bar_preview.rb +1 -1
  78. data/previews/pulse/table_preview.rb +6 -6
  79. metadata +17 -11
@@ -7,9 +7,25 @@
7
7
  --actionListContent-paddingBlock: var(--control-medium-paddingBlock);
8
8
  }
9
9
 
10
+ /*
11
+ Accent bar beside the selected or current item. Set
12
+ --activeIndicatorLine-offset to move it. Tailwind 4 has no mixins, so this
13
+ is a custom utility pulled in with `@apply`.
14
+ */
15
+ @utility active-indicator-line {
16
+ position: absolute;
17
+ top: calc(50% - 12px);
18
+ left: var(--activeIndicatorLine-offset, calc(-1 * var(--base-size-8)));
19
+ width: 4px;
20
+ height: 24px;
21
+ content: "";
22
+ background: var(--borderColor-accent-emphasis);
23
+ border-radius: var(--borderRadius-medium);
24
+ }
25
+
10
26
  /* ActionList */
11
27
  .ActionListHeader {
12
- @apply pulse-ml-[var(--base-size-8)] pulse-mb-[var(--base-size-16)];
28
+ @apply pulse:ml-[var(--base-size-8)] pulse:mb-[var(--base-size-16)];
13
29
  }
14
30
 
15
31
  /* <ul> */
@@ -17,12 +33,12 @@
17
33
  list-style: none;
18
34
  }
19
35
  .ActionListWrap--inset {
20
- @apply pulse-pt-[var(--base-size-8)] pulse-pr-[var(--base-size-8)] pulse-pb-[var(--base-size-8)] pulse-pl-[var(--base-size-8)];
36
+ @apply pulse:pt-[var(--base-size-8)] pulse:pr-[var(--base-size-8)] pulse:pb-[var(--base-size-8)] pulse:pl-[var(--base-size-8)];
21
37
  }
22
38
 
23
39
  /* list dividers */
24
40
  .ActionListWrap--divided .ActionListItem-label::before {
25
- @apply pulse-absolute pulse-top-[calc(-1_*_var(--actionListContent-paddingBlock))] pulse-block pulse-w-full pulse-h-px pulse-content-[''];
41
+ @apply pulse:absolute pulse:top-[calc(-1_*_var(--actionListContent-paddingBlock))] pulse:block pulse:w-full pulse:h-px pulse:content-[''];
26
42
  background: var(
27
43
  --borderColor-muted,
28
44
  var(--color-action-list-item-inline-divider)
@@ -31,7 +47,7 @@
31
47
 
32
48
  /* if descriptionWrap--inline exists, move pseudo divider to wrapper */
33
49
  .ActionListWrap--divided .ActionListItem-descriptionWrap--inline::before {
34
- @apply pulse-absolute pulse-top-[calc(-1_*_var(--actionListContent-paddingBlock))] pulse-block pulse-w-full pulse-h-[var(--borderWidth-thin)] pulse-content-[''];
50
+ @apply pulse:absolute pulse:top-[calc(-1_*_var(--actionListContent-paddingBlock))] pulse:block pulse:w-full pulse:h-[var(--borderWidth-thin)] pulse:content-[''];
35
51
  background: var(
36
52
  --borderColor-muted,
37
53
  var(--color-action-list-item-inline-divider)
@@ -42,7 +58,7 @@
42
58
  .ActionListWrap--divided
43
59
  .ActionListItem-descriptionWrap--inline
44
60
  .ActionListItem-label::before {
45
- @apply pulse-content-[unset];
61
+ @apply pulse:content-[unset];
46
62
  }
47
63
 
48
64
  /* hide divider if item is active */
@@ -53,13 +69,13 @@
53
69
  .ActionListItem--navActive
54
70
  + .ActionListItem
55
71
  .ActionListItem-label::before {
56
- @apply pulse-invisible;
72
+ @apply pulse:invisible;
57
73
  }
58
74
 
59
75
  /* hide if item is first of type with label::before, or is the first item after a sectionDivider */
60
76
  .ActionListItem:first-of-type .ActionListItem-label::before,
61
77
  .ActionList-sectionDivider + .ActionListItem .ActionListItem-label::before {
62
- @apply pulse-invisible;
78
+ @apply pulse:invisible;
63
79
  }
64
80
 
65
81
  /* hide if item is first of type with label::before, or is the first item after a sectionDivider */
@@ -67,49 +83,49 @@
67
83
  .ActionList-sectionDivider
68
84
  + .ActionListItem
69
85
  .ActionListItem-descriptionWrap--inline::before {
70
- @apply pulse-invisible;
86
+ @apply pulse:invisible;
71
87
  }
72
88
 
73
89
  /* ActionList::Item */
74
90
  .ActionListItem {
75
- @apply pulse-relative pulse-bg-[color:var(--control-transparent-bgColor-rest)] pulse-rounded-[var(--borderRadius-medium)] selected:pulse-font-[number:var(--base-text-weight-normal)];
91
+ @apply pulse:relative pulse:bg-[color:var(--control-transparent-bgColor-rest)] pulse:rounded-[var(--borderRadius-medium)] pulse:aria-selected:font-[number:var(--base-text-weight-normal)];
76
92
  list-style: none;
77
93
  }
78
94
 
79
95
  /* state */
80
96
  .ActionListItem:hover,
81
97
  .ActionListItem:active {
82
- @apply pulse-cursor-pointer;
98
+ @apply pulse:cursor-pointer;
83
99
  }
84
100
 
85
101
  /* hide dividers */
86
102
  @media (hover: hover) {
87
103
  .ActionListItem:hover .ActionListItem-label::before,
88
104
  .ActionListItem:hover + .ActionListItem .ActionListItem-label::before {
89
- @apply pulse-invisible;
105
+ @apply pulse:invisible;
90
106
  }
91
107
  .ActionListItem:hover .ActionListItem-descriptionWrap--inline::before,
92
108
  .ActionListItem:hover
93
109
  + .ActionListItem
94
110
  .ActionListItem-descriptionWrap--inline::before {
95
- @apply pulse-invisible;
111
+ @apply pulse:invisible;
96
112
  }
97
113
  }
98
114
 
99
115
  /* Make sure that the first visible item isn't a divider */
100
116
  .ActionListItem[hidden] + .ActionList-sectionDivider {
101
- @apply pulse-hidden;
117
+ @apply pulse:hidden;
102
118
  }
103
119
 
104
120
  /* collapse styles here */
105
121
 
106
122
  /* first child */
107
123
  .ActionListItem.ActionListItem--hasSubItem > .ActionListContent {
108
- @apply pulse-z-[1] active:pulse-bg-[color:var(--control-transparent-bgColor-active)];
124
+ @apply pulse:z-[1] pulse:active:bg-[color:var(--control-transparent-bgColor-active)];
109
125
  }
110
126
  @media (hover: hover) {
111
127
  .ActionListItem.ActionListItem--hasSubItem > .ActionListContent:hover {
112
- @apply pulse-bg-[color:var(--control-transparent-bgColor-hover)];
128
+ @apply pulse:bg-[color:var(--control-transparent-bgColor-hover)];
113
129
  }
114
130
  }
115
131
 
@@ -117,12 +133,15 @@
117
133
  @media (hover: hover) {
118
134
  .ActionListItem:not(.ActionListItem--hasSubItem):hover,
119
135
  .ActionListItem.ActionListItem--hasSubItem > .ActionListContent:hover {
120
- @apply pulse-cursor-pointer pulse-bg-[color:var(--control-transparent-bgColor-hover)];
136
+ @apply pulse:cursor-pointer pulse:bg-[color:var(--control-transparent-bgColor-hover)];
121
137
  }
122
- .ActionListItem:not(.ActionListItem--hasSubItem):hover:not(.ActionListItem--navActive, :focus-visible),
138
+ .ActionListItem:not(.ActionListItem--hasSubItem):hover:not(
139
+ .ActionListItem--navActive,
140
+ :focus-visible
141
+ ),
123
142
  .ActionListItem.ActionListItem--hasSubItem
124
143
  > .ActionListContent:hover:not(.ActionListItem--navActive, :focus-visible) {
125
- @apply pulse-outline-offset-[calc(-1_*_var(--borderWidth-thin))] pulse-shadow-[var(--boxShadow-thin)_var(--control-transparent-borderColor-active)];
144
+ @apply pulse:outline-offset-[calc(-1_*_var(--borderWidth-thin))] pulse:shadow-[var(--boxShadow-thin)_var(--control-transparent-borderColor-active)];
126
145
 
127
146
  /* Support for "Windows high contrast mode" */
128
147
  outline: solid var(--borderWidth-thin) transparent;
@@ -132,10 +151,12 @@
132
151
  .ActionListItem.ActionListItem--hasSubItem > .ActionListContent:active {
133
152
  background: var(--control-transparent-bgColor-active);
134
153
  }
135
- .ActionListItem:not(.ActionListItem--hasSubItem):active:not(.ActionListItem--navActive),
154
+ .ActionListItem:not(.ActionListItem--hasSubItem):active:not(
155
+ .ActionListItem--navActive
156
+ ),
136
157
  .ActionListItem.ActionListItem--hasSubItem
137
158
  > .ActionListContent:active:not(.ActionListItem--navActive) {
138
- @apply pulse-outline-offset-[calc(-1_*_var(--borderWidth-thin))] pulse-shadow-[var(--boxShadow-thin)_var(--control-transparent-borderColor-active)];
159
+ @apply pulse:outline-offset-[calc(-1_*_var(--borderWidth-thin))] pulse:shadow-[var(--boxShadow-thin)_var(--control-transparent-borderColor-active)];
139
160
 
140
161
  /* Support for "Windows high contrast mode" https:sarahmhigley.com/writing/whcm-quick-tips/ */
141
162
  outline: solid var(--borderWidth-thin) transparent;
@@ -152,7 +173,7 @@
152
173
  > .ActionListContent:active
153
174
  + .ActionListItem
154
175
  .ActionListItem-label::before {
155
- @apply pulse-invisible;
176
+ @apply pulse:invisible;
156
177
  }
157
178
 
158
179
  /* Autocomplete [aria-selected] items */
@@ -161,46 +182,47 @@
161
182
  }
162
183
  @media (hover: hover) {
163
184
  .ActionListItem[aria-selected="true"]:hover {
164
- @apply pulse-bg-[color:var(--control-transparent-bgColor-hover)];
185
+ @apply pulse:bg-[color:var(--control-transparent-bgColor-hover)];
165
186
  }
166
187
  }
167
188
  .ActionListItem[aria-selected="true"]::before,
168
189
  .ActionListItem[aria-selected="true"] + .ActionListItem::before {
169
- @apply pulse-invisible;
190
+ @apply pulse:invisible;
170
191
  }
171
192
 
172
193
  /* blue accent line */
173
194
  .ActionListItem[aria-selected="true"]::after {
174
- @mixin activeIndicatorLine calc(-1 * var(--base-size-4));
195
+ --activeIndicatorLine-offset: calc(-1 * var(--base-size-4));
196
+ @apply pulse:active-indicator-line;
175
197
  }
176
198
 
177
199
  /* active state [aria-current] */
178
200
  .ActionListItem.ActionListItem--navActive {
179
- @apply pulse-outline-none;
201
+ @apply pulse:outline-hidden;
180
202
 
181
203
  /* provides a visual indication of the current item for Windows high-contrast mode */
182
204
  }
183
205
  .ActionListItem.ActionListItem--navActive:not(.ActionListItem--subItem)
184
206
  .ActionListItem-label {
185
- @apply pulse-font-[number:var(--base-text-weight-semibold)];
207
+ @apply pulse:font-[number:var(--base-text-weight-semibold)];
186
208
  }
187
209
  .ActionListItem.ActionListItem--navActive:not(.ActionListItem--danger) {
188
210
  background: var(--control-transparent-bgColor-selected);
189
211
  }
190
212
  @media (hover: hover) {
191
213
  .ActionListItem.ActionListItem--navActive:not(.ActionListItem--danger):hover {
192
- @apply pulse-bg-[color:var(--control-transparent-bgColor-hover)];
214
+ @apply pulse:bg-[color:var(--control-transparent-bgColor-hover)];
193
215
  }
194
216
  }
195
217
  .ActionListItem.ActionListItem--navActive:not(.ActionListItem--danger)::before,
196
218
  .ActionListItem.ActionListItem--navActive:not(.ActionListItem--danger)
197
219
  + .ActionListItem::before {
198
- @apply pulse-invisible;
220
+ @apply pulse:invisible;
199
221
  }
200
222
 
201
223
  /* blue accent line */
202
224
  .ActionListItem.ActionListItem--navActive:not(.ActionListItem--danger)::after {
203
- @mixin activeIndicatorLine;
225
+ @apply pulse:active-indicator-line;
204
226
  }
205
227
 
206
228
  /* disabled */
@@ -214,7 +236,7 @@
214
236
  .ActionListItem[aria-disabled="true"]
215
237
  .ActionListContent
216
238
  .ActionListItem-description {
217
- @apply pulse-text-[color:var(--control-fgColor-disabled)];
239
+ @apply pulse:text-[color:var(--control-fgColor-disabled)];
218
240
  }
219
241
  .ActionListItem.ActionListItem--disabled
220
242
  .ActionListContent
@@ -222,12 +244,12 @@
222
244
  .ActionListItem[aria-disabled="true"]
223
245
  .ActionListContent
224
246
  .ActionListItem-visual {
225
- @apply pulse-fill-[var(--control-fgColor-disabled)];
247
+ @apply pulse:fill-[var(--control-fgColor-disabled)];
226
248
  }
227
249
  @media (hover: hover) {
228
250
  .ActionListItem.ActionListItem--disabled:hover,
229
251
  .ActionListItem[aria-disabled="true"]:hover {
230
- @apply pulse-cursor-not-allowed pulse-bg-transparent;
252
+ @apply pulse:cursor-not-allowed pulse:bg-transparent;
231
253
  }
232
254
  }
233
255
 
@@ -235,10 +257,10 @@
235
257
 
236
258
  /* danger */
237
259
  .ActionListItem.ActionListItem--danger .ActionListItem-label {
238
- @apply pulse-text-[color:var(--control-danger-fgColor-rest)];
260
+ @apply pulse:text-[color:var(--control-danger-fgColor-rest)];
239
261
  }
240
262
  .ActionListItem.ActionListItem--danger .ActionListItem-visual {
241
- @apply pulse-text-[color:var(--control-danger-fgColor-rest)];
263
+ @apply pulse:text-[color:var(--control-danger-fgColor-rest)];
242
264
  }
243
265
  @media (hover: hover) {
244
266
  .ActionListItem.ActionListItem--danger:hover {
@@ -247,7 +269,7 @@
247
269
  .ActionListItem.ActionListItem--danger:hover .ActionListItem-label,
248
270
  .ActionListItem.ActionListItem--danger:hover .ActionListItem-visual,
249
271
  .ActionListItem.ActionListItem--danger:hover .ActionListItem-description {
250
- @apply pulse-text-[color:var(--control-danger-fgColor-hover)];
272
+ @apply pulse:text-[color:var(--control-danger-fgColor-hover)];
251
273
  }
252
274
  }
253
275
  .ActionListItem.ActionListItem--danger .ActionListContent:active {
@@ -262,12 +284,12 @@
262
284
  .ActionListItem.ActionListItem--danger
263
285
  .ActionListContent:active
264
286
  .ActionListItem-description {
265
- @apply pulse-text-[color:var(--control-danger-fgColor-hover)];
287
+ @apply pulse:text-[color:var(--control-danger-fgColor-hover)];
266
288
  }
267
289
 
268
290
  /* button or a href */
269
291
  .ActionListContent {
270
- @apply pulse-relative pulse-grid pulse-w-full pulse-text-[color:var(--control-fgColor-rest)] pulse-text-left pulse-select-none pulse-bg-transparent pulse-rounded-[var(--borderRadius-medium)] pulse-transition-[background] pulse-duration-[33.333ms] pulse-ease-linear pulse-touch-manipulation pulse-grid-rows-[min-content] pulse-grid-cols-[min-content_min-content_minmax(0,auto)_min-content_min-content] pulse-border-[none] hover:pulse-no-underline;
292
+ @apply pulse:relative pulse:grid pulse:w-full pulse:text-[color:var(--control-fgColor-rest)] pulse:text-left pulse:select-none pulse:bg-transparent pulse:rounded-[var(--borderRadius-medium)] pulse:transition-[background] pulse:duration-[33.333ms] pulse:ease-linear pulse:touch-manipulation pulse:grid-rows-[min-content] pulse:grid-cols-[min-content_min-content_minmax(0,auto)_min-content_min-content] pulse:border-none pulse:hover:no-underline;
271
293
  padding-block: var(--actionListContent-paddingBlock);
272
294
  padding-inline: var(--control-medium-paddingInline-condensed);
273
295
  -webkit-tap-highlight-color: transparent;
@@ -276,20 +298,20 @@
276
298
  }
277
299
  /* column-gap persists with empty grid-areas, margin applies only when children exist */
278
300
  .ActionListContent > :not(:last-child) {
279
- @apply pulse-mr-[var(--control-medium-gap)];
301
+ @apply pulse:mr-[var(--control-medium-gap)];
280
302
  }
281
303
  /* state */
282
304
  /* disabled */
283
305
  .ActionListContent[aria-disabled="true"] .ActionListItem-label,
284
306
  .ActionListContent[aria-disabled="true"] .ActionListItem-description {
285
- @apply pulse-text-[color:var(--control-fgColor-disabled)];
307
+ @apply pulse:text-[color:var(--control-fgColor-disabled)];
286
308
  }
287
309
  .ActionListContent[aria-disabled="true"] .ActionListItem-visual {
288
- @apply pulse-fill-[var(--control-fgColor-disabled)];
310
+ @apply pulse:fill-[var(--control-fgColor-disabled)];
289
311
  }
290
312
  @media (hover: hover) {
291
313
  .ActionListContent[aria-disabled="true"]:hover {
292
- @apply pulse-cursor-not-allowed pulse-bg-transparent;
314
+ @apply pulse:cursor-not-allowed pulse:bg-transparent;
293
315
  }
294
316
  }
295
317
  /* collapsible item [aria-expanded] */
@@ -297,46 +319,47 @@
297
319
  target items inside expanded subgroups */
298
320
  @media screen and (prefers-reduced-motion: no-preference) {
299
321
  .ActionListContent[aria-expanded] + .ActionList--subGroup {
300
- transition: opacity 160ms cubic-bezier(0.25, 1, 0.5, 1),
322
+ transition:
323
+ opacity 160ms cubic-bezier(0.25, 1, 0.5, 1),
301
324
  transform 160ms cubic-bezier(0.25, 1, 0.5, 1);
302
325
  }
303
326
  }
304
327
  .ActionListContent[aria-expanded] + .ActionList--subGroup .ActionListContent {
305
- @apply pulse-pl-[var(--base-size-24)];
328
+ @apply pulse:pl-[var(--base-size-24)];
306
329
  }
307
330
  /* has 16px leading visual */
308
331
  .ActionListContent[aria-expanded].ActionListContent--visual16
309
332
  + .ActionList--subGroup
310
333
  .ActionListContent {
311
- @apply pulse-pl-[var(--base-size-32)];
334
+ @apply pulse:pl-[var(--base-size-32)];
312
335
  }
313
336
  /* has 20px leading visual */
314
337
  .ActionListContent[aria-expanded].ActionListContent--visual20
315
338
  + .ActionList--subGroup
316
339
  .ActionListContent {
317
- @apply pulse-pl-[var(--base-size-36)];
340
+ @apply pulse:pl-[var(--base-size-36)];
318
341
  }
319
342
  /* has 24px leading visual */
320
343
  .ActionListContent[aria-expanded].ActionListContent--visual24
321
344
  + .ActionList--subGroup
322
345
  .ActionListContent {
323
- @apply pulse-pl-[var(--base-size-40)];
346
+ @apply pulse:pl-[var(--base-size-40)];
324
347
  }
325
348
  .ActionListContent[aria-expanded="true"] .ActionListItem-collapseIcon {
326
- @apply pulse-transition-transform pulse-duration-[120ms] pulse-ease-linear -pulse-scale-y-100;
349
+ @apply pulse:transition-transform pulse:duration-[120ms] pulse:ease-linear pulse:-scale-y-100;
327
350
  }
328
351
  .ActionListContent[aria-expanded="true"] + .ActionList--subGroup {
329
- @apply pulse-h-auto pulse-overflow-visible pulse-visible pulse-opacity-100 pulse-translate-y-0;
352
+ @apply pulse:h-auto pulse:overflow-visible pulse:visible pulse:opacity-100 pulse:translate-y-0;
330
353
  }
331
354
  .ActionListContent[aria-expanded="true"].ActionListContent--hasActiveSubItem
332
355
  > .ActionListItem-label {
333
- @apply pulse-font-[number:var(--base-text-weight-semibold)];
356
+ @apply pulse:font-[number:var(--base-text-weight-semibold)];
334
357
  }
335
358
  .ActionListContent[aria-expanded="false"] .ActionListItem-collapseIcon {
336
- @apply pulse-transition-transform pulse-duration-[120ms] pulse-ease-linear pulse-scale-y-100;
359
+ @apply pulse:transition-transform pulse:duration-[120ms] pulse:ease-linear pulse:scale-y-100;
337
360
  }
338
361
  .ActionListContent[aria-expanded="false"] + .ActionList--subGroup {
339
- @apply pulse-h-0 pulse-overflow-hidden pulse-invisible pulse-opacity-0 pulse-translate-y-[calc(-1_*_var(--base-size-16];
362
+ @apply pulse:h-0 pulse:overflow-hidden pulse:invisible pulse:opacity-0 pulse:translate-y-[calc(-1_*_var(--base-size-16))];
340
363
  }
341
364
  /* show active indicator on parent collapse if child is active */
342
365
  .ActionListContent[aria-expanded="false"].ActionListContent--hasActiveSubItem {
@@ -344,16 +367,16 @@
344
367
  }
345
368
  .ActionListContent[aria-expanded="false"].ActionListContent--hasActiveSubItem
346
369
  .ActionListItem-label {
347
- @apply pulse-font-[number:var(--base-text-weight-semibold)];
370
+ @apply pulse:font-[number:var(--base-text-weight-semibold)];
348
371
  }
349
372
  .ActionListContent[aria-expanded="false"].ActionListContent--hasActiveSubItem::before,
350
373
  .ActionListContent[aria-expanded="false"].ActionListContent--hasActiveSubItem
351
374
  + .ActionListItem::before {
352
- @apply pulse-invisible;
375
+ @apply pulse:invisible;
353
376
  }
354
377
  /* blue accent line */
355
378
  .ActionListContent[aria-expanded="false"].ActionListContent--hasActiveSubItem::after {
356
- @mixin activeIndicatorLine;
379
+ @apply pulse:active-indicator-line;
357
380
  }
358
381
  /*
359
382
  * checkbox item [aria-checked]
@@ -362,13 +385,15 @@
362
385
  /* multiselect checkmark */
363
386
  .ActionListContent[aria-checked="true"] .ActionListItem-multiSelectCheckmark,
364
387
  .ActionListContent[aria-selected="true"] .ActionListItem-multiSelectCheckmark {
365
- @apply pulse-visible pulse-opacity-100;
366
- transition: visibility 0 linear 0, opacity 50ms;
388
+ @apply pulse:visible pulse:opacity-100;
389
+ transition:
390
+ visibility 0 linear 0,
391
+ opacity 50ms;
367
392
  }
368
393
  /* singleselect checkmark */
369
394
  .ActionListContent[aria-checked="true"] .ActionListItem-singleSelectCheckmark,
370
395
  .ActionListContent[aria-selected="true"] .ActionListItem-singleSelectCheckmark {
371
- @apply pulse-visible motion-safe:pulse-animate-[checkmarkIn_200ms_cubic-bezier(0.11,0,0.5,0)_forwards];
396
+ @apply pulse:visible pulse:motion-safe:animate-[checkmarkIn_200ms_cubic-bezier(0.11,0,0.5,0)_forwards];
372
397
  }
373
398
  @media screen and (prefers-reduced-motion: no-preference) {
374
399
  @keyframes checkmarkIn {
@@ -387,7 +412,7 @@
387
412
  .ActionListContent[aria-selected="true"]
388
413
  .ActionListItem-multiSelectIcon
389
414
  .ActionListItem-multiSelectIconRect {
390
- @apply pulse-fill-[var(--control-checked-bgColor-rest)] pulse-stroke-[color:var(--control-checked-bgColor-rest)] pulse-stroke-[length:var(--borderWidth-thin,1px)];
415
+ @apply pulse:fill-[var(--control-checked-bgColor-rest)] pulse:stroke-[color:var(--control-checked-bgColor-rest)] pulse:stroke-[length:var(--borderWidth-thin,1px)];
391
416
  }
392
417
  .ActionListContent[aria-checked="true"]
393
418
  .ActionListItem-multiSelectIcon
@@ -395,19 +420,21 @@
395
420
  .ActionListContent[aria-selected="true"]
396
421
  .ActionListItem-multiSelectIcon
397
422
  .ActionListItem-multiSelectCheckmark {
398
- @apply pulse-fill-[var(--pulse-fgColor-onEmphasis)];
423
+ @apply pulse:fill-[var(--pulse-fgColor-onEmphasis)];
399
424
  }
400
425
  /* multiselect checkmark */
401
426
  .ActionListContent[aria-checked="false"] .ActionListItem-multiSelectCheckmark,
402
427
  .ActionListContent[aria-selected="false"] .ActionListItem-multiSelectCheckmark {
403
- @apply pulse-invisible pulse-opacity-0;
404
- transition: visibility 0 linear 50ms, opacity 50ms;
428
+ @apply pulse:invisible pulse:opacity-0;
429
+ transition:
430
+ visibility 0 linear 50ms,
431
+ opacity 50ms;
405
432
  }
406
433
  /* singleselect checkmark */
407
434
  .ActionListContent[aria-checked="false"] .ActionListItem-singleSelectCheckmark,
408
435
  .ActionListContent[aria-selected="false"]
409
436
  .ActionListItem-singleSelectCheckmark {
410
- @apply pulse-invisible pulse-transition-[visibility] pulse-duration-[0s] pulse-ease-linear pulse-delay-200 motion-safe:pulse-animate-[checkmarkOut_200ms_cubic-bezier(0.11,0,0.5,0)_forwards];
437
+ @apply pulse:invisible pulse:transition-[visibility] pulse:duration-[0s] pulse:ease-linear pulse:delay-200 pulse:motion-safe:animate-[checkmarkOut_200ms_cubic-bezier(0.11,0,0.5,0)_forwards];
411
438
  clip-path: inset(16px 0 0 0);
412
439
  }
413
440
  @media screen and (prefers-reduced-motion: no-preference) {
@@ -427,11 +454,11 @@
427
454
  .ActionListContent[aria-selected="false"]
428
455
  .ActionListItem-multiSelectIcon
429
456
  .ActionListItem-multiSelectIconRect {
430
- @apply pulse-fill-[var(--bgColor-default)] pulse-stroke-[color:var(--control-borderColor-rest)] pulse-stroke-[length:var(--borderWidth-thin,1px)];
457
+ @apply pulse:fill-[var(--bgColor-default)] pulse:stroke-[color:var(--control-borderColor-rest)] pulse:stroke-[length:var(--borderWidth-thin,1px)];
431
458
  }
432
459
  .ActionListContent[aria-checked="false"] .ActionListItem-multiSelectIconRect,
433
460
  .ActionListContent[aria-selected="false"] .ActionListItem-multiSelectIconRect {
434
- @apply pulse-fill-[var(--bgColor-default)] pulse-border-[var(--borderWidth-thin,] pulse-border-[solid_var(--control-borderColor-rest)];
461
+ @apply pulse:fill-[var(--bgColor-default)] pulse:border-[length:var(--borderWidth-thin,1px)] pulse:border-solid pulse:border-[color:var(--control-borderColor-rest)];
435
462
  }
436
463
  /* sizes */
437
464
  .ActionListContent.ActionListContent--sizeLarge {
@@ -448,7 +475,7 @@
448
475
  }
449
476
  /* if leading/trailing visual, align with first line of content */
450
477
  .ActionListContent.ActionListContent--blockDescription .ActionListItem-visual {
451
- @apply pulse-place-self-start;
478
+ @apply pulse:place-self-start;
452
479
  }
453
480
 
454
481
  /* place children on grid */
@@ -467,81 +494,81 @@
467
494
 
468
495
  /* have leading visual svg filled with chosen color */
469
496
  /* .ActionListItem-visual--leading svg {
470
- @apply pulse-fill-[currentcolor];
497
+ @apply pulse:fill-[currentcolor];
471
498
  } */
472
499
 
473
500
  /* wrapper span
474
501
  default block */
475
502
  .ActionListItem-descriptionWrap {
476
- @apply pulse-flex pulse-flex-col pulse-gap-[var(--base-size-4)];
503
+ @apply pulse:flex pulse:flex-col pulse:gap-[var(--base-size-4)];
477
504
  grid-area: label;
478
505
  }
479
506
  .ActionListItem-descriptionWrap .ActionListItem-label {
480
- @apply pulse-font-[number:var(--base-text-weight-semibold)];
507
+ @apply pulse:font-[number:var(--base-text-weight-semibold)];
481
508
  }
482
509
 
483
510
  /* inline */
484
511
  .ActionListItem-descriptionWrap--inline {
485
- @apply pulse-relative pulse-flex-row pulse-items-baseline pulse-gap-[var(--base-size-8)];
512
+ @apply pulse:relative pulse:flex-row pulse:items-baseline pulse:gap-[var(--base-size-8)];
486
513
  }
487
514
 
488
515
  /* description */
489
516
  .ActionListItem-description {
490
- @apply pulse-text-[length:var(--text-body-size-small)] pulse-font-[number:var(--base-text-weight-normal)] pulse-leading-[var(--text-body-lineHeight-small)] pulse-text-[color:var(--fgColor-muted)];
517
+ @apply pulse:text-[length:var(--text-body-size-small)] pulse:font-[number:var(--base-text-weight-normal)] pulse:leading-[var(--text-body-lineHeight-small)] pulse:text-[color:var(--fgColor-muted)];
491
518
  }
492
519
 
493
520
  /* helper for grid alignment with multi-line content
494
521
  span wrapping svg or text */
495
522
  .ActionListItem-visual,
496
523
  .ActionListItem-action {
497
- @apply pulse-flex pulse-min-h-[var(--control-medium-lineBoxHeight)] pulse-text-[color:var(--fgColor-muted)] pulse-pointer-events-none pulse-fill-[var(--fgColor-muted)] pulse-items-center;
524
+ @apply pulse:flex pulse:min-h-[var(--control-medium-lineBoxHeight)] pulse:text-[color:var(--fgColor-muted)] pulse:pointer-events-none pulse:fill-[var(--fgColor-muted)] pulse:items-center;
498
525
  }
499
526
 
500
527
  /* text */
501
528
  .ActionListItem-label {
502
- @apply pulse-relative pulse-text-[length:var(--text-body-size-medium)] pulse-font-[number:var(--base-text-weight-normal)] pulse-leading-[var(--text-body-lineHeight-medium)] pulse-text-[color:var(--fgColor-default)];
529
+ @apply pulse:relative pulse:text-[length:var(--text-body-size-medium)] pulse:font-[number:var(--base-text-weight-normal)] pulse:leading-[var(--text-body-lineHeight-medium)] pulse:text-[color:var(--fgColor-default)];
503
530
  grid-area: label;
504
531
  }
505
532
  .ActionListItem-label--truncate {
506
- @apply pulse-overflow-hidden pulse-text-ellipsis pulse-whitespace-nowrap;
533
+ @apply pulse:overflow-hidden pulse:text-ellipsis pulse:whitespace-nowrap;
507
534
  }
508
535
 
509
536
  /* nested lists (only supports 1 level currently)
510
537
  target ActionListItem--subItem for padding-left to maintain :active :after state */
511
538
  .ActionListItem--subItem > .ActionListContent > .ActionListItem-label {
512
- @apply pulse-text-[length:var(--text-body-size-small)] pulse-leading-[var(--text-body-lineHeight-small)];
539
+ @apply pulse:text-[length:var(--text-body-size-small)] pulse:leading-[var(--text-body-lineHeight-small)];
513
540
  }
514
541
 
515
542
  /* trailing action icon button */
516
543
  .ActionListItem--withActions {
517
- @apply pulse-flex pulse-flex-nowrap pulse-items-center;
544
+ @apply pulse:flex pulse:flex-nowrap pulse:items-center;
518
545
  }
519
546
  .ActionListItem-trailingAction {
520
- @apply pulse-rounded-tl-none pulse-rounded-bl-none;
547
+ @apply pulse:rounded-tl-none pulse:rounded-bl-none;
521
548
  }
522
549
 
523
550
  /* show trailing action button on hover */
524
551
  .ActionListItem--trailingActionHover .ActionListItem-trailingAction {
525
- @apply pulse-invisible;
552
+ @apply pulse:invisible;
526
553
  }
527
554
  .ActionListItem--trailingActionHover:hover .ActionListItem-trailingAction,
528
555
  .ActionListItem--trailingActionHover:focus-within
529
556
  .ActionListItem-trailingAction {
530
- @apply pulse-visible;
557
+ @apply pulse:visible;
531
558
  }
532
559
 
533
560
  /* ActionList::Divider */
534
561
 
535
562
  /* with children */
536
563
  .ActionList-sectionDivider:not(:empty) {
537
- @apply pulse-flex pulse-text-[length:var(--text-body-size-small)] pulse-leading-[var(--text-body-lineHeight-small)] pulse-font-[number:var(--base-text-weight-semibold)] pulse-text-[color:var(--fgColor-muted)] pulse-flex-col;
564
+ @apply pulse:flex pulse:text-[length:var(--text-body-size-small)] pulse:leading-[var(--text-body-lineHeight-small)] pulse:font-[number:var(--base-text-weight-semibold)] pulse:text-[color:var(--fgColor-muted)] pulse:flex-col;
538
565
  padding-inline: var(--actionListContent-paddingBlock);
539
566
  padding-block: var(--base-size-8);
540
567
  }
541
568
 
542
569
  /* no children */
543
570
  .ActionList-sectionDivider:empty {
544
- @apply pulse-block pulse-h-[var(--borderWidth-thin)] pulse-p-0 pulse-border-0;
571
+ @apply pulse:block pulse:h-[var(--borderWidth-thin)] pulse:p-0 pulse:border-0;
545
572
  margin-block-start: calc(var(--base-size-8) - var(--borderWidth-thin));
546
573
  margin-block-end: var(--base-size-8);
547
574
  margin-inline: calc(-1 * var(--base-size-8));
@@ -552,10 +579,10 @@
552
579
  );
553
580
  }
554
581
  .ActionList-sectionDivider .ActionList-sectionDivider-title {
555
- @apply pulse-text-[length:var(--text-body-size-small)] pulse-font-[number:var(--base-text-weight-semibold)] pulse-text-[color:var(--fgColor-muted)];
582
+ @apply pulse:text-[length:var(--text-body-size-small)] pulse:font-[number:var(--base-text-weight-semibold)] pulse:text-[color:var(--fgColor-muted)];
556
583
  }
557
584
  .ActionList-sectionDivider--filled {
558
- @apply pulse-border-t-[color:var(--borderColor-muted,var(--color-action-list-item-inline-divider))] pulse-border-b-[color:var(--borderColor-muted,var(--color-action-list-item-inline-divider))] pulse-border-y-[solid] empty:pulse-h-[var(--base-size-8)] empty:pulse-box-border;
585
+ @apply pulse:border-t-[color:var(--borderColor-muted,var(--color-action-list-item-inline-divider))] pulse:border-b-[color:var(--borderColor-muted,var(--color-action-list-item-inline-divider))] pulse:[border-block-style:solid] pulse:empty:h-[var(--base-size-8)] pulse:empty:box-border;
559
586
  margin-block-start: calc(var(--base-size-8) - var(--borderWidth-thin));
560
587
  margin-block-end: var(--base-size-8);
561
588
  margin-inline: calc(-1 * var(--base-size-8));
@@ -0,0 +1,11 @@
1
+ /! components/pulse/action_list
2
+ = render(Pulse::BaseComponent.new(tag: :div, **@list_wrapper_arguments)) do
3
+ = heading
4
+ = render(Pulse::BaseComponent.new(**@system_arguments)) do
5
+ - items.each_with_index do |item, index|
6
+ - if index > 0 && @show_dividers && !item.respond_to?(:divider?) && !items[index - 1].respond_to?(:divider?)
7
+ = render(Pulse::ActionList::Divider.new)
8
+ = item
9
+
10
+ - if post_list_content_block
11
+ = capture(&post_list_content_block)
@@ -8,6 +8,11 @@ module Pulse
8
8
  # Each item in an action list can be augmented by specifying corresponding leading
9
9
  # and/or trailing visuals.
10
10
  class ActionList < Pulse::Component
11
+ # Incomplete: select variants, trailing actions, tooltips, avatar items and
12
+ # the `:inset` scheme depend on Primer CSS or components that Pulse does
13
+ # not ship. Links, visuals, descriptions, headings and dividers work.
14
+ status :alpha
15
+
11
16
  DEFAULT_ROLE = :list
12
17
 
13
18
  MENU_ROLE = :menu
@@ -4,32 +4,36 @@ module Pulse
4
4
  # Renders a badge component
5
5
  # see: /lookbook/inspect/pulse/badge/default
6
6
  class Badge < Pulse::Component
7
+ status :stable
8
+
7
9
  DEFAULT_TAG = :span
8
10
  TAG_OPTIONS = [DEFAULT_TAG, :summary, :a, :div].freeze
9
11
 
10
12
  DEFAULT_VARIANT = :standard
11
13
  VARIANT_MAPPINGS = {
12
- standard: 'pulse-inline-block pulse-rounded pulse-uppercase ' \
13
- 'pulse-py-0.5 pulse-px-1.5 pulse-text-[10px] ' \
14
- 'pulse-font-bold',
15
- pill: 'pulse-inline-block pulse-rounded-2xl pulse-min-w-[8rem] ' \
16
- 'pulse-text-center pulse-p-2 pulse-text-sm ' \
17
- 'pulse-leading-none pulse-font-bold'
14
+ standard: 'pulse:inline-block pulse:rounded pulse:uppercase ' \
15
+ 'pulse:py-0.5 pulse:px-1.5 pulse:text-[10px] ' \
16
+ 'pulse:font-bold',
17
+ pill: 'pulse:inline-block pulse:rounded-2xl pulse:min-w-32 ' \
18
+ 'pulse:text-center pulse:p-2 pulse:text-sm ' \
19
+ 'pulse:leading-none pulse:font-bold'
18
20
  }.freeze
19
21
  VARIANT_OPTIONS = VARIANT_MAPPINGS.keys.freeze
20
22
 
21
23
  DEFAULT_SCHEME = :secondary
22
24
  SCHEME_MAPPINGS = {
23
- primary: 'pulse-bg-primary pulse-text-white hover:pulse-text-white',
24
- secondary: 'pulse-bg-secondary pulse-text-white',
25
- secondary_outline: 'pulse-bg-white pulse-border pulse-border-secondary ' \
26
- 'pulse-text-secondary ' \
27
- 'pulse-hover:pulse-text-secondary',
28
- invited: 'pulse-bg-secondary-200 pulse-text-gray ' \
29
- 'pulse-hover:pulse-text-gray',
30
- active: 'pulse-bg-success-200 pulse-text-gray hover:pulse-text-gray',
31
- disabled: 'pulse-bg-gray-100 pulse-text-gray hover:pulse-text-gray',
32
- info: 'pulse-bg-gray-600 pulse-text-white hover:pulse-text-white'
25
+ primary: 'pulse:bg-primary pulse:text-white pulse:hover:text-white',
26
+ secondary: 'pulse:bg-secondary pulse:text-white',
27
+ secondary_outline: 'pulse:bg-white pulse:border pulse:border-secondary ' \
28
+ 'pulse:text-secondary ' \
29
+ 'pulse:hover:text-secondary',
30
+ invited: 'pulse:bg-secondary-200 pulse:text-neutral-700 ' \
31
+ 'pulse:hover:text-neutral-700',
32
+ active: 'pulse:bg-success-200 pulse:text-neutral-700 ' \
33
+ 'pulse:hover:text-neutral-700',
34
+ disabled: 'pulse:bg-neutral-100 pulse:text-neutral-700 ' \
35
+ 'pulse:hover:text-neutral-700',
36
+ info: 'pulse:bg-neutral-600 pulse:text-white pulse:hover:text-white'
33
37
  }.freeze
34
38
  SCHEME_OPTIONS = SCHEME_MAPPINGS.keys.freeze
35
39