stimulus_plumbers_tailwind 0.4.9 → 0.4.10
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 +21 -0
- data/README.md +2 -2
- data/docs/guide.md +13 -3
- data/lib/generators/stimulus_plumbers/tailwind/install/install_generator.rb +20 -2
- data/lib/stimulus_plumbers/tailwind/generators/animations_directive.rb +5 -5
- data/lib/stimulus_plumbers/tailwind/version.rb +1 -1
- data/lib/stimulus_plumbers/themes/tailwind/card.rb +10 -10
- data/lib/stimulus_plumbers/themes/tailwind/checklist.rb +12 -12
- data/lib/stimulus_plumbers/themes/tailwind/combobox.rb +2 -2
- data/lib/stimulus_plumbers/themes/tailwind/form/code.rb +37 -0
- data/lib/stimulus_plumbers/themes/tailwind/form/credit_card.rb +39 -0
- data/lib/stimulus_plumbers/themes/tailwind/form/field.rb +2 -2
- data/lib/stimulus_plumbers/themes/tailwind/form/input.rb +10 -10
- data/lib/stimulus_plumbers/themes/tailwind/form.rb +2 -2
- data/lib/stimulus_plumbers/themes/tailwind/list.rb +12 -12
- data/lib/stimulus_plumbers/themes/tailwind/ordered_list.rb +10 -10
- data/lib/stimulus_plumbers/themes/tailwind_theme.rb +4 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79b18f9be6a2f72a2b552a8f69cca0f96bc1d0d4092ed858c33f76e09c3b1e26
|
|
4
|
+
data.tar.gz: ec35944909722c5a7bbf3840573db3a51549e8afa1720f5f069951d94b146771
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a35c48c1e604efc1f04581c6975f66199664c92f07e51050c492bcd4683dacd89fe16ff516ae84dca4bde164d34441923c5e42b4597f3f27fd64a4b056b07161
|
|
7
|
+
data.tar.gz: 0b65ffab71d672cdd08f6ed69794fe932840838a55c4f76acdf197ae3a6822a2938bbc7b58d558033bf562da6d4f76669e5a81ffddff3bc125945187929bcbca
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
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.9](https://github.com/ryancyq/stimulus-plumbers/compare/stimulus-plumbers-tailwind/v0.4.8..stimulus-plumbers-tailwind/v0.4.9) - 2026-07-18
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- css source + token in generator ([#163](https://github.com/ryancyq/stimulus-plumbers/issues/163)) - ([69165f5](https://github.com/ryancyq/stimulus-plumbers/commit/69165f523242e27cae5075f635c7e66c40a862ab)) - Ryan Chang
|
|
11
|
+
|
|
12
|
+
### Documentation
|
|
13
|
+
|
|
14
|
+
- update missing documentation ([#164](https://github.com/ryancyq/stimulus-plumbers/issues/164)) - ([edcd79d](https://github.com/ryancyq/stimulus-plumbers/commit/edcd79df3dd1739521641274863a50a32b5fcb36)) - Ryan Chang
|
|
15
|
+
- align code example/instructions in doc and remove stale reference ([#167](https://github.com/ryancyq/stimulus-plumbers/issues/167)) - ([b1ace4d](https://github.com/ryancyq/stimulus-plumbers/commit/b1ace4da5117b70f4f22403f727655c1586606e1)) - Ryan Chang
|
|
16
|
+
- update component documentation ([#173](https://github.com/ryancyq/stimulus-plumbers/issues/173)) - ([27240bc](https://github.com/ryancyq/stimulus-plumbers/commit/27240bc85265b249adba5186fd34b9c26423daa3)) - Ryan Chang
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
- ordered list ([#166](https://github.com/ryancyq/stimulus-plumbers/issues/166)) - ([cda05b5](https://github.com/ryancyq/stimulus-plumbers/commit/cda05b589e2f99ba992785fdb672b0ecef026046)) - Ryan Chang
|
|
21
|
+
- progress ring/bar/meter ([#170](https://github.com/ryancyq/stimulus-plumbers/issues/170)) - ([b43087c](https://github.com/ryancyq/stimulus-plumbers/commit/b43087cec2b40fd8b3dced65215afdbbdfc2c435)) - Ryan Chang
|
|
22
|
+
- status indicator ([#171](https://github.com/ryancyq/stimulus-plumbers/issues/171)) - ([ad3f330](https://github.com/ryancyq/stimulus-plumbers/commit/ad3f330bc8d999b4977f8aeaafc8c4763229a448)) - Ryan Chang
|
|
23
|
+
- horizontal grouped timeline ([#172](https://github.com/ryancyq/stimulus-plumbers/issues/172)) - ([fe9b9ab](https://github.com/ryancyq/stimulus-plumbers/commit/fe9b9abfb8c3c211fe9a7282d2940326678328dc)) - Ryan Chang
|
|
24
|
+
- checklist ([#174](https://github.com/ryancyq/stimulus-plumbers/issues/174)) - ([35dca2a](https://github.com/ryancyq/stimulus-plumbers/commit/35dca2af29955f6f2c85fffc4efc39711ed5bb99)) - Ryan Chang
|
|
25
|
+
|
|
5
26
|
---
|
|
6
27
|
## [0.4.8](https://github.com/ryancyq/stimulus-plumbers/compare/stimulus-plumbers-tailwind/v0.4.5..stimulus-plumbers-tailwind/v0.4.8) - 2026-07-03
|
|
7
28
|
|
data/README.md
CHANGED
|
@@ -33,13 +33,13 @@ StimulusPlumbers.configure do |config|
|
|
|
33
33
|
end
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
Run the install generator once to
|
|
36
|
+
Run the install generator once to copy `stimulus_plumbers/tokens.css` and `stimulus_plumbers/tailwind/animations.css` into your app, then inject their relative imports and the required `@source` directive into your Tailwind CSS entry file — see [docs/guide.md](docs/guide.md) for file-detection/override details:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
bin/rails generate stimulus_plumbers:tailwind:install
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
After that, the `@source` path is kept current automatically — no manual re-run needed after `bundle update`. The engine hooks `stimulus_plumbers:tailwind:install` as a prerequisite of:
|
|
42
|
+
After that, the `@source` path is kept current automatically — no manual re-run needed after `bundle update`. The copied CSS remains application-owned and is never overwritten; update it intentionally when adopting new defaults. The engine hooks `stimulus_plumbers:tailwind:install` as a prerequisite of:
|
|
43
43
|
|
|
44
44
|
- `assets:precompile` (Sprockets and Propshaft both define this task)
|
|
45
45
|
- `tailwindcss:build` (when `tailwindcss-rails` is present)
|
data/docs/guide.md
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
Adding this gem registers and activates the Tailwind theme automatically in Rails — no config
|
|
4
4
|
needed. Outside Rails, activate it explicitly with `config.theme.use(:tailwind)`.
|
|
5
5
|
|
|
6
|
-
Run the install generator once to wire the required `@source` directive
|
|
7
|
-
|
|
8
|
-
CSS entry file:
|
|
6
|
+
Run the install generator once to wire the required CSS imports and `@source` directive into your
|
|
7
|
+
Tailwind CSS entry file:
|
|
9
8
|
|
|
10
9
|
```bash
|
|
11
10
|
bin/rails generate stimulus_plumbers:tailwind:install
|
|
@@ -15,6 +14,17 @@ It re-runs automatically on `assets:precompile`/`tailwindcss:build` after that.
|
|
|
15
14
|
the `STIMULUS_PLUMBERS_CSS_ENTRY` override are shared with the core gem — see
|
|
16
15
|
[stimulus-plumbers-rails/docs/guide.md#css-entry-file-detection](../../stimulus-plumbers-rails/docs/guide.md#css-entry-file-detection).
|
|
17
16
|
|
|
17
|
+
## Installed CSS files
|
|
18
|
+
|
|
19
|
+
The Tailwind installer copies these files into the application and imports them relatively:
|
|
20
|
+
|
|
21
|
+
- `app/assets/stylesheets/stimulus_plumbers/tokens.css`
|
|
22
|
+
- `app/assets/stylesheets/stimulus_plumbers/tailwind/animations.css` — registers the indeterminate progress bar slide keyframe.
|
|
23
|
+
|
|
24
|
+
Both files are application-owned: later generator runs restore a missing copy but never overwrite
|
|
25
|
+
an existing one. Legacy imports that point into gem directories are migrated to these app-local
|
|
26
|
+
paths.
|
|
27
|
+
|
|
18
28
|
Icons: pass a kebab-case name to `sp_icon` or any `icon_leading:`/`icon_trailing:` option (append
|
|
19
29
|
`/solid` for the filled variant) — see [README.md](../README.md#icons) for aliases and the
|
|
20
30
|
optional `heroicons` gem.
|
|
@@ -12,9 +12,19 @@ module StimulusPlumbers
|
|
|
12
12
|
class InstallGenerator < Rails::Generators::Base
|
|
13
13
|
include StimulusPlumbers::Generators::CssEntrypoint
|
|
14
14
|
|
|
15
|
+
TOKENS_CSS_SOURCE = File.join(
|
|
16
|
+
Gem.loaded_specs.fetch("stimulus_plumbers").gem_dir,
|
|
17
|
+
StimulusPlumbers::Generators::TokensDirective::TOKENS_CSS_PATH
|
|
18
|
+
)
|
|
19
|
+
ANIMATIONS_CSS_SOURCE = File.join(
|
|
20
|
+
File.expand_path("../../../../../", __dir__),
|
|
21
|
+
AnimationsDirective::ANIMATIONS_CSS_PATH
|
|
22
|
+
)
|
|
23
|
+
|
|
15
24
|
def install
|
|
16
25
|
css_file = entry_css_file(**css_file_lookup_options)
|
|
17
26
|
return warn_entry_css_not_found(label: "Tailwind CSS", **css_file_lookup_options) unless css_file
|
|
27
|
+
return unless copy_assets
|
|
18
28
|
|
|
19
29
|
apply_tokens_directive(css_file)
|
|
20
30
|
apply_animations_directive(css_file)
|
|
@@ -33,7 +43,10 @@ module StimulusPlumbers
|
|
|
33
43
|
def apply_tokens_directive(css_file)
|
|
34
44
|
apply_edit(
|
|
35
45
|
css_file,
|
|
36
|
-
StimulusPlumbers::Generators::TokensDirective.directive(
|
|
46
|
+
StimulusPlumbers::Generators::TokensDirective.directive(
|
|
47
|
+
from: File.dirname(css_file),
|
|
48
|
+
destination_root: destination_root
|
|
49
|
+
),
|
|
37
50
|
stale_pattern: StimulusPlumbers::Generators::TokensDirective.stale_pattern
|
|
38
51
|
)
|
|
39
52
|
end
|
|
@@ -41,12 +54,17 @@ module StimulusPlumbers
|
|
|
41
54
|
def apply_animations_directive(css_file)
|
|
42
55
|
apply_edit(
|
|
43
56
|
css_file,
|
|
44
|
-
AnimationsDirective.directive(from: File.dirname(css_file)),
|
|
57
|
+
AnimationsDirective.directive(from: File.dirname(css_file), destination_root: destination_root),
|
|
45
58
|
anchor_pattern: AnimationsDirective.anchor_pattern,
|
|
46
59
|
stale_pattern: AnimationsDirective.stale_pattern
|
|
47
60
|
)
|
|
48
61
|
end
|
|
49
62
|
|
|
63
|
+
def copy_assets
|
|
64
|
+
copy_asset(TOKENS_CSS_SOURCE, StimulusPlumbers::Generators::TokensDirective::TOKENS_CSS_PATH) &&
|
|
65
|
+
copy_asset(ANIMATIONS_CSS_SOURCE, AnimationsDirective::ANIMATIONS_CSS_PATH)
|
|
66
|
+
end
|
|
67
|
+
|
|
50
68
|
def apply_sources_directive(css_file)
|
|
51
69
|
apply_edit(
|
|
52
70
|
css_file,
|
|
@@ -6,14 +6,14 @@ module StimulusPlumbers
|
|
|
6
6
|
module Tailwind
|
|
7
7
|
module Generators
|
|
8
8
|
module AnimationsDirective
|
|
9
|
-
|
|
10
|
-
ANIMATIONS_CSS_REL_PATH = "app/assets/stylesheets/stimulus_plumbers/tailwind/animations.css"
|
|
9
|
+
ANIMATIONS_CSS_PATH = "app/assets/stylesheets/stimulus_plumbers/tailwind/animations.css"
|
|
11
10
|
|
|
12
11
|
module_function
|
|
13
12
|
|
|
14
|
-
def directive(from:)
|
|
15
|
-
path = Pathname.new(
|
|
13
|
+
def directive(from:, destination_root:)
|
|
14
|
+
path = Pathname.new(destination_root).join(ANIMATIONS_CSS_PATH)
|
|
16
15
|
rel = path.relative_path_from(Pathname.new(from))
|
|
16
|
+
rel = "./#{rel}" unless rel.to_s.start_with?(".", "/")
|
|
17
17
|
%(@import "#{rel}";)
|
|
18
18
|
end
|
|
19
19
|
|
|
@@ -24,7 +24,7 @@ module StimulusPlumbers
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def stale_pattern
|
|
27
|
-
%r{@import "[^"]*#{Regexp.escape(
|
|
27
|
+
%r{@import "[^"]*#{Regexp.escape(ANIMATIONS_CSS_PATH)}";}
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -20,24 +20,24 @@ module StimulusPlumbers
|
|
|
20
20
|
info: %w[[--card-ring:var(--sp-color-info)]].freeze
|
|
21
21
|
}.freeze
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
HEADER = %w[
|
|
24
24
|
flex items-center gap-(--sp-space-3)
|
|
25
25
|
px-(--sp-space-6) py-(--sp-space-6)
|
|
26
26
|
].freeze
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
ICON = %w[
|
|
29
29
|
shrink-0 stroke-current text-(--sp-color-muted-fg)
|
|
30
30
|
].freeze
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
TITLE = %w[
|
|
33
33
|
text-(length:--sp-text-base) font-semibold text-(--sp-color-fg)
|
|
34
34
|
].freeze
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
BODY = %w[
|
|
37
37
|
px-(--sp-space-6) py-(--sp-space-3)
|
|
38
38
|
].freeze
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
ACTION = %w[w-full justify-start].freeze
|
|
41
41
|
|
|
42
42
|
private
|
|
43
43
|
|
|
@@ -45,11 +45,11 @@ module StimulusPlumbers
|
|
|
45
45
|
{ classes: klasses(*VARIANTS.fetch(variant, VARIANTS[:tertiary]), *BASE) }
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def card_header_classes = { classes: klasses(*
|
|
49
|
-
def card_icon_classes = { classes: klasses(*
|
|
50
|
-
def card_title_classes = { classes: klasses(*
|
|
51
|
-
def card_body_classes = { classes: klasses(*
|
|
52
|
-
def card_action_classes = { classes: klasses(*
|
|
48
|
+
def card_header_classes = { classes: klasses(*HEADER) }
|
|
49
|
+
def card_icon_classes = { classes: klasses(*ICON) }
|
|
50
|
+
def card_title_classes = { classes: klasses(*TITLE) }
|
|
51
|
+
def card_body_classes = { classes: klasses(*BODY) }
|
|
52
|
+
def card_action_classes = { classes: klasses(*ACTION) }
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
end
|
|
@@ -4,9 +4,9 @@ module StimulusPlumbers
|
|
|
4
4
|
module Themes
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Checklist
|
|
7
|
-
|
|
7
|
+
CHECKLIST = %w[flex flex-col gap-(--sp-space-1)].freeze
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
ITEM = [
|
|
10
10
|
*Control::BASE,
|
|
11
11
|
"group/checklist-item flex items-center gap-(--sp-space-2) w-full text-start",
|
|
12
12
|
"px-(--sp-space-2) py-(--sp-space-1)",
|
|
@@ -16,7 +16,7 @@ module StimulusPlumbers
|
|
|
16
16
|
"has-disabled:cursor-default has-disabled:hover:bg-transparent"
|
|
17
17
|
].freeze
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
INPUT = [
|
|
20
20
|
*Control::ACCENT,
|
|
21
21
|
"size-(--sp-control-size) rounded-(--sp-radius-sm) shrink-0",
|
|
22
22
|
"border border-(--sp-color-border) bg-(--sp-color-muted)",
|
|
@@ -24,40 +24,40 @@ module StimulusPlumbers
|
|
|
24
24
|
"disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
|
|
25
25
|
].freeze
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
CONTENT = %w[flex flex-col flex-1 min-w-0].freeze
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
TITLE = %w[
|
|
30
30
|
text-(length:--sp-text-sm) font-medium text-(--sp-color-fg)
|
|
31
31
|
group-has-checked/checklist-item:line-through
|
|
32
32
|
group-has-checked/checklist-item:text-(--sp-color-muted-fg)
|
|
33
33
|
].freeze
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
DESCRIPTION = %w[text-(length:--sp-text-xs) text-(--sp-color-muted-fg)].freeze
|
|
36
36
|
|
|
37
37
|
private
|
|
38
38
|
|
|
39
39
|
def checklist_classes
|
|
40
|
-
{ classes: klasses(*
|
|
40
|
+
{ classes: klasses(*CHECKLIST) }
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def checklist_item_classes
|
|
44
|
-
{ classes: klasses(*
|
|
44
|
+
{ classes: klasses(*ITEM) }
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def checklist_item_input_classes
|
|
48
|
-
{ classes: klasses(*
|
|
48
|
+
{ classes: klasses(*INPUT) }
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
def checklist_item_content_classes
|
|
52
|
-
{ classes: klasses(*
|
|
52
|
+
{ classes: klasses(*CONTENT) }
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def checklist_item_title_classes
|
|
56
|
-
{ classes: klasses(*
|
|
56
|
+
{ classes: klasses(*TITLE) }
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def checklist_item_description_classes
|
|
60
|
-
{ classes: klasses(*
|
|
60
|
+
{ classes: klasses(*DESCRIPTION) }
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
end
|
|
@@ -32,7 +32,7 @@ module StimulusPlumbers
|
|
|
32
32
|
py-(--sp-space-1) overflow-y-auto max-h-60 min-h-(--sp-space-6)
|
|
33
33
|
].freeze
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
OPTION = %w[
|
|
36
36
|
flex items-center gap-(--sp-space-2) w-full
|
|
37
37
|
px-(--sp-space-2) py-(--sp-space-1)
|
|
38
38
|
rounded-(--sp-radius-sm) text-(length:--sp-text-sm)
|
|
@@ -96,7 +96,7 @@ module StimulusPlumbers
|
|
|
96
96
|
def combobox_option_classes(selected: false, disabled: false)
|
|
97
97
|
{
|
|
98
98
|
classes: klasses(
|
|
99
|
-
*
|
|
99
|
+
*OPTION,
|
|
100
100
|
*(selected ? OPTION_SELECTED : []),
|
|
101
101
|
*(disabled ? OPTION_DISABLED : [])
|
|
102
102
|
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StimulusPlumbers
|
|
4
|
+
module Themes
|
|
5
|
+
module Tailwind
|
|
6
|
+
module Form
|
|
7
|
+
module Code
|
|
8
|
+
FIELD = %w[
|
|
9
|
+
relative inline-flex w-fit rounded-(--sp-radius-md)
|
|
10
|
+
focus-within:ring-(length:--sp-focus-ring-width) focus-within:ring-(--sp-focus-ring-color)
|
|
11
|
+
focus-within:ring-offset-(length:--sp-focus-ring-offset)
|
|
12
|
+
].freeze
|
|
13
|
+
FIELD_ERROR = %w[focus-within:ring-(--sp-color-error)].freeze
|
|
14
|
+
CELLS = %w[flex items-center gap-(--sp-space-1)].freeze
|
|
15
|
+
CELL = %w[
|
|
16
|
+
flex size-10 items-center justify-center rounded-(--sp-radius-md) border
|
|
17
|
+
border-(--sp-color-muted-fg) bg-(--sp-color-bg)
|
|
18
|
+
text-(length:--sp-text-lg) font-medium text-(--sp-color-fg)
|
|
19
|
+
transition-colors
|
|
20
|
+
data-[filled]:border-(--sp-color-fg)
|
|
21
|
+
data-[caret]:border-(--sp-color-primary) data-[caret]:ring-1 data-[caret]:ring-(--sp-color-primary)
|
|
22
|
+
data-[group-end]:me-(--sp-space-2)
|
|
23
|
+
].freeze
|
|
24
|
+
CELL_ERROR = %w[border-(--sp-color-error) data-[caret]:ring-(--sp-color-error)].freeze
|
|
25
|
+
OVERLAY = %w[absolute inset-0 size-full cursor-text opacity-0 disabled:cursor-not-allowed].freeze
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def form_field_input_code_classes(error: false) = { classes: klasses(*FIELD, *(error ? FIELD_ERROR : [])) }
|
|
30
|
+
def form_field_input_code_cells_classes = { classes: klasses(*CELLS) }
|
|
31
|
+
def form_field_input_code_cell_classes(error: false) = { classes: klasses(*CELL, *(error ? CELL_ERROR : [])) }
|
|
32
|
+
def form_field_input_code_overlay_classes(**) = { classes: klasses(*OVERLAY) }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StimulusPlumbers
|
|
4
|
+
module Themes
|
|
5
|
+
module Tailwind
|
|
6
|
+
module Form
|
|
7
|
+
module CreditCard
|
|
8
|
+
FIELD = %w[
|
|
9
|
+
relative inline-flex w-fit rounded-(--sp-radius-md)
|
|
10
|
+
focus-within:ring-(length:--sp-focus-ring-width) focus-within:ring-(--sp-focus-ring-color)
|
|
11
|
+
focus-within:ring-offset-(length:--sp-focus-ring-offset)
|
|
12
|
+
].freeze
|
|
13
|
+
FIELD_ERROR = %w[focus-within:ring-(--sp-color-error)].freeze
|
|
14
|
+
CELLS = %w[flex items-center gap-(--sp-space-1)].freeze
|
|
15
|
+
CELL = %w[
|
|
16
|
+
flex h-10 min-w-16 items-center justify-center px-(--sp-space-2)
|
|
17
|
+
rounded-(--sp-radius-md) border
|
|
18
|
+
border-(--sp-color-muted-fg) bg-(--sp-color-bg)
|
|
19
|
+
text-(length:--sp-text-lg) font-medium text-(--sp-color-fg)
|
|
20
|
+
transition-colors
|
|
21
|
+
data-[filled]:border-(--sp-color-fg)
|
|
22
|
+
data-[caret]:border-(--sp-color-primary) data-[caret]:ring-1 data-[caret]:ring-(--sp-color-primary)
|
|
23
|
+
].freeze
|
|
24
|
+
CELL_ERROR = %w[border-(--sp-color-error) data-[caret]:ring-(--sp-color-error)].freeze
|
|
25
|
+
SEPARATOR = %w[text-(--sp-color-muted-fg)].freeze
|
|
26
|
+
OVERLAY = %w[absolute inset-0 size-full cursor-text opacity-0 disabled:cursor-not-allowed].freeze
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def form_field_input_credit_card_classes(error: false) = { classes: klasses(*FIELD, *(error ? FIELD_ERROR : [])) }
|
|
31
|
+
def form_field_input_credit_card_cells_classes = { classes: klasses(*CELLS) }
|
|
32
|
+
def form_field_input_credit_card_cell_classes(error: false) = { classes: klasses(*CELL, *(error ? CELL_ERROR : [])) }
|
|
33
|
+
def form_field_input_credit_card_separator_classes = { classes: klasses(*SEPARATOR) }
|
|
34
|
+
def form_field_input_credit_card_overlay_classes(**) = { classes: klasses(*OVERLAY) }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -16,7 +16,7 @@ module StimulusPlumbers
|
|
|
16
16
|
standard: %w[relative z-0].freeze
|
|
17
17
|
}.freeze
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
FLOATING_LABEL = %w[
|
|
20
20
|
absolute text-(length:--sp-text-sm) text-(--sp-color-muted-fg)
|
|
21
21
|
duration-300 transform origin-[0]
|
|
22
22
|
].freeze
|
|
@@ -117,7 +117,7 @@ module StimulusPlumbers
|
|
|
117
117
|
def form_field_label_classes(floating: nil, hidden: false, error: false, **)
|
|
118
118
|
if floating
|
|
119
119
|
color = error ? FLOATING_LABEL_ERROR : FLOATING_LABEL_FOCUS
|
|
120
|
-
{ classes: klasses(*
|
|
120
|
+
{ classes: klasses(*FLOATING_LABEL, *FLOATING_LABEL_TYPES.fetch(floating, []), *color) }
|
|
121
121
|
else
|
|
122
122
|
{ classes: klasses(*LABEL, hidden ? "sr-only" : nil) }
|
|
123
123
|
end
|
|
@@ -6,7 +6,7 @@ module StimulusPlumbers
|
|
|
6
6
|
module Form
|
|
7
7
|
module Input
|
|
8
8
|
# ── Standalone input ──────────────────────────────────────────────────
|
|
9
|
-
|
|
9
|
+
INPUT = %w[
|
|
10
10
|
w-full rounded-(--sp-radius-md) border px-(--sp-space-3) py-(--sp-space-2)
|
|
11
11
|
text-(length:--sp-text-sm) text-(--sp-color-fg) bg-(--sp-color-bg)
|
|
12
12
|
focus:outline-none focus:ring-(length:--sp-focus-ring-width) focus:ring-offset-0
|
|
@@ -18,7 +18,7 @@ module StimulusPlumbers
|
|
|
18
18
|
INPUT_ERROR = %w[border-(--sp-color-error) focus:ring-(--sp-color-error)].freeze
|
|
19
19
|
|
|
20
20
|
# ── Floating input ────────────────────────────────────────────────────
|
|
21
|
-
|
|
21
|
+
FLOATING_INPUT = %w[
|
|
22
22
|
peer w-full text-(length:--sp-text-sm) text-(--sp-color-fg) appearance-none
|
|
23
23
|
focus:outline-none focus:ring-0
|
|
24
24
|
focus-visible:outline-none focus-visible:ring-0
|
|
@@ -44,11 +44,11 @@ module StimulusPlumbers
|
|
|
44
44
|
FLOATING_INPUT_ERROR = %w[border-(--sp-color-error)].freeze
|
|
45
45
|
|
|
46
46
|
# ── Input group ───────────────────────────────────────────────────────
|
|
47
|
-
|
|
47
|
+
INPUT_GROUP = %w[flex items-center overflow-hidden rounded-(--sp-radius-md) border].freeze
|
|
48
48
|
INPUT_GROUP_BORDER = { error: "border-(--sp-color-error)", default: "border-(--sp-color-muted-fg)" }.freeze
|
|
49
49
|
|
|
50
50
|
# ── Floating input group ──────────────────────────────────────────────
|
|
51
|
-
|
|
51
|
+
FLOATING_INPUT_GROUP = %w[flex items-center overflow-hidden peer].freeze
|
|
52
52
|
FLOATING_INPUT_GROUP_TYPES = {
|
|
53
53
|
filled: %w[rounded-t-(--sp-radius-md) bg-(--sp-color-bg-muted) border-0 border-b-2].freeze,
|
|
54
54
|
outlined: %w[rounded-(--sp-radius-md) border].freeze,
|
|
@@ -136,13 +136,13 @@ module StimulusPlumbers
|
|
|
136
136
|
def form_field_input_classes(floating: nil, error: false)
|
|
137
137
|
if floating
|
|
138
138
|
{ classes: klasses(
|
|
139
|
-
*
|
|
139
|
+
*FLOATING_INPUT,
|
|
140
140
|
*FLOATING_INPUT_TYPES.fetch(floating, []),
|
|
141
141
|
*(error ? FLOATING_INPUT_ERROR : FLOATING_INPUT_DEFAULT)
|
|
142
142
|
)
|
|
143
143
|
}
|
|
144
144
|
else
|
|
145
|
-
{ classes: klasses(*
|
|
145
|
+
{ classes: klasses(*INPUT, *(error ? INPUT_ERROR : INPUT_DEFAULT)) }
|
|
146
146
|
end
|
|
147
147
|
end
|
|
148
148
|
|
|
@@ -171,9 +171,9 @@ module StimulusPlumbers
|
|
|
171
171
|
def input_group_classes(error: false, floating: nil)
|
|
172
172
|
if floating
|
|
173
173
|
color = error ? FLOATING_INPUT_GROUP_ERROR : FLOATING_INPUT_GROUP_DEFAULT
|
|
174
|
-
{ classes: klasses(*
|
|
174
|
+
{ classes: klasses(*FLOATING_INPUT_GROUP, *FLOATING_INPUT_GROUP_TYPES.fetch(floating, []), *color) }
|
|
175
175
|
else
|
|
176
|
-
{ classes: klasses(*
|
|
176
|
+
{ classes: klasses(*INPUT_GROUP, INPUT_GROUP_BORDER[error ? :error : :default]) }
|
|
177
177
|
end
|
|
178
178
|
end
|
|
179
179
|
|
|
@@ -183,7 +183,7 @@ module StimulusPlumbers
|
|
|
183
183
|
else
|
|
184
184
|
{
|
|
185
185
|
classes: klasses(
|
|
186
|
-
*
|
|
186
|
+
*INPUT,
|
|
187
187
|
*(error ? INPUT_ERROR : INPUT_DEFAULT),
|
|
188
188
|
*COMBOBOX_INPUT,
|
|
189
189
|
*COMBOBOX_TRIGGER_GROUP
|
|
@@ -195,7 +195,7 @@ module StimulusPlumbers
|
|
|
195
195
|
def form_field_input_combobox_floating_classes(floating: :standard, error: false)
|
|
196
196
|
{
|
|
197
197
|
classes: klasses(
|
|
198
|
-
*
|
|
198
|
+
*FLOATING_INPUT,
|
|
199
199
|
*FLOATING_INPUT_TYPES.fetch(floating, []),
|
|
200
200
|
*(error ? FLOATING_INPUT_ERROR : FLOATING_INPUT_DEFAULT),
|
|
201
201
|
*COMBOBOX_INPUT,
|
|
@@ -4,13 +4,13 @@ module StimulusPlumbers
|
|
|
4
4
|
module Themes
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Form
|
|
7
|
-
|
|
7
|
+
GROUP = %w[flex gap-(--sp-space-1) mb-(--sp-space-3)].freeze
|
|
8
8
|
GROUP_INLINE = %w[flex-row items-center].freeze
|
|
9
9
|
|
|
10
10
|
private
|
|
11
11
|
|
|
12
12
|
def form_group_classes(layout: :stacked, **_rest)
|
|
13
|
-
{ classes: klasses(*
|
|
13
|
+
{ classes: klasses(*GROUP, layout == :inline ? GROUP_INLINE : "flex-col") }
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def form_submit_classes(**) = {}
|
|
@@ -5,19 +5,19 @@ module StimulusPlumbers
|
|
|
5
5
|
module Tailwind
|
|
6
6
|
module List
|
|
7
7
|
# ── Section ───────────────────────────────────────────────────────────
|
|
8
|
-
|
|
8
|
+
SECTION_TITLE = %w[
|
|
9
9
|
block px-(--sp-space-2) pb-(--sp-space-1)
|
|
10
10
|
text-(length:--sp-text-xs) font-semibold uppercase tracking-wider
|
|
11
11
|
text-(--sp-color-muted-fg)
|
|
12
12
|
].freeze
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
SECTION_DESCRIPTION = %w[
|
|
15
15
|
block px-(--sp-space-2) pb-(--sp-space-1)
|
|
16
16
|
text-(length:--sp-text-xs) text-(--sp-color-muted-fg)
|
|
17
17
|
].freeze
|
|
18
18
|
|
|
19
19
|
# ── Item ──────────────────────────────────────────────────────────────
|
|
20
|
-
|
|
20
|
+
ITEM = [
|
|
21
21
|
*Control::BASE,
|
|
22
22
|
"flex items-center gap-(--sp-space-2) w-full",
|
|
23
23
|
"px-(--sp-space-2) py-(--sp-space-1)",
|
|
@@ -29,15 +29,15 @@ module StimulusPlumbers
|
|
|
29
29
|
"aria-[current]:bg-(--sp-color-primary)/10 aria-[current]:text-(--sp-color-primary)"
|
|
30
30
|
].freeze
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
ITEM_CONTENT = %w[
|
|
33
33
|
flex flex-col flex-1 min-w-0
|
|
34
34
|
].freeze
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
ITEM_TITLE = %w[
|
|
37
37
|
text-(length:--sp-text-sm) font-medium text-(--sp-color-fg)
|
|
38
38
|
].freeze
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
ITEM_DESCRIPTION = %w[
|
|
41
41
|
text-(length:--sp-text-xs) text-(--sp-color-muted-fg)
|
|
42
42
|
].freeze
|
|
43
43
|
|
|
@@ -52,15 +52,15 @@ module StimulusPlumbers
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def list_section_title_classes
|
|
55
|
-
{ classes: klasses(*
|
|
55
|
+
{ classes: klasses(*SECTION_TITLE) }
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def list_section_description_classes
|
|
59
|
-
{ classes: klasses(*
|
|
59
|
+
{ classes: klasses(*SECTION_DESCRIPTION) }
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def list_item_classes
|
|
63
|
-
{ classes: klasses(*
|
|
63
|
+
{ classes: klasses(*ITEM) }
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
def list_item_icon_classes
|
|
@@ -68,15 +68,15 @@ module StimulusPlumbers
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def list_item_content_classes
|
|
71
|
-
{ classes: klasses(*
|
|
71
|
+
{ classes: klasses(*ITEM_CONTENT) }
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
def list_item_title_classes
|
|
75
|
-
{ classes: klasses(*
|
|
75
|
+
{ classes: klasses(*ITEM_TITLE) }
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
def list_item_description_classes
|
|
79
|
-
{ classes: klasses(*
|
|
79
|
+
{ classes: klasses(*ITEM_DESCRIPTION) }
|
|
80
80
|
end
|
|
81
81
|
end
|
|
82
82
|
end
|
|
@@ -5,7 +5,7 @@ module StimulusPlumbers
|
|
|
5
5
|
module Tailwind
|
|
6
6
|
module OrderedList
|
|
7
7
|
# ── Item ──────────────────────────────────────────────────────────────
|
|
8
|
-
|
|
8
|
+
ITEM = [
|
|
9
9
|
*Control::BASE,
|
|
10
10
|
"flex items-center gap-(--sp-space-2) w-full",
|
|
11
11
|
"px-(--sp-space-2) py-(--sp-space-1)",
|
|
@@ -15,7 +15,7 @@ module StimulusPlumbers
|
|
|
15
15
|
"aria-[current]:bg-(--sp-color-primary)/10 aria-[current]:text-(--sp-color-primary)"
|
|
16
16
|
].freeze
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
HANDLE = %w[
|
|
19
19
|
flex items-center justify-center shrink-0
|
|
20
20
|
stroke-current
|
|
21
21
|
text-(--sp-color-muted-fg)
|
|
@@ -23,15 +23,15 @@ module StimulusPlumbers
|
|
|
23
23
|
touch-none
|
|
24
24
|
].freeze
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
CONTENT = %w[
|
|
27
27
|
flex flex-col flex-1 min-w-0
|
|
28
28
|
].freeze
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
TITLE = %w[
|
|
31
31
|
text-(length:--sp-text-sm) font-medium text-(--sp-color-fg)
|
|
32
32
|
].freeze
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
DESCRIPTION = %w[
|
|
35
35
|
text-(length:--sp-text-xs) text-(--sp-color-muted-fg)
|
|
36
36
|
].freeze
|
|
37
37
|
|
|
@@ -42,23 +42,23 @@ module StimulusPlumbers
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def ordered_list_item_classes
|
|
45
|
-
{ classes: klasses(*
|
|
45
|
+
{ classes: klasses(*ITEM) }
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def ordered_list_item_handle_classes
|
|
49
|
-
{ classes: klasses(*
|
|
49
|
+
{ classes: klasses(*HANDLE) }
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def ordered_list_item_content_classes
|
|
53
|
-
{ classes: klasses(*
|
|
53
|
+
{ classes: klasses(*CONTENT) }
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def ordered_list_item_title_classes
|
|
57
|
-
{ classes: klasses(*
|
|
57
|
+
{ classes: klasses(*TITLE) }
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def ordered_list_item_description_classes
|
|
61
|
-
{ classes: klasses(*
|
|
61
|
+
{ classes: klasses(*DESCRIPTION) }
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
end
|
|
@@ -12,6 +12,8 @@ require_relative "tailwind/card"
|
|
|
12
12
|
require_relative "tailwind/combobox"
|
|
13
13
|
require_relative "tailwind/form"
|
|
14
14
|
require_relative "tailwind/form/field"
|
|
15
|
+
require_relative "tailwind/form/code"
|
|
16
|
+
require_relative "tailwind/form/credit_card"
|
|
15
17
|
require_relative "tailwind/form/input"
|
|
16
18
|
require_relative "tailwind/icon"
|
|
17
19
|
require_relative "tailwind/indicator"
|
|
@@ -34,6 +36,8 @@ module StimulusPlumbers
|
|
|
34
36
|
include Tailwind::Card
|
|
35
37
|
include Tailwind::Form
|
|
36
38
|
include Tailwind::Form::Field
|
|
39
|
+
include Tailwind::Form::Code
|
|
40
|
+
include Tailwind::Form::CreditCard
|
|
37
41
|
include Tailwind::Form::Input
|
|
38
42
|
include Tailwind::Icon
|
|
39
43
|
include Tailwind::Indicator
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stimulus_plumbers_tailwind
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Chang
|
|
@@ -50,6 +50,8 @@ files:
|
|
|
50
50
|
- lib/stimulus_plumbers/themes/tailwind/combobox.rb
|
|
51
51
|
- lib/stimulus_plumbers/themes/tailwind/control.rb
|
|
52
52
|
- lib/stimulus_plumbers/themes/tailwind/form.rb
|
|
53
|
+
- lib/stimulus_plumbers/themes/tailwind/form/code.rb
|
|
54
|
+
- lib/stimulus_plumbers/themes/tailwind/form/credit_card.rb
|
|
53
55
|
- lib/stimulus_plumbers/themes/tailwind/form/field.rb
|
|
54
56
|
- lib/stimulus_plumbers/themes/tailwind/form/input.rb
|
|
55
57
|
- lib/stimulus_plumbers/themes/tailwind/icon.rb
|