stimulus_plumbers_tailwind 0.4.15 → 0.4.16
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 33ab72484958134862e7462abb7dccd71ee6cc386addfdc741085979514ac5c5
|
|
4
|
+
data.tar.gz: f3557154e6f5077fe2bebe5aacc3e1c06b23cba932cad8ce99a1d105196308d4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af816ad054bb6ec34a4632bd6e24cace88339614747bb005578325946998490c472d010d267ae182b6d2c56f2168e0ed29c085410a9efa6abd1ae7d3d2171e7a
|
|
7
|
+
data.tar.gz: 4643a0fbe7b94fabbbdaf7c062be07ba90cc48b6c95b3e30db7e67ffb39b9a9595cf546c2a72c2faccfbe2782bf9ee0ebdc2b2f3b7b6562242cf1483a06c227c
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
---
|
|
6
|
+
## [0.4.15](https://github.com/ryancyq/stimulus-plumbers/compare/stimulus-plumbers-tailwind/v0.4.14..stimulus-plumbers-tailwind/v0.4.15) - 2026-07-23
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- password strength ([#191](https://github.com/ryancyq/stimulus-plumbers/issues/191)) - ([2f7ad55](https://github.com/ryancyq/stimulus-plumbers/commit/2f7ad550ab882225fd886956c586c0011af021fc)) - Ryan Chang
|
|
11
|
+
- segmented progress bar ([#192](https://github.com/ryancyq/stimulus-plumbers/issues/192)) - ([9c43461](https://github.com/ryancyq/stimulus-plumbers/commit/9c43461a262dc19a7546aadadefaf2e4e75a4acb)) - Ryan Chang
|
|
12
|
+
|
|
5
13
|
---
|
|
6
14
|
## [0.4.14](https://github.com/ryancyq/stimulus-plumbers/compare/stimulus-plumbers-tailwind/v0.4.13..stimulus-plumbers-tailwind/v0.4.14) - 2026-07-20
|
|
7
15
|
|
data/docs/guide.md
CHANGED
|
@@ -12,7 +12,7 @@ bin/rails generate stimulus_plumbers:tailwind:install
|
|
|
12
12
|
|
|
13
13
|
It re-runs automatically on `assets:precompile`/`tailwindcss:build` after that. File detection and
|
|
14
14
|
the `STIMULUS_PLUMBERS_CSS_ENTRY` override are shared with the core gem — see
|
|
15
|
-
[
|
|
15
|
+
`guide://component` ([CSS entry file detection](https://github.com/ryancyq/stimulus-plumbers/blob/main/stimulus-plumbers-rails/docs/guide.md#css-entry-file-detection)).
|
|
16
16
|
|
|
17
17
|
## Installed CSS files
|
|
18
18
|
|
|
@@ -27,8 +27,9 @@ an existing one. Legacy imports that point into gem directories are migrated to
|
|
|
27
27
|
paths.
|
|
28
28
|
|
|
29
29
|
Icons: pass a kebab-case name to `sp_icon` or any `icon_leading:`/`icon_trailing:` option (append
|
|
30
|
-
`/solid` for the filled variant) —
|
|
31
|
-
|
|
30
|
+
`/solid` for the filled variant) — names and aliases are in `component://icons` (`list_icons`), and
|
|
31
|
+
the [README](https://github.com/ryancyq/stimulus-plumbers/blob/main/stimulus-plumbers-tailwind/README.md#icons)
|
|
32
|
+
covers the optional `heroicons` gem.
|
|
32
33
|
|
|
33
|
-
To implement a custom theme instead of/alongside Tailwind, see
|
|
34
|
-
[stimulus-plumbers
|
|
34
|
+
To implement a custom theme instead of/alongside Tailwind, see `guide://theme`
|
|
35
|
+
([theme.md](https://github.com/ryancyq/stimulus-plumbers/blob/main/stimulus-plumbers-rails/docs/component/theme.md)).
|
|
@@ -78,6 +78,59 @@ module StimulusPlumbers
|
|
|
78
78
|
[&>div:first-child]:focus-within:ring-0
|
|
79
79
|
].freeze
|
|
80
80
|
|
|
81
|
+
# ── Range ─────────────────────────────────────────────────────────────
|
|
82
|
+
# A slider is a track and a thumb, so it takes none of INPUT's box chrome.
|
|
83
|
+
# WebKit has no filled-track pseudo-element: the fill is a gradient stopped at
|
|
84
|
+
# --sp-progress-percent (set by the progress controller). Firefox has
|
|
85
|
+
# ::-moz-range-progress and uses that instead.
|
|
86
|
+
# Must stay on one line: Tailwind scans source text, so a class split across a string
|
|
87
|
+
# continuation never appears contiguously and is silently dropped from the build.
|
|
88
|
+
# rubocop:disable Layout/LineLength
|
|
89
|
+
RANGE_FILL = "[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--sp-color-primary)_0_calc(var(--sp-progress-percent,0)*1%),transparent_0)]"
|
|
90
|
+
# rubocop:enable Layout/LineLength
|
|
91
|
+
|
|
92
|
+
RANGE = [
|
|
93
|
+
"w-full appearance-none bg-transparent cursor-pointer",
|
|
94
|
+
"focus:outline-none",
|
|
95
|
+
"focus-visible:outline-none",
|
|
96
|
+
"focus-visible:ring-(length:--sp-focus-ring-width)",
|
|
97
|
+
"focus-visible:ring-(--sp-focus-ring-color)",
|
|
98
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
99
|
+
# WebKit track + thumb
|
|
100
|
+
"[&::-webkit-slider-runnable-track]:h-2",
|
|
101
|
+
"[&::-webkit-slider-runnable-track]:rounded-full",
|
|
102
|
+
"[&::-webkit-slider-runnable-track]:bg-(--sp-color-muted)",
|
|
103
|
+
RANGE_FILL,
|
|
104
|
+
"[&::-webkit-slider-thumb]:appearance-none",
|
|
105
|
+
"[&::-webkit-slider-thumb]:size-4",
|
|
106
|
+
"[&::-webkit-slider-thumb]:rounded-full",
|
|
107
|
+
"[&::-webkit-slider-thumb]:bg-(--sp-color-primary)",
|
|
108
|
+
# Centers a 16px thumb on an 8px track.
|
|
109
|
+
"[&::-webkit-slider-thumb]:-mt-1",
|
|
110
|
+
# Firefox track + native fill + thumb
|
|
111
|
+
"[&::-moz-range-track]:h-2",
|
|
112
|
+
"[&::-moz-range-track]:rounded-full",
|
|
113
|
+
"[&::-moz-range-track]:bg-(--sp-color-muted)",
|
|
114
|
+
"[&::-moz-range-progress]:h-2",
|
|
115
|
+
"[&::-moz-range-progress]:rounded-full",
|
|
116
|
+
"[&::-moz-range-progress]:bg-(--sp-color-primary)",
|
|
117
|
+
"[&::-moz-range-thumb]:size-4",
|
|
118
|
+
"[&::-moz-range-thumb]:border-0",
|
|
119
|
+
"[&::-moz-range-thumb]:rounded-full",
|
|
120
|
+
"[&::-moz-range-thumb]:bg-(--sp-color-primary)"
|
|
121
|
+
].freeze
|
|
122
|
+
|
|
123
|
+
# The readout sits outside the input, so the input's own disabled:opacity-50 never
|
|
124
|
+
# reaches it — without this a disabled slider keeps a full-strength readout.
|
|
125
|
+
RANGE_GROUP = %w[
|
|
126
|
+
flex items-center gap-(--sp-space-3)
|
|
127
|
+
[&:has(input:disabled)>span]:opacity-50
|
|
128
|
+
].freeze
|
|
129
|
+
|
|
130
|
+
# Sits beside the track, not over it — no pill background needed.
|
|
131
|
+
# Shares Progress::VALUE_TEXT, resolved at call time since progress.rb loads later.
|
|
132
|
+
RANGE_VALUE = %w[shrink-0 text-(--sp-color-fg)].freeze
|
|
133
|
+
|
|
81
134
|
# ── Choice inputs ─────────────────────────────────────────────────────
|
|
82
135
|
CHECKBOX_TYPES = {
|
|
83
136
|
default: [
|
|
@@ -154,6 +207,24 @@ module StimulusPlumbers
|
|
|
154
207
|
form_field_input_classes(floating: floating, error: error)
|
|
155
208
|
end
|
|
156
209
|
|
|
210
|
+
# Not form_field_input_classes — a progressbar is display-only, so it takes none of the
|
|
211
|
+
# text-input chrome (border, padding, focus ring); the track styling comes from progress_bar.
|
|
212
|
+
def form_field_input_progress_classes
|
|
213
|
+
{ classes: klasses("w-full") }
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def form_field_input_range_classes
|
|
217
|
+
{ classes: klasses(*RANGE) }
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def form_field_input_range_group_classes
|
|
221
|
+
{ classes: klasses(*RANGE_GROUP) }
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def form_field_input_range_value_classes
|
|
225
|
+
{ classes: klasses(*Progress::VALUE_TEXT, *RANGE_VALUE) }
|
|
226
|
+
end
|
|
227
|
+
|
|
157
228
|
def form_field_input_select_classes(floating: nil, error: false)
|
|
158
229
|
form_field_input_classes(floating: floating, error: error)
|
|
159
230
|
end
|
|
@@ -5,28 +5,65 @@ module StimulusPlumbers
|
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Progress
|
|
7
7
|
BAR = %w[
|
|
8
|
-
relative w-full
|
|
8
|
+
relative w-full overflow-hidden rounded-full
|
|
9
9
|
bg-(--sp-color-muted)
|
|
10
10
|
].freeze
|
|
11
11
|
|
|
12
|
+
BAR_HEIGHTS = { false => "h-2", true => "h-5" }.freeze
|
|
13
|
+
|
|
14
|
+
# tabular-nums so the readout doesn't jitter as digits change under a drag.
|
|
15
|
+
VALUE_TEXT = %w[text-xs font-medium leading-none tabular-nums].freeze
|
|
16
|
+
|
|
17
|
+
# Row wrapper for an outside readout — the track shrinks to leave room for the text.
|
|
18
|
+
BAR_GROUP = %w[flex w-full items-center gap-(--sp-space-2)].freeze
|
|
19
|
+
|
|
20
|
+
# Clipped to the glyphs, this paints primary-fg up to the fill edge and fg past it, so the
|
|
21
|
+
# digits split rather than sit on a pill — neither color alone clears AA over both. The
|
|
22
|
+
# edge is --sp-progress-percent (set by the progress controller), 0 until it connects.
|
|
23
|
+
# Must stay on one line: Tailwind scans source text, so a class split across a string
|
|
24
|
+
# continuation or interpolation never appears contiguously and is silently dropped.
|
|
25
|
+
# rubocop:disable Layout/LineLength
|
|
26
|
+
BAR_VALUE_SPLIT = "bg-[linear-gradient(to_right,var(--sp-color-primary-fg)_0_calc(var(--sp-progress-percent,0)*1%),var(--sp-color-fg)_0)]"
|
|
27
|
+
# rubocop:enable Layout/LineLength
|
|
28
|
+
|
|
29
|
+
# Spans the track so the gradient's coordinates are the track's.
|
|
30
|
+
BAR_VALUE = [
|
|
31
|
+
*VALUE_TEXT,
|
|
32
|
+
"absolute inset-x-0 top-1/2 -translate-y-1/2 text-center pointer-events-none",
|
|
33
|
+
BAR_VALUE_SPLIT,
|
|
34
|
+
"bg-clip-text [-webkit-background-clip:text] text-transparent"
|
|
35
|
+
].freeze
|
|
36
|
+
|
|
37
|
+
# Beside the track it never sits over the fill, so it needs no pill.
|
|
38
|
+
BAR_VALUE_OUTSIDE = [*VALUE_TEXT, "shrink-0 text-(--sp-color-primary)"].freeze
|
|
39
|
+
|
|
12
40
|
# `data-intent` (set per-segment by a ramp) overrides the default primary fill color.
|
|
13
|
-
|
|
41
|
+
FILL_BASE = %w[
|
|
14
42
|
h-full rounded-full bg-(--sp-color-primary)
|
|
15
43
|
[&[data-intent=danger]]:bg-(--sp-color-destructive)
|
|
16
44
|
[&[data-intent=warning]]:bg-(--sp-color-warning)
|
|
17
45
|
[&[data-intent=success]]:bg-(--sp-color-success)
|
|
46
|
+
].freeze
|
|
47
|
+
|
|
48
|
+
# animations.css renames a slot fill's keyframes but reads iteration-count off this.
|
|
49
|
+
FILL_INDETERMINATE = %w[
|
|
18
50
|
[.sp-progress-indeterminate_&]:animate-progress-slide
|
|
19
51
|
[.sp-progress-indeterminate_&]:motion-reduce:animate-none
|
|
20
52
|
].freeze
|
|
21
53
|
|
|
22
|
-
|
|
23
|
-
|
|
54
|
+
BAR_FILL = [*FILL_BASE, *FILL_INDETERMINATE].freeze
|
|
55
|
+
|
|
56
|
+
# Row of equal-width slots; each slot is its own track with a SEGMENT_FILL inside.
|
|
57
|
+
SEGMENT_GROUP = %w[flex w-full gap-(--sp-space-1)].freeze
|
|
24
58
|
|
|
25
59
|
SEGMENT = %w[
|
|
26
60
|
flex-1 h-2 overflow-hidden rounded-full
|
|
27
61
|
bg-(--sp-color-muted)
|
|
28
62
|
].freeze
|
|
29
63
|
|
|
64
|
+
# Separate key so a theme can restyle a slot's chunk without touching the bar's.
|
|
65
|
+
SEGMENT_FILL = [*FILL_BASE, *FILL_INDETERMINATE].freeze
|
|
66
|
+
|
|
30
67
|
# Circle stroke/fill live in icons/customs/progress-ring.svg — @source never scans
|
|
31
68
|
# .svg files, so Tailwind classes there are inert.
|
|
32
69
|
# Indeterminate class and utility land on this same svg, so this needs the compound
|
|
@@ -49,22 +86,38 @@ module StimulusPlumbers
|
|
|
49
86
|
|
|
50
87
|
private
|
|
51
88
|
|
|
52
|
-
def progress_bar_classes
|
|
53
|
-
{ classes: klasses(*BAR) }
|
|
89
|
+
def progress_bar_classes(labelled: false)
|
|
90
|
+
{ classes: klasses(*BAR, BAR_HEIGHTS.fetch(labelled)) }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def progress_bar_group_classes
|
|
94
|
+
{ classes: klasses(*BAR_GROUP) }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def progress_bar_value_classes
|
|
98
|
+
{ classes: klasses(*BAR_VALUE) }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def progress_bar_value_outside_classes
|
|
102
|
+
{ classes: klasses(*BAR_VALUE_OUTSIDE) }
|
|
54
103
|
end
|
|
55
104
|
|
|
56
105
|
def progress_bar_fill_classes
|
|
57
106
|
{ classes: klasses(*BAR_FILL) }
|
|
58
107
|
end
|
|
59
108
|
|
|
60
|
-
def
|
|
61
|
-
{ classes: klasses(*
|
|
109
|
+
def progress_segment_group_classes
|
|
110
|
+
{ classes: klasses(*SEGMENT_GROUP) }
|
|
62
111
|
end
|
|
63
112
|
|
|
64
113
|
def progress_segment_classes
|
|
65
114
|
{ classes: klasses(*SEGMENT) }
|
|
66
115
|
end
|
|
67
116
|
|
|
117
|
+
def progress_segment_fill_classes
|
|
118
|
+
{ classes: klasses(*SEGMENT_FILL) }
|
|
119
|
+
end
|
|
120
|
+
|
|
68
121
|
def progress_ring_classes(size: nil)
|
|
69
122
|
{ classes: klasses(*RING, *Array(RING_SIZES[size])) }
|
|
70
123
|
end
|