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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +98 -1
- data/README.md +26 -0
- data/app/assets/builds/js/pulse_view_components.js +3 -3
- data/app/assets/builds/js/pulse_view_components.js.map +1 -1
- data/app/assets/builds/pulse_view_components.css +2 -1
- data/app/assets/stylesheets/pulse_view_components/application.tailwind.css +44 -4
- data/app/assets/stylesheets/pulse_view_components/tokens.primitives.css +68 -0
- data/app/assets/stylesheets/pulse_view_components/tokens.system.css +95 -0
- data/app/components/pulse/action_list/divider.rb +13 -4
- data/app/components/pulse/action_list/form_wrapper.rb +2 -0
- data/app/components/pulse/action_list/heading.html.slim +7 -0
- data/app/components/pulse/action_list/heading.rb +2 -0
- data/app/components/pulse/action_list/item.html.slim +6 -6
- data/app/components/pulse/action_list/item.rb +11 -9
- data/app/components/pulse/action_list.css +109 -82
- data/app/components/pulse/action_list.html.slim +11 -0
- data/app/components/pulse/action_list.rb +5 -0
- data/app/components/pulse/badge.rb +20 -16
- data/app/components/pulse/base_component.rb +25 -1
- data/app/components/pulse/blank_slate.rb +4 -2
- data/app/components/pulse/border_box/header.rb +5 -3
- data/app/components/pulse/border_box.rb +21 -17
- data/app/components/pulse/box.rb +2 -0
- data/app/components/pulse/breadcrumb_item.rb +3 -1
- data/app/components/pulse/breadcrumbs.html.slim +2 -2
- data/app/components/pulse/breadcrumbs.rb +2 -0
- data/app/components/pulse/button.rb +28 -25
- data/app/components/pulse/component.rb +2 -1
- data/app/components/pulse/conditional_wrapper.rb +2 -0
- data/app/components/pulse/content.rb +2 -0
- data/app/components/pulse/counter.css +3 -3
- data/app/components/pulse/counter.rb +4 -0
- data/app/components/pulse/flash.rb +10 -6
- data/app/components/pulse/forms/error_explanation.html.slim +3 -3
- data/app/components/pulse/forms/error_explanation.rb +30 -13
- data/app/components/pulse/forms/error_explanation.yml +4 -0
- data/app/components/pulse/icon.rb +2 -0
- data/app/components/pulse/label.rb +5 -3
- data/app/components/pulse/layout.css +53 -52
- data/app/components/pulse/layout.rb +14 -6
- data/app/components/pulse/link.rb +10 -8
- data/app/components/pulse/modal.html.slim +20 -20
- data/app/components/pulse/modal.rb +10 -8
- data/app/components/pulse/modal_controller.js +3 -3
- data/app/components/pulse/nav_link.html.slim +7 -7
- data/app/components/pulse/nav_link.rb +4 -2
- data/app/components/pulse/nav_list/heading.rb +3 -1
- data/app/components/pulse/nav_list/item.html.slim +8 -0
- data/app/components/pulse/nav_list/item.rb +2 -2
- data/app/components/pulse/nav_list.rb +5 -0
- data/app/components/pulse/popover.html.slim +1 -1
- data/app/components/pulse/popover.rb +65 -26
- data/app/components/pulse/progress_bar.html.slim +2 -2
- data/app/components/pulse/progress_bar.rb +5 -3
- data/app/components/pulse/table/cell.html.slim +2 -2
- data/app/components/pulse/table/cell.rb +14 -10
- data/app/components/pulse/table/column.rb +2 -0
- data/app/components/pulse/table.html.slim +3 -3
- data/app/components/pulse/table.rb +19 -16
- data/app/components/pulse/text.rb +26 -24
- data/app/components/pulse/toast.html.slim +8 -8
- data/app/components/pulse/toast.rb +25 -23
- data/app/lib/pulse/status.rb +48 -0
- data/lib/pulse/view_components/version.rb +1 -1
- data/previews/foundations/colors_preview/palettes.html.slim +12 -0
- data/previews/foundations/colors_preview/semantic.html.slim +16 -0
- data/previews/foundations/colors_preview.rb +55 -0
- data/previews/pulse/action_list_preview.rb +77 -0
- data/previews/pulse/border_box_preview.rb +1 -1
- data/previews/pulse/counter_preview.rb +1 -1
- data/previews/pulse/flash_preview.rb +1 -1
- data/previews/pulse/forms/error_explanation_preview.rb +49 -0
- data/previews/pulse/layout_preview.rb +5 -5
- data/previews/pulse/nav_list_preview.rb +1 -1
- data/previews/pulse/popover_preview.rb +48 -22
- data/previews/pulse/progress_bar_preview.rb +1 -1
- data/previews/pulse/table_preview.rb +6 -6
- metadata +17 -11
|
@@ -1,95 +1,96 @@
|
|
|
1
1
|
/* Layout */
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/*
|
|
4
|
+
Stacks the sidebar and main columns vertically. Applied below a breakpoint
|
|
5
|
+
by the media queries after `.Layout`. Tailwind 4 has no mixins, so this is a
|
|
6
|
+
custom utility pulled in with `@apply`.
|
|
7
|
+
*/
|
|
8
|
+
@utility layout-flow-row {
|
|
4
9
|
grid-auto-flow: row;
|
|
5
10
|
grid-template-columns: 1fr !important;
|
|
6
11
|
|
|
7
12
|
& .Layout-sidebar,
|
|
8
13
|
& .Layout-divider,
|
|
9
14
|
& .Layout-main {
|
|
10
|
-
@apply pulse
|
|
15
|
+
@apply pulse:w-full pulse:col-[1];
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
&.Layout--sidebarPosition-flowRow-start {
|
|
14
19
|
& .Layout-sidebar {
|
|
15
|
-
@apply pulse
|
|
20
|
+
@apply pulse:row-[1];
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
& .Layout-main {
|
|
19
|
-
@apply pulse
|
|
24
|
+
@apply pulse:row-[2_/_span_2];
|
|
20
25
|
}
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
&.Layout--sidebarPosition-flowRow-end {
|
|
24
29
|
& .Layout-sidebar {
|
|
25
|
-
@apply pulse
|
|
30
|
+
@apply pulse:row-[2_/_span_2];
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
& .Layout-main {
|
|
29
|
-
@apply pulse
|
|
34
|
+
@apply pulse:row-[1];
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
&.Layout--sidebarPosition-flowRow-none {
|
|
34
39
|
& .Layout-sidebar {
|
|
35
|
-
@apply pulse
|
|
40
|
+
@apply pulse:hidden;
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
&.Layout--divided {
|
|
40
|
-
|
|
45
|
+
--Layout-gutter: 0;
|
|
46
|
+
|
|
47
|
+
& .Layout-divider {
|
|
48
|
+
@apply pulse:h-px pulse:row-[2];
|
|
49
|
+
|
|
50
|
+
&.Layout-divider--flowRow-hidden {
|
|
51
|
+
@apply pulse:hidden;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.Layout-divider--flowRow-shallow {
|
|
55
|
+
@apply pulse:h-2 pulse:border-[color:var(--borderColor-default)] pulse:[border-width:var(--borderWidth-thin)_0] pulse:mr-0 pulse:border-solid;
|
|
56
|
+
background: var(--bgColor-inset);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
41
59
|
|
|
42
60
|
& .Layout-main {
|
|
43
|
-
@apply pulse
|
|
61
|
+
@apply pulse:row-[3_/_span_1];
|
|
44
62
|
}
|
|
45
63
|
|
|
46
64
|
&.Layout--sidebarPosition-flowRow-end {
|
|
47
65
|
& .Layout-sidebar {
|
|
48
|
-
@apply pulse
|
|
66
|
+
@apply pulse:row-[3_/_span_1];
|
|
49
67
|
}
|
|
50
68
|
|
|
51
69
|
& .Layout-main {
|
|
52
|
-
@apply pulse
|
|
70
|
+
@apply pulse:row-[1];
|
|
53
71
|
}
|
|
54
72
|
}
|
|
55
73
|
}
|
|
56
74
|
}
|
|
57
75
|
|
|
58
|
-
@define-mixin flow-as-row-divider {
|
|
59
|
-
--Layout-gutter: 0;
|
|
60
|
-
|
|
61
|
-
& .Layout-divider {
|
|
62
|
-
@apply pulse-h-px pulse-row-[2];
|
|
63
|
-
|
|
64
|
-
&.Layout-divider--flowRow-hidden {
|
|
65
|
-
@apply pulse-hidden;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
&.Layout-divider--flowRow-shallow {
|
|
69
|
-
@apply pulse-h-2 pulse-border-[color:var(--borderColor-default)] pulse-border-[var(--borderWidth-thin)_0] pulse-mr-0 pulse-border-solid;
|
|
70
|
-
background: var(--bgColor-inset);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
76
|
.Layout {
|
|
76
|
-
@apply pulse
|
|
77
|
+
@apply pulse:grid pulse:grid-flow-col pulse:grid-cols-[auto_0_minmax(0,calc(100%_-_var(--Layout-sidebar-width)_-_var(--Layout-gutter)))] pulse:gap-[var(--Layout-gutter)];
|
|
77
78
|
--Layout-sidebar-width: 220px;
|
|
78
79
|
--Layout-gutter: 16px;
|
|
79
80
|
}
|
|
80
81
|
@media (max-width: calc(544px - 0.02px)) {
|
|
81
82
|
.Layout {
|
|
82
|
-
@
|
|
83
|
+
@apply pulse:layout-flow-row;
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
@media (max-width: calc(768px - 0.02px)) {
|
|
86
87
|
.Layout.Layout--flowRow-until-md {
|
|
87
|
-
@
|
|
88
|
+
@apply pulse:layout-flow-row;
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
@media (max-width: calc(1012px - 0.02px)) {
|
|
91
92
|
.Layout.Layout--flowRow-until-lg {
|
|
92
|
-
@
|
|
93
|
+
@apply pulse:layout-flow-row;
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
@@ -97,13 +98,13 @@
|
|
|
97
98
|
|
|
98
99
|
/* sidebar column, separator, main column */
|
|
99
100
|
.Layout .Layout-sidebar {
|
|
100
|
-
@apply pulse
|
|
101
|
+
@apply pulse:col-[1];
|
|
101
102
|
}
|
|
102
103
|
.Layout .Layout-divider {
|
|
103
|
-
@apply pulse
|
|
104
|
+
@apply pulse:hidden;
|
|
104
105
|
}
|
|
105
106
|
.Layout .Layout-main {
|
|
106
|
-
@apply pulse
|
|
107
|
+
@apply pulse:col-[2_/_span_2];
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
/* Gutter spacing */
|
|
@@ -171,43 +172,43 @@
|
|
|
171
172
|
|
|
172
173
|
/* Sidebar position */
|
|
173
174
|
.Layout.Layout--sidebarPosition-start .Layout-sidebar {
|
|
174
|
-
@apply pulse
|
|
175
|
+
@apply pulse:col-[1];
|
|
175
176
|
}
|
|
176
177
|
.Layout.Layout--sidebarPosition-start .Layout-main {
|
|
177
|
-
@apply pulse
|
|
178
|
+
@apply pulse:col-[2_/_span_2];
|
|
178
179
|
}
|
|
179
180
|
.Layout.Layout--sidebarPosition-end {
|
|
180
|
-
@apply pulse
|
|
181
|
+
@apply pulse:grid-cols-[minmax(0,calc(100%_-_var(--Layout-sidebar-width)_-_var(--Layout-gutter)))_0_auto];
|
|
181
182
|
}
|
|
182
183
|
.Layout.Layout--sidebarPosition-end .Layout-main {
|
|
183
|
-
@apply pulse
|
|
184
|
+
@apply pulse:col-[1];
|
|
184
185
|
}
|
|
185
186
|
.Layout.Layout--sidebarPosition-end .Layout-sidebar {
|
|
186
|
-
@apply pulse
|
|
187
|
+
@apply pulse:col-[2_/_span_2];
|
|
187
188
|
}
|
|
188
189
|
|
|
189
190
|
/* Sidebar divider */
|
|
190
191
|
.Layout.Layout--divided .Layout-divider {
|
|
191
|
-
@apply pulse
|
|
192
|
+
@apply pulse:block pulse:col-[2] pulse:w-px pulse:-mr-px;
|
|
192
193
|
background: var(--borderColor-default);
|
|
193
194
|
}
|
|
194
195
|
.Layout.Layout--divided .Layout-main {
|
|
195
|
-
@apply pulse
|
|
196
|
+
@apply pulse:col-[3_/_span_1];
|
|
196
197
|
}
|
|
197
198
|
.Layout.Layout--divided.Layout--sidebarPosition-end .Layout-sidebar {
|
|
198
|
-
@apply pulse
|
|
199
|
+
@apply pulse:col-[3_/_span_1];
|
|
199
200
|
}
|
|
200
201
|
.Layout.Layout--divided.Layout--sidebarPosition-end .Layout-main {
|
|
201
|
-
@apply pulse
|
|
202
|
+
@apply pulse:col-[1];
|
|
202
203
|
}
|
|
203
204
|
.Layout-divider {
|
|
204
|
-
@apply pulse
|
|
205
|
+
@apply pulse:hidden pulse:w-px;
|
|
205
206
|
}
|
|
206
207
|
.Layout-sidebar {
|
|
207
|
-
@apply pulse
|
|
208
|
+
@apply pulse:w-[var(--Layout-sidebar-width)];
|
|
208
209
|
}
|
|
209
210
|
.Layout-main {
|
|
210
|
-
@apply pulse
|
|
211
|
+
@apply pulse:min-w-0;
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
/* Centered main column
|
|
@@ -215,7 +216,7 @@
|
|
|
215
216
|
.Layout-main .Layout-main-centered-md,
|
|
216
217
|
.Layout-main .Layout-main-centered-lg,
|
|
217
218
|
.Layout-main .Layout-main-centered-xl {
|
|
218
|
-
@apply pulse
|
|
219
|
+
@apply pulse:mx-auto;
|
|
219
220
|
}
|
|
220
221
|
.Layout-main .Layout-main-centered-md > .container-md,
|
|
221
222
|
.Layout-main .Layout-main-centered-md > .container-lg,
|
|
@@ -226,14 +227,14 @@
|
|
|
226
227
|
.Layout-main .Layout-main-centered-xl > .container-md,
|
|
227
228
|
.Layout-main .Layout-main-centered-xl > .container-lg,
|
|
228
229
|
.Layout-main .Layout-main-centered-xl > .container-xl {
|
|
229
|
-
@apply pulse
|
|
230
|
+
@apply pulse:ml-0;
|
|
230
231
|
}
|
|
231
232
|
.Layout-main .Layout-main-centered-md {
|
|
232
|
-
@apply pulse
|
|
233
|
+
@apply pulse:max-w-[calc(var(--breakpoint-medium)_+_var(--Layout-sidebar-width)_+_var(--Layout-gutter))];
|
|
233
234
|
}
|
|
234
235
|
.Layout-main .Layout-main-centered-lg {
|
|
235
|
-
@apply pulse
|
|
236
|
+
@apply pulse:max-w-[calc(var(--breakpoint-large)_+_var(--Layout-sidebar-width)_+_var(--Layout-gutter))];
|
|
236
237
|
}
|
|
237
238
|
.Layout-main .Layout-main-centered-xl {
|
|
238
|
-
@apply pulse
|
|
239
|
+
@apply pulse:max-w-[calc(var(--breakpoint-xlarge)_+_var(--Layout-sidebar-width)_+_var(--Layout-gutter))];
|
|
239
240
|
}
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
module Pulse
|
|
4
4
|
# Renders a two-column page layout
|
|
5
5
|
class Layout < Pulse::Component
|
|
6
|
+
# Main and sidebar placement work. Main `width:` options other than `:full`
|
|
7
|
+
# emit Primer classes that no CSS defines, so the content is not centred.
|
|
8
|
+
status :beta
|
|
9
|
+
|
|
6
10
|
FIRST_IN_SOURCE_DEFAULT = :sidebar
|
|
7
11
|
FIRST_IN_SOURCE_OPTIONS = [FIRST_IN_SOURCE_DEFAULT, :main].freeze
|
|
8
12
|
|
|
@@ -61,10 +65,10 @@ module Pulse
|
|
|
61
65
|
@system_arguments = system_arguments
|
|
62
66
|
@system_arguments[:tag] = :div
|
|
63
67
|
@system_arguments[:classes] = merge_classes(
|
|
64
|
-
'pulse
|
|
65
|
-
'pulse
|
|
68
|
+
'pulse:grid pulse:grid-flow-col',
|
|
69
|
+
'pulse:grid-cols-[auto_0_minmax(0,calc(100%_-_var(--pulse-layout' \
|
|
66
70
|
'-sidebar-width)_-_var(--pulse-layout-gutter)))]',
|
|
67
|
-
'pulse
|
|
71
|
+
'pulse:gap-(--pulse-layout-gutter)',
|
|
68
72
|
GUTTER_MAPPINGS[fetch_or_fallback(GUTTER_OPTIONS, gutter,
|
|
69
73
|
GUTTER_DEFAULT)],
|
|
70
74
|
system_arguments[:classes]
|
|
@@ -77,6 +81,8 @@ module Pulse
|
|
|
77
81
|
|
|
78
82
|
# The layout's main content.
|
|
79
83
|
class Main < Pulse::Component
|
|
84
|
+
status :stable
|
|
85
|
+
|
|
80
86
|
WIDTH_DEFAULT = :full
|
|
81
87
|
WIDTH_OPTIONS = [WIDTH_DEFAULT, :md, :lg, :xl].freeze
|
|
82
88
|
|
|
@@ -92,7 +98,7 @@ module Pulse
|
|
|
92
98
|
@system_arguments[:tag] =
|
|
93
99
|
fetch_or_fallback(TAG_OPTIONS, tag, TAG_DEFAULT)
|
|
94
100
|
@system_arguments[:classes] = merge_classes(
|
|
95
|
-
'pulse
|
|
101
|
+
'pulse:col-[2/span_2]',
|
|
96
102
|
system_arguments[:classes]
|
|
97
103
|
)
|
|
98
104
|
end
|
|
@@ -105,7 +111,7 @@ module Pulse
|
|
|
105
111
|
render(
|
|
106
112
|
Pulse::BaseComponent.new(
|
|
107
113
|
tag: :div,
|
|
108
|
-
classes: "pulse
|
|
114
|
+
classes: "pulse:mx-auto Layout-main-centered-#{@width}"
|
|
109
115
|
)
|
|
110
116
|
) do
|
|
111
117
|
render(Pulse::BaseComponent.new(tag: :div, container: @width)) do
|
|
@@ -119,6 +125,8 @@ module Pulse
|
|
|
119
125
|
|
|
120
126
|
# The layout's sidebar content.
|
|
121
127
|
class Sidebar < Pulse::Component
|
|
128
|
+
status :stable
|
|
129
|
+
|
|
122
130
|
TAG_DEFAULT = :div
|
|
123
131
|
TAG_OPTIONS = [TAG_DEFAULT, :aside, :nav, :section].freeze
|
|
124
132
|
|
|
@@ -128,7 +136,7 @@ module Pulse
|
|
|
128
136
|
@system_arguments[:tag] =
|
|
129
137
|
fetch_or_fallback(TAG_OPTIONS, tag, TAG_DEFAULT)
|
|
130
138
|
@system_arguments[:classes] = merge_classes(
|
|
131
|
-
'pulse
|
|
139
|
+
'pulse:col-1',
|
|
132
140
|
@system_arguments[:classes]
|
|
133
141
|
)
|
|
134
142
|
end
|
|
@@ -5,13 +5,15 @@ module Pulse
|
|
|
5
5
|
# `Link` styles anchor tags with default styling and hover
|
|
6
6
|
# text-decoration.
|
|
7
7
|
class Link < Pulse::Component
|
|
8
|
+
status :stable
|
|
9
|
+
|
|
8
10
|
DEFAULT_SCHEME = :tertiary
|
|
9
11
|
SCHEME_MAPPINGS = {
|
|
10
|
-
primary: 'pulse
|
|
11
|
-
secondary: 'pulse
|
|
12
|
-
tertiary: 'pulse
|
|
13
|
-
reversed: 'pulse
|
|
14
|
-
'focus:
|
|
12
|
+
primary: 'pulse:text-primary pulse:hover:text-primary',
|
|
13
|
+
secondary: 'pulse:text-secondary pulse:hover:text-secondary',
|
|
14
|
+
tertiary: 'pulse:text-tertiary pulse:hover:text-tertiary',
|
|
15
|
+
reversed: 'pulse:text-neutral-300 pulse:hover:text-neutral-300 ' \
|
|
16
|
+
'pulse:focus:text-neutral-300'
|
|
15
17
|
}.freeze
|
|
16
18
|
SCHEME_OPTIONS = SCHEME_MAPPINGS.keys.freeze
|
|
17
19
|
|
|
@@ -31,8 +33,8 @@ module Pulse
|
|
|
31
33
|
SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_MAPPINGS.keys, scheme,
|
|
32
34
|
DEFAULT_SCHEME)],
|
|
33
35
|
@options[:classes],
|
|
34
|
-
'pulse
|
|
35
|
-
'pulse
|
|
36
|
+
'pulse:font-bold': bold,
|
|
37
|
+
'pulse:underline pulse:hover:no-underline': condition && underline
|
|
36
38
|
)
|
|
37
39
|
end
|
|
38
40
|
|
|
@@ -45,7 +47,7 @@ module Pulse
|
|
|
45
47
|
|
|
46
48
|
@options[:classes] = class_names(
|
|
47
49
|
@options[:classes],
|
|
48
|
-
'pulse
|
|
50
|
+
'pulse:flex pulse:items-center pulse:gap-1.5'
|
|
49
51
|
)
|
|
50
52
|
end
|
|
51
53
|
end
|
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
= turbo_frame_tag 'pulse_modal' do
|
|
2
2
|
= render Pulse::BaseComponent.new(**@system_arguments) do
|
|
3
3
|
- unless auto_close
|
|
4
|
-
div class="pulse
|
|
4
|
+
div class="pulse:flex pulse:items-center pulse:justify-center pulse:min-h-screen pulse:p-6 pulse:box-border"
|
|
5
5
|
/! bg overlay
|
|
6
6
|
div{
|
|
7
7
|
data-pulse--modal-target="wrapper" data-action="#{close_on_overlay_click ? 'click->pulse--modal#close' : ''}" aria-hidden="true"
|
|
8
|
-
data-transition-enter="pulse
|
|
9
|
-
data-transition-enter-start="pulse
|
|
10
|
-
data-transition-enter-end="pulse
|
|
11
|
-
data-transition-leave="pulse
|
|
12
|
-
data-transition-leave-start="pulse
|
|
13
|
-
data-transition-leave-end="pulse
|
|
14
|
-
class="pulse
|
|
8
|
+
data-transition-enter="pulse:ease-out pulse:duration-300"
|
|
9
|
+
data-transition-enter-start="pulse:opacity-0"
|
|
10
|
+
data-transition-enter-end="pulse:opacity-100"
|
|
11
|
+
data-transition-leave="pulse:ease-in pulse:duration-200"
|
|
12
|
+
data-transition-leave-start="pulse:opacity-100"
|
|
13
|
+
data-transition-leave-end="pulse:opacity-0"
|
|
14
|
+
class="pulse:fixed pulse:inset-0 pulse:bg-neutral-700/75 pulse:transition-opacity" }
|
|
15
15
|
|
|
16
16
|
/! modal
|
|
17
17
|
div{
|
|
18
18
|
data-pulse--modal-target="body"
|
|
19
|
-
data-transition-enter="pulse
|
|
20
|
-
data-transition-enter-start="pulse
|
|
21
|
-
data-transition-enter-end="pulse
|
|
22
|
-
data-transition-leave="pulse
|
|
23
|
-
data-transition-leave-start="pulse
|
|
24
|
-
data-transition-leave-end="pulse
|
|
25
|
-
class="pulse
|
|
19
|
+
data-transition-enter="pulse:ease-out pulse:duration-300"
|
|
20
|
+
data-transition-enter-start="pulse:opacity-0 pulse:translate-y-4 pulse:sm:translate-y-0 pulse:sm:scale-95"
|
|
21
|
+
data-transition-enter-end="pulse:opacity-100 pulse:translate-y-0 pulse:sm:scale-100"
|
|
22
|
+
data-transition-leave="pulse:ease-in pulse:duration-200"
|
|
23
|
+
data-transition-leave-start="pulse:opacity-100 pulse:translate-y-0 pulse:sm:scale-100"
|
|
24
|
+
data-transition-leave-end="pulse:opacity-0 pulse:translate-y-4 pulse:sm:translate-y-0 pulse:sm:scale-95"
|
|
25
|
+
class="pulse:relative pulse:z-50 pulse:bg-white pulse:shadow-xl pulse:rounded-lg pulse:transition-all #{modal_classes}"
|
|
26
26
|
role="dialog"
|
|
27
27
|
aria-modal="true"}
|
|
28
28
|
|
|
29
29
|
/! header
|
|
30
|
-
div class="pulse
|
|
30
|
+
div class="pulse:flex pulse:items-center pulse:justify-between pulse:gap-4 pulse:p-4 pulse:md:p-5 pulse:border-b"
|
|
31
31
|
- if title?
|
|
32
|
-
= render Pulse::Text.new(type: :h4, el_tag: :h2, classes: 'pulse
|
|
32
|
+
= render Pulse::Text.new(type: :h4, el_tag: :h2, classes: 'pulse:tracking-tight pulse:text-neutral-700 pulse:truncate')
|
|
33
33
|
= title
|
|
34
34
|
|
|
35
35
|
- if close_button
|
|
36
36
|
button{
|
|
37
|
-
class="pulse
|
|
37
|
+
class="pulse:ms-auto pulse:inline-flex pulse:items-center pulse:justify-center pulse:w-10 pulse:h-7 pulse:bg-transparent pulse:border-none pulse:text-neutral-700"
|
|
38
38
|
data-action="pulse--modal#close"
|
|
39
39
|
aria-label="Close Modal"}
|
|
40
40
|
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
/! body
|
|
45
|
-
div class="pulse
|
|
45
|
+
div class="pulse:p-4 pulse:md:p-5 #{'pulse:mb-4' unless footer}"
|
|
46
46
|
= content
|
|
47
47
|
|
|
48
48
|
/! footer
|
|
49
49
|
- if footer
|
|
50
|
-
div class="pulse
|
|
50
|
+
div class="pulse:flex pulse:items-center pulse:p-4 pulse:md:p-5 pulse:border-t pulse:border-neutral-300"
|
|
51
51
|
= footer
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module Pulse
|
|
4
4
|
# Renders a modal component targetable by turbo frame
|
|
5
5
|
class Modal < Pulse::Component
|
|
6
|
+
status :stable
|
|
7
|
+
|
|
6
8
|
include Turbo::FramesHelper
|
|
7
9
|
|
|
8
10
|
renders_one :title
|
|
@@ -10,11 +12,11 @@ module Pulse
|
|
|
10
12
|
|
|
11
13
|
DEFAULT_SIZE = :md
|
|
12
14
|
SIZE_MAPPINGS = {
|
|
13
|
-
sm: 'pulse
|
|
14
|
-
md: 'pulse
|
|
15
|
-
lg: 'pulse
|
|
16
|
-
xl: 'pulse
|
|
17
|
-
xxl: 'pulse
|
|
15
|
+
sm: 'pulse:max-w-md',
|
|
16
|
+
md: 'pulse:max-w-2xl',
|
|
17
|
+
lg: 'pulse:max-w-4xl',
|
|
18
|
+
xl: 'pulse:max-w-5xl',
|
|
19
|
+
xxl: 'pulse:max-w-6xl'
|
|
18
20
|
}.freeze
|
|
19
21
|
SIZE_OPTIONS = SIZE_MAPPINGS.keys.freeze
|
|
20
22
|
|
|
@@ -24,7 +26,7 @@ module Pulse
|
|
|
24
26
|
@size = fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)
|
|
25
27
|
@system_arguments = system_arguments
|
|
26
28
|
@modal_classes = merge_classes(
|
|
27
|
-
'pulse
|
|
29
|
+
'pulse:w-full',
|
|
28
30
|
SIZE_MAPPINGS[@size],
|
|
29
31
|
@system_arguments.delete(:classes)
|
|
30
32
|
)
|
|
@@ -36,8 +38,8 @@ module Pulse
|
|
|
36
38
|
|
|
37
39
|
@system_arguments[:'aria-labelledby'] = 'modal-title'
|
|
38
40
|
@system_arguments[:'aria-modal'] = true
|
|
39
|
-
@system_arguments[:classes] = 'pulse
|
|
40
|
-
'pulse
|
|
41
|
+
@system_arguments[:classes] = 'pulse:fixed pulse:z-9999 pulse:inset-0 ' \
|
|
42
|
+
'pulse:overflow-y-auto'
|
|
41
43
|
@system_arguments[:data] = data_attributes
|
|
42
44
|
@system_arguments[:role] = 'dialog'
|
|
43
45
|
@system_arguments[:tabindex] = 0
|
|
@@ -43,7 +43,7 @@ export default class extends Controller {
|
|
|
43
43
|
this.lastFocusedElement = document.activeElement
|
|
44
44
|
enter(this.wrapperTarget)
|
|
45
45
|
enter(this.bodyTarget)
|
|
46
|
-
document.body.classList.add("pulse
|
|
46
|
+
document.body.classList.add("pulse:overflow-hidden")
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
close(e) {
|
|
@@ -54,7 +54,7 @@ export default class extends Controller {
|
|
|
54
54
|
this.element.remove()
|
|
55
55
|
})
|
|
56
56
|
|
|
57
|
-
document.body.classList.remove("pulse
|
|
57
|
+
document.body.classList.remove("pulse:overflow-hidden")
|
|
58
58
|
|
|
59
59
|
// Return focus to the last focused element
|
|
60
60
|
if (this.lastFocusedElement) this.lastFocusedElement.focus()
|
|
@@ -66,7 +66,7 @@ export default class extends Controller {
|
|
|
66
66
|
|
|
67
67
|
autoClose(e) {
|
|
68
68
|
this.element.remove()
|
|
69
|
-
document.body.classList.remove("pulse
|
|
69
|
+
document.body.classList.remove("pulse:overflow-hidden")
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
handleSubmit = e => {
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
= render Pulse::BaseComponent.new(**@system_arguments) do
|
|
3
3
|
- if @variant == :desktop
|
|
4
4
|
= active_link_to @path, active: @active_mode,
|
|
5
|
-
class_active: 'pulse
|
|
6
|
-
class_inactive: 'pulse
|
|
5
|
+
class_active: 'pulse:text-white pulse:hover:text-white pulse:hover:no-underline pulse:px-3 pulse:py-2 pulse:font-medium pulse:relative pulse:group pulse-is-active',
|
|
6
|
+
class_inactive: 'pulse:text-white pulse:hover:text-white pulse:hover:no-underline pulse:px-3 pulse:py-2 pulse:font-medium pulse:relative pulse:group' do
|
|
7
7
|
= @label
|
|
8
|
-
span class="pulse
|
|
9
|
-
span class="pulse
|
|
10
|
-
span class="pulse
|
|
8
|
+
span class="pulse:absolute pulse:-bottom-0.5 pulse:left-1/2 pulse:w-0 pulse:h-0.5 pulse:bg-neutral-300 pulse:group-hover:w-1/2 pulse:group-hover:transition-all pulse:duration-200"
|
|
9
|
+
span class="pulse:absolute pulse:-bottom-0.5 pulse:right-1/2 pulse:w-0 pulse:h-0.5 pulse:bg-neutral-300 pulse:group-hover:w-1/2 pulse:group-hover:transition-all pulse:duration-200"
|
|
10
|
+
span class="pulse:absolute pulse:-bottom-0.5 pulse:inset-s-0 pulse:w-full pulse:h-0.5 pulse:bg-primary pulse:hidden pulse:group-[.pulse-is-active]:block"
|
|
11
11
|
- else
|
|
12
12
|
= active_link_to @path, active: @active_mode,
|
|
13
|
-
class_active: 'pulse
|
|
14
|
-
class_inactive: 'pulse
|
|
13
|
+
class_active: 'pulse:text-primary-800 pulse:hover:no-underline pulse:block pulse:px-3 pulse:py-2',
|
|
14
|
+
class_inactive: 'pulse:text-neutral-700 pulse:hover:no-underline pulse:block pulse:px-3 pulse:py-2',
|
|
15
15
|
data: { action: 'dropdown#toggle' } do
|
|
16
16
|
= @label
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
module Pulse
|
|
4
4
|
# Links in navbars
|
|
5
5
|
class NavLink < Pulse::Component
|
|
6
|
+
status :stable
|
|
7
|
+
|
|
6
8
|
DEFAULT_VARIANT = :desktop
|
|
7
9
|
VARIANT_MAPPINGS = {
|
|
8
|
-
desktop: 'pulse
|
|
9
|
-
mobile: 'pulse
|
|
10
|
+
desktop: 'pulse:px-3 pulse:py-2',
|
|
11
|
+
mobile: 'pulse:px-3 pulse:py-2'
|
|
10
12
|
}.freeze
|
|
11
13
|
VARIANT_OPTIONS = VARIANT_MAPPINGS.keys.freeze
|
|
12
14
|
|
|
@@ -6,6 +6,8 @@ module Pulse
|
|
|
6
6
|
#
|
|
7
7
|
# See <%= link_to_component(NavList) %> for usage examples.
|
|
8
8
|
class Heading < Pulse::Component
|
|
9
|
+
status :alpha
|
|
10
|
+
|
|
9
11
|
attr_reader :title, :id, :heading_level, :system_arguments
|
|
10
12
|
|
|
11
13
|
# @param title [String] The text content of the heading.
|
|
@@ -26,7 +28,7 @@ module Pulse
|
|
|
26
28
|
type: :body4,
|
|
27
29
|
tag: :"h#{heading_level}",
|
|
28
30
|
id:,
|
|
29
|
-
classes: 'pulse
|
|
31
|
+
classes: 'pulse:ml-2 pulse:mb-4',
|
|
30
32
|
**system_arguments
|
|
31
33
|
).with_content(title)
|
|
32
34
|
)
|
|
@@ -81,7 +81,7 @@ module Pulse
|
|
|
81
81
|
else
|
|
82
82
|
@system_arguments[:classes] = merge_classes(
|
|
83
83
|
@system_arguments[:classes],
|
|
84
|
-
'pulse
|
|
84
|
+
'pulse:outline-hidden pulse:bg-neutral-50' => active?
|
|
85
85
|
)
|
|
86
86
|
end
|
|
87
87
|
|
|
@@ -118,7 +118,7 @@ module Pulse
|
|
|
118
118
|
"
|
|
119
119
|
|
|
120
120
|
with_private_trailing_action_icon(
|
|
121
|
-
:'chevron-down',
|
|
121
|
+
icon: :'chevron-down',
|
|
122
122
|
classes: 'ActionListItem-collapseIcon'
|
|
123
123
|
)
|
|
124
124
|
|
|
@@ -14,6 +14,11 @@ module Pulse
|
|
|
14
14
|
# or more ID values that determine which item will appear selected. Use the
|
|
15
15
|
# `selected_item_id` argument to select the appropriate item.
|
|
16
16
|
class NavList < Pulse::Component
|
|
17
|
+
# Incomplete: built on `ActionList`. Avatar items raise, sub-items render
|
|
18
|
+
# expanded and cannot be toggled, and the show-more item has no JavaScript.
|
|
19
|
+
# Top-level items, headings, groups and selection work.
|
|
20
|
+
status :alpha
|
|
21
|
+
|
|
17
22
|
# @private
|
|
18
23
|
def self.custom_element_name
|
|
19
24
|
'nav-list'
|