stimulus_plumbers_tailwind 0.4.0 → 0.4.3
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 +40 -0
- data/README.md +27 -9
- data/lib/generators/stimulus_plumbers_tailwind/install/install_generator.rb +78 -0
- data/lib/stimulus_plumbers/themes/tailwind/avatar.rb +12 -12
- data/lib/stimulus_plumbers/themes/tailwind/button.rb +26 -22
- data/lib/stimulus_plumbers/themes/tailwind/calendar.rb +23 -20
- data/lib/stimulus_plumbers/themes/tailwind/card.rb +4 -5
- data/lib/stimulus_plumbers/themes/tailwind/combobox.rb +27 -17
- data/lib/stimulus_plumbers/themes/tailwind/form/field.rb +44 -57
- data/lib/stimulus_plumbers/themes/tailwind/form/input.rb +140 -54
- data/lib/stimulus_plumbers/themes/tailwind/form.rb +1 -10
- data/lib/stimulus_plumbers/themes/tailwind/icon.rb +7 -2
- data/lib/stimulus_plumbers/themes/tailwind/layout.rb +6 -3
- data/lib/stimulus_plumbers/themes/tailwind/link.rb +31 -29
- data/lib/stimulus_plumbers/themes/tailwind/list.rb +15 -13
- data/lib/stimulus_plumbers/themes/tailwind/timeline/group.rb +28 -0
- data/lib/stimulus_plumbers/themes/tailwind/timeline.rb +104 -0
- data/lib/stimulus_plumbers/themes/tailwind_theme.rb +3 -0
- data/lib/stimulus_plumbers_tailwind/engine.rb +4 -0
- data/lib/stimulus_plumbers_tailwind/version.rb +1 -1
- data/lib/tasks/stimulus_plumbers_tailwind.rake +15 -0
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9eb6bbfe958bd425b443843724ef2b3a66041f04fe40ec4b041a72accd9ec497
|
|
4
|
+
data.tar.gz: f1928462ed5485e7560a1993e72aeddbd90dd734db280703ae50e751bfcb6306
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ce4edf07b1b20042b73e67c4d16d86eb6213e0e08a3fdb2049a362c4042941fe7672b5503e185da78c4e85394a4592e7a51971fcfca01802c14d4df5c2cf4bad
|
|
7
|
+
data.tar.gz: 625987458573abbe7ab612323c81ce300b2ac993347e6af4903e1a034b35c7153a81d716695a79531c38578d78f0884feddfe15655b0e252cbccc0f254d05ae5
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
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.3](https://github.com/ryancyq/stimulus-plumbers/compare/stimulus-plumbers-tailwind/v0.4.2..stimulus-plumbers-tailwind/v0.4.3) - 2026-06-30
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- tailwind generator ([#149](https://github.com/ryancyq/stimulus-plumbers/issues/149)) - ([9dafae0](https://github.com/ryancyq/stimulus-plumbers/commit/9dafae03b5d49fb543d08f84cdb718d944dce49f)) - Ryan Chang
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
## [0.4.2](https://github.com/ryancyq/stimulus-plumbers/compare/stimulus-plumbers-tailwind/v0.4.0..stimulus-plumbers-tailwind/v0.4.2) - 2026-06-30
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
- form submit button style ([#127](https://github.com/ryancyq/stimulus-plumbers/issues/127)) - ([2bbc73f](https://github.com/ryancyq/stimulus-plumbers/commit/2bbc73f15b7ffa2d9d8f87991adead33fab8156e)) - Ryan Chang
|
|
18
|
+
- various component styles ([#128](https://github.com/ryancyq/stimulus-plumbers/issues/128)) - ([011cc69](https://github.com/ryancyq/stimulus-plumbers/commit/011cc69bb6df3770949564521cdf949493d028cc)) - Ryan Chang
|
|
19
|
+
- use generic icon in core gem then provide alias in tailwind gem ([#129](https://github.com/ryancyq/stimulus-plumbers/issues/129)) - ([5c87d0d](https://github.com/ryancyq/stimulus-plumbers/commit/5c87d0da0c012652a3afa5aa8345b58d03e6ce5b)) - Ryan Chang
|
|
20
|
+
- combobox time ([#130](https://github.com/ryancyq/stimulus-plumbers/issues/130)) - ([ff5d968](https://github.com/ryancyq/stimulus-plumbers/commit/ff5d968da34fc723b0112a791bd95ef43f2b1640)) - Ryan Chang
|
|
21
|
+
- extract img avatar building block ([#132](https://github.com/ryancyq/stimulus-plumbers/issues/132)) - ([c3808b8](https://github.com/ryancyq/stimulus-plumbers/commit/c3808b8df38eecef940b51dab29f50bc815b4e74)) - Ryan Chang
|
|
22
|
+
- update floating style to label/input/group ([#135](https://github.com/ryancyq/stimulus-plumbers/issues/135)) - ([3947f38](https://github.com/ryancyq/stimulus-plumbers/commit/3947f38467e0a498fe51101d1859a573db93349f)) - Ryan Chang
|
|
23
|
+
- accessibility + plumber helpers ([#136](https://github.com/ryancyq/stimulus-plumbers/issues/136)) - ([e84053d](https://github.com/ryancyq/stimulus-plumbers/commit/e84053d43db4726c3704d459a0464f70529fff8b)) - Ryan Chang
|
|
24
|
+
- calendar disabled + out of range ([#148](https://github.com/ryancyq/stimulus-plumbers/issues/148)) - ([7bd1ca2](https://github.com/ryancyq/stimulus-plumbers/commit/7bd1ca21af1b982cf7df9460e0ba1c9e78866a87)) - Ryan Chang
|
|
25
|
+
|
|
26
|
+
### Dependencies
|
|
27
|
+
|
|
28
|
+
- **(deps-dev)** bump @playwright/test in /stimulus-plumbers-tailwind ([#147](https://github.com/ryancyq/stimulus-plumbers/issues/147)) - ([941634d](https://github.com/ryancyq/stimulus-plumbers/commit/941634de18e2accc39f926258cb3d1b2534d11dc)) - dependabot[bot]
|
|
29
|
+
- **(deps-dev)** bump prettier in /stimulus-plumbers-tailwind ([#146](https://github.com/ryancyq/stimulus-plumbers/issues/146)) - ([570c8ff](https://github.com/ryancyq/stimulus-plumbers/commit/570c8ff7630039bdbdc6e3d89c6a181bbc706dd8)) - dependabot[bot]
|
|
30
|
+
|
|
31
|
+
### Documentation
|
|
32
|
+
|
|
33
|
+
- update readme and component doc ([#134](https://github.com/ryancyq/stimulus-plumbers/issues/134)) - ([3e5f462](https://github.com/ryancyq/stimulus-plumbers/commit/3e5f4621c4fbf142af061659cfbb8cd3e99fd093)) - Ryan Chang
|
|
34
|
+
- update component documentation - ([89ecb78](https://github.com/ryancyq/stimulus-plumbers/commit/89ecb786d88eed66ab925921ac182aa84560207d)) - Ryan Chang
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
- calendar redesign ([#133](https://github.com/ryancyq/stimulus-plumbers/issues/133)) - ([e19df95](https://github.com/ryancyq/stimulus-plumbers/commit/e19df95f3814b3d947142722ff0295f1bdcef6b3)) - Ryan Chang
|
|
39
|
+
|
|
40
|
+
### Tests
|
|
41
|
+
|
|
42
|
+
- update sandbox view and spec coverage ([#122](https://github.com/ryancyq/stimulus-plumbers/issues/122)) - ([0fd3381](https://github.com/ryancyq/stimulus-plumbers/commit/0fd33817325070c29ffed82d37843b4c4be3e911)) - Ryan Chang
|
|
43
|
+
- update collection radio locator - ([f0fa9e8](https://github.com/ryancyq/stimulus-plumbers/commit/f0fa9e85bc0b835b3adc46f5dc406a8bdedbeefe)) - Ryan Chang
|
|
44
|
+
|
|
5
45
|
---
|
|
6
46
|
## [0.4.0](https://github.com/ryancyq/stimulus-plumbers/compare/stimulus-plumbers-tailwind/v0.3.3..stimulus-plumbers-tailwind/v0.4.0) - 2026-06-14
|
|
7
47
|
|
data/README.md
CHANGED
|
@@ -27,18 +27,34 @@ Activate the theme in an initializer or `config/application.rb`:
|
|
|
27
27
|
|
|
28
28
|
```ruby
|
|
29
29
|
StimulusPlumbers.configure do |config|
|
|
30
|
-
config.theme
|
|
30
|
+
config.theme.use(:tailwind)
|
|
31
31
|
end
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Run the install generator once to inject the required `@source` directive into your Tailwind CSS entry file:
|
|
35
35
|
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
@source "/path/to/gems/stimulus_plumbers_tailwind-VERSION/lib/**/*.rb";
|
|
36
|
+
```bash
|
|
37
|
+
bin/rails generate stimulus_plumbers_tailwind:install
|
|
39
38
|
```
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
The generator checks these files in order:
|
|
41
|
+
|
|
42
|
+
- `app/assets/stylesheets/application.tailwind.css`
|
|
43
|
+
- `app/assets/stylesheets/application.css`
|
|
44
|
+
- `app/javascript/entrypoints/application.css`
|
|
45
|
+
|
|
46
|
+
Override the detected file for both the generator and rake task with `TAILWIND_CSS_FILE=/path/to/entry.css`.
|
|
47
|
+
|
|
48
|
+
After the initial install, 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:
|
|
49
|
+
|
|
50
|
+
- `assets:precompile` (Sprockets and Propshaft both define this task)
|
|
51
|
+
- `tailwindcss:build` (when `tailwindcss-rails` is present)
|
|
52
|
+
|
|
53
|
+
To trigger an update manually without a full compile (useful for debugging or after `bundle update`):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
bin/rails stimulus_plumbers_tailwind:install
|
|
57
|
+
```
|
|
42
58
|
|
|
43
59
|
## Theming
|
|
44
60
|
|
|
@@ -46,7 +62,6 @@ Use `bundle show stimulus_plumbers_tailwind` to get the exact installed path.
|
|
|
46
62
|
|
|
47
63
|
| Module | Components |
|
|
48
64
|
|--------|------------|
|
|
49
|
-
| `Tailwind::ActionList` | Action list, menu items |
|
|
50
65
|
| `Tailwind::Avatar` | Avatar |
|
|
51
66
|
| `Tailwind::Button` | Button |
|
|
52
67
|
| `Tailwind::Calendar` | Calendar grid, date picker |
|
|
@@ -55,6 +70,9 @@ Use `bundle show stimulus_plumbers_tailwind` to get the exact installed path.
|
|
|
55
70
|
| `Tailwind::Form` | Form fields, labels, errors |
|
|
56
71
|
| `Tailwind::Icon` | Icon (SVG rendering, icon registry) |
|
|
57
72
|
| `Tailwind::Layout` | Layout primitives |
|
|
73
|
+
| `Tailwind::Link` | Link |
|
|
74
|
+
| `Tailwind::List` | List |
|
|
75
|
+
| `Tailwind::Timeline` | Timeline |
|
|
58
76
|
|
|
59
77
|
Custom themes can subclass `TailwindTheme` to override individual methods, or subclass `StimulusPlumbers::Themes::Base` directly.
|
|
60
78
|
|
|
@@ -85,8 +103,8 @@ bundle install
|
|
|
85
103
|
npm install
|
|
86
104
|
|
|
87
105
|
bundle exec rake test:unit # unit tests
|
|
88
|
-
|
|
89
|
-
|
|
106
|
+
node --run test:snapshots # visual snapshot tests (Playwright)
|
|
107
|
+
node --run test:snapshots:update # regenerate baseline screenshots
|
|
90
108
|
bundle exec rake rubocop # lint
|
|
91
109
|
bundle exec rake coverage # run tests with coverage + collate report
|
|
92
110
|
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module StimulusPlumbersTailwind
|
|
6
|
+
module Generators
|
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
|
8
|
+
GEM_NAME = "stimulus_plumbers_tailwind"
|
|
9
|
+
TAILWIND_CSS_FILE = "TAILWIND_CSS_FILE"
|
|
10
|
+
CSS_CANDIDATES = %w[
|
|
11
|
+
app/assets/stylesheets/application.tailwind.css
|
|
12
|
+
app/assets/stylesheets/application.css
|
|
13
|
+
app/javascript/entrypoints/application.css
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
def install
|
|
17
|
+
css_file = entry_css_file
|
|
18
|
+
return warn_entry_css_not_found unless css_file
|
|
19
|
+
|
|
20
|
+
apply_edit(css_file)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def warn_entry_css_not_found
|
|
26
|
+
tried = CSS_CANDIDATES.map { |c| File.join(destination_root, c) }
|
|
27
|
+
tried.unshift(File.expand_path(ENV[TAILWIND_CSS_FILE])) if ENV[TAILWIND_CSS_FILE]
|
|
28
|
+
say "Could not find a Tailwind CSS entry file. Tried: #{tried.join(", ")}. " \
|
|
29
|
+
"Set #{TAILWIND_CSS_FILE}=/path/to/entry.css and re-run.",
|
|
30
|
+
:red
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def apply_edit(css_file)
|
|
34
|
+
content = File.read(css_file)
|
|
35
|
+
new_content, status = content_edit(content, source_directive)
|
|
36
|
+
|
|
37
|
+
if new_content
|
|
38
|
+
File.write(css_file, new_content)
|
|
39
|
+
say_status status, relative_to_destination(css_file), :green
|
|
40
|
+
else
|
|
41
|
+
say_status :identical, relative_to_destination(css_file)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def content_edit(content, source_line)
|
|
46
|
+
if content.include?(source_line)
|
|
47
|
+
nil
|
|
48
|
+
elsif (existing = content.match(%r{@source "[^"]*#{Regexp.escape(GEM_NAME)}[^"]*";}))
|
|
49
|
+
[content.sub(existing[0], source_line), :update]
|
|
50
|
+
elsif (import_line = content.match(%r{@import "tailwindcss"[^;]*;}))
|
|
51
|
+
[content.sub(import_line[0], "#{import_line[0]}\n#{source_line}"), :insert]
|
|
52
|
+
else
|
|
53
|
+
["#{content.rstrip}\n#{source_line}\n", :append]
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def source_directive
|
|
58
|
+
spec = Gem.loaded_specs[GEM_NAME]
|
|
59
|
+
%(@source "#{spec.gem_dir}/lib/**/*.rb";)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def entry_css_file
|
|
63
|
+
if ENV[TAILWIND_CSS_FILE]
|
|
64
|
+
path = File.expand_path(ENV[TAILWIND_CSS_FILE])
|
|
65
|
+
return path if File.exist?(path)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
CSS_CANDIDATES
|
|
69
|
+
.map { |c| File.join(destination_root, c) }
|
|
70
|
+
.find { |f| File.exist?(f) }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def relative_to_destination(path)
|
|
74
|
+
path.delete_prefix("#{destination_root}/")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -4,6 +4,18 @@ module StimulusPlumbers
|
|
|
4
4
|
module Themes
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Avatar
|
|
7
|
+
BASE = %w[
|
|
8
|
+
rounded-(--sp-radius-full)
|
|
9
|
+
overflow-hidden
|
|
10
|
+
inline-flex items-center justify-center
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
SIZES = {
|
|
14
|
+
sm: "size-(--sp-avatar-size-sm)",
|
|
15
|
+
md: "size-(--sp-avatar-size-md)",
|
|
16
|
+
lg: "size-(--sp-avatar-size-lg)"
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
7
19
|
VARIANTS = {
|
|
8
20
|
amber: "text-white bg-amber-600",
|
|
9
21
|
lime: "text-white bg-lime-600",
|
|
@@ -19,18 +31,6 @@ module StimulusPlumbers
|
|
|
19
31
|
blue: "text-white bg-blue-600"
|
|
20
32
|
}.freeze
|
|
21
33
|
|
|
22
|
-
SIZES = {
|
|
23
|
-
sm: "size-(--sp-icon-size)",
|
|
24
|
-
md: "size-(--sp-avatar-size)",
|
|
25
|
-
lg: "size-(--sp-avatar-size-lg)"
|
|
26
|
-
}.freeze
|
|
27
|
-
|
|
28
|
-
BASE = %w[
|
|
29
|
-
rounded-(--sp-radius-full)
|
|
30
|
-
overflow-hidden
|
|
31
|
-
inline-flex items-center justify-center
|
|
32
|
-
].freeze
|
|
33
|
-
|
|
34
34
|
def avatar_variants
|
|
35
35
|
VARIANTS
|
|
36
36
|
end
|
|
@@ -4,6 +4,25 @@ module StimulusPlumbers
|
|
|
4
4
|
module Themes
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Button
|
|
7
|
+
# ── Structure ─────────────────────────────────────────────────────────
|
|
8
|
+
BASE = [
|
|
9
|
+
*Control::BASE,
|
|
10
|
+
"whitespace-nowrap",
|
|
11
|
+
"focus-visible:ring-(--btn-ring)"
|
|
12
|
+
].freeze
|
|
13
|
+
|
|
14
|
+
LAYOUT = %w[
|
|
15
|
+
inline-flex items-center justify-center gap-(--sp-space-2)
|
|
16
|
+
[&:not(:has(>span))]:aspect-square
|
|
17
|
+
[&:not(:has(>span))]:px-0
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
CARD = %w[
|
|
21
|
+
inline-flex justify-start items-center flex-1 gap-(--sp-space-3) p-(--sp-space-4)
|
|
22
|
+
[&>:last-child:not(:first-child)]:ml-auto
|
|
23
|
+
].freeze
|
|
24
|
+
|
|
25
|
+
# ── Color tokens ──────────────────────────────────────────────────────
|
|
7
26
|
VARIANTS = {
|
|
8
27
|
primary: %w[
|
|
9
28
|
[--btn-bg:var(--sp-color-primary)]
|
|
@@ -56,6 +75,7 @@ module StimulusPlumbers
|
|
|
56
75
|
].freeze
|
|
57
76
|
}.freeze
|
|
58
77
|
|
|
78
|
+
# ── Type styles ───────────────────────────────────────────────────────
|
|
59
79
|
TYPES = {
|
|
60
80
|
default: %w[
|
|
61
81
|
rounded-(--sp-radius-md)
|
|
@@ -67,13 +87,13 @@ module StimulusPlumbers
|
|
|
67
87
|
rounded-(--sp-radius-md)
|
|
68
88
|
bg-(--sp-color-bg) text-(--btn-accent)
|
|
69
89
|
border border-(--btn-border)
|
|
70
|
-
hover:bg-(--btn-
|
|
90
|
+
hover:bg-(--btn-accent)/10
|
|
71
91
|
].freeze,
|
|
72
92
|
ghost: %w[
|
|
73
93
|
rounded-(--sp-radius-md)
|
|
74
94
|
bg-transparent text-(--btn-accent)
|
|
75
95
|
border border-transparent
|
|
76
|
-
hover:bg-(--btn-
|
|
96
|
+
hover:bg-(--btn-accent)/10
|
|
77
97
|
].freeze,
|
|
78
98
|
fab: %w[
|
|
79
99
|
rounded-(--sp-radius-full)
|
|
@@ -93,16 +113,17 @@ module StimulusPlumbers
|
|
|
93
113
|
rounded-(--sp-radius-md)
|
|
94
114
|
bg-(--sp-color-bg) text-(--btn-accent)
|
|
95
115
|
border border-dashed border-(--btn-border)
|
|
96
|
-
hover:bg-(--btn-
|
|
116
|
+
hover:bg-(--btn-accent)/10
|
|
97
117
|
].freeze,
|
|
98
118
|
card: %w[
|
|
99
119
|
rounded-(--sp-radius-md)
|
|
100
120
|
bg-(--sp-color-bg) text-(--btn-accent)
|
|
101
121
|
border border-(--btn-border) shadow-(--sp-shadow-xs)
|
|
102
|
-
hover:bg-(--btn-
|
|
122
|
+
hover:bg-(--btn-accent)/10
|
|
103
123
|
].freeze
|
|
104
124
|
}.freeze
|
|
105
125
|
|
|
126
|
+
# ── Sizes ─────────────────────────────────────────────────────────────
|
|
106
127
|
SIZES = {
|
|
107
128
|
xs: %w[h-7 px-(--sp-space-2) text-(length:--sp-text-xs)].freeze,
|
|
108
129
|
sm: %w[h-8 px-(--sp-space-3) text-(length:--sp-text-sm)].freeze,
|
|
@@ -111,23 +132,6 @@ module StimulusPlumbers
|
|
|
111
132
|
xl: %w[h-14 px-(--sp-space-6) text-(length:--sp-text-lg)].freeze
|
|
112
133
|
}.freeze
|
|
113
134
|
|
|
114
|
-
BASE = [
|
|
115
|
-
*Control::BASE,
|
|
116
|
-
"whitespace-nowrap",
|
|
117
|
-
"focus-visible:ring-(--btn-ring)"
|
|
118
|
-
].freeze
|
|
119
|
-
|
|
120
|
-
LAYOUT = %w[
|
|
121
|
-
inline-flex items-center justify-center gap-(--sp-space-2)
|
|
122
|
-
[&:not(:has(>span))]:aspect-square
|
|
123
|
-
[&:not(:has(>span))]:px-0
|
|
124
|
-
].freeze
|
|
125
|
-
|
|
126
|
-
CARD = %w[
|
|
127
|
-
inline-flex justify-start items-center flex-1 gap-(--sp-space-3) p-(--sp-space-4)
|
|
128
|
-
[&>:last-child:not(:first-child)]:ml-auto
|
|
129
|
-
].freeze
|
|
130
|
-
|
|
131
135
|
private
|
|
132
136
|
|
|
133
137
|
def button_classes(type: :default, variant: :primary, size: :md)
|
|
@@ -143,7 +147,7 @@ module StimulusPlumbers
|
|
|
143
147
|
end
|
|
144
148
|
|
|
145
149
|
def button_icon_classes
|
|
146
|
-
{ classes: klasses("size-(--sp-
|
|
150
|
+
{ classes: klasses("size-(--sp-icon-size-sm)", "stroke-current") }
|
|
147
151
|
end
|
|
148
152
|
end
|
|
149
153
|
end
|
|
@@ -4,7 +4,7 @@ module StimulusPlumbers
|
|
|
4
4
|
module Themes
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Calendar
|
|
7
|
-
GRID =
|
|
7
|
+
GRID = [].freeze
|
|
8
8
|
|
|
9
9
|
DAYS_OF_WEEK = %w[
|
|
10
10
|
grid grid-cols-7 text-center text-(length:--sp-text-xs)
|
|
@@ -16,41 +16,52 @@ module StimulusPlumbers
|
|
|
16
16
|
DAY = %w[
|
|
17
17
|
size-(--sp-calendar-day-size) rounded-(--sp-radius-md)
|
|
18
18
|
flex items-center justify-center text-(length:--sp-text-sm)
|
|
19
|
-
hover:bg-(--sp-color-muted) cursor-pointer
|
|
19
|
+
[&:is(button)]:hover:bg-(--sp-color-muted) [&:is(button)]:cursor-pointer
|
|
20
20
|
aria-[current=date]:font-bold
|
|
21
21
|
aria-selected:bg-(--sp-color-primary)
|
|
22
22
|
aria-selected:text-(--sp-color-primary-fg)
|
|
23
23
|
aria-selected:hover:bg-(--sp-color-primary)/90
|
|
24
24
|
aria-[hidden=true]:pointer-events-none
|
|
25
|
-
aria-[
|
|
25
|
+
aria-[disabled=true]:text-(--sp-color-muted-fg)
|
|
26
|
+
aria-[disabled=true]:opacity-40
|
|
27
|
+
aria-[disabled=true]:pointer-events-none
|
|
28
|
+
disabled:text-(--sp-color-muted-fg)
|
|
29
|
+
disabled:opacity-40
|
|
30
|
+
disabled:pointer-events-none
|
|
26
31
|
].freeze
|
|
27
32
|
|
|
28
|
-
QUARTER_GRID = %w[grid grid-cols-4].freeze
|
|
33
|
+
QUARTER_GRID = %w[grid grid-cols-4 gap-(--sp-space-1)].freeze
|
|
29
34
|
|
|
30
35
|
MONTHS_OF_YEAR = "contents"
|
|
31
36
|
|
|
32
37
|
MONTH = %w[
|
|
33
38
|
rounded-(--sp-radius-md) flex items-center justify-center
|
|
34
|
-
text-(length:--sp-text-sm) h-10 flex-1
|
|
39
|
+
text-(length:--sp-text-sm) h-10 flex-1 px-(--sp-space-2)
|
|
35
40
|
hover:bg-(--sp-color-muted) cursor-pointer
|
|
36
41
|
aria-selected:bg-(--sp-color-primary)
|
|
37
42
|
aria-selected:text-(--sp-color-primary-fg)
|
|
38
43
|
aria-selected:hover:bg-(--sp-color-primary)/90
|
|
39
|
-
aria-disabled:pointer-events-none aria-disabled:text-(--sp-color-disabled-fg)
|
|
40
44
|
aria-[current=month]:font-bold
|
|
45
|
+
aria-[disabled=true]:text-(--sp-color-muted-fg)
|
|
46
|
+
aria-[disabled=true]:opacity-40
|
|
47
|
+
aria-[disabled=true]:pointer-events-none
|
|
48
|
+
aria-[disabled=true]:hover:bg-transparent
|
|
41
49
|
].freeze
|
|
42
50
|
|
|
43
51
|
YEARS_OF_DECADE = "contents"
|
|
44
52
|
|
|
45
53
|
YEAR = %w[
|
|
46
54
|
rounded-(--sp-radius-md) flex items-center justify-center
|
|
47
|
-
text-(length:--sp-text-sm) h-10 flex-1
|
|
55
|
+
text-(length:--sp-text-sm) h-10 flex-1 px-(--sp-space-2)
|
|
48
56
|
hover:bg-(--sp-color-muted) cursor-pointer
|
|
49
57
|
aria-selected:bg-(--sp-color-primary)
|
|
50
58
|
aria-selected:text-(--sp-color-primary-fg)
|
|
51
59
|
aria-selected:hover:bg-(--sp-color-primary)/90
|
|
52
|
-
aria-disabled:pointer-events-none aria-disabled:text-(--sp-color-disabled-fg)
|
|
53
60
|
aria-[current=year]:font-bold
|
|
61
|
+
aria-[disabled=true]:text-(--sp-color-muted-fg)
|
|
62
|
+
aria-[disabled=true]:opacity-40
|
|
63
|
+
aria-[disabled=true]:pointer-events-none
|
|
64
|
+
aria-[disabled=true]:hover:bg-transparent
|
|
54
65
|
].freeze
|
|
55
66
|
|
|
56
67
|
private
|
|
@@ -80,21 +91,13 @@ module StimulusPlumbers
|
|
|
80
91
|
end
|
|
81
92
|
|
|
82
93
|
def calendar_day_classes(outside: false, **)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
*DAY,
|
|
86
|
-
*(outside ? %w[text-(--sp-color-disabled-fg)] : [])
|
|
87
|
-
)
|
|
88
|
-
}
|
|
94
|
+
extra = outside ? %w[text-(--sp-color-muted-fg)] : []
|
|
95
|
+
{ classes: klasses(*DAY, *extra) }
|
|
89
96
|
end
|
|
90
97
|
|
|
91
|
-
def calendar_month_classes(**)
|
|
92
|
-
{ classes: klasses(*MONTH) }
|
|
93
|
-
end
|
|
98
|
+
def calendar_month_classes(**) = { classes: klasses(*MONTH) }
|
|
94
99
|
|
|
95
|
-
def calendar_year_classes(**)
|
|
96
|
-
{ classes: klasses(*YEAR) }
|
|
97
|
-
end
|
|
100
|
+
def calendar_year_classes(**) = { classes: klasses(*YEAR) }
|
|
98
101
|
|
|
99
102
|
def calendar_quarter_grid_classes
|
|
100
103
|
{ classes: klasses(*QUARTER_GRID) }
|
|
@@ -5,6 +5,7 @@ module StimulusPlumbers
|
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Card
|
|
7
7
|
BASE = %w[
|
|
8
|
+
flex flex-col
|
|
8
9
|
rounded-(--sp-radius-md) border border-(--card-ring)
|
|
9
10
|
bg-(--sp-color-bg) shadow-(--sp-shadow-xs)
|
|
10
11
|
].freeze
|
|
@@ -21,7 +22,7 @@ module StimulusPlumbers
|
|
|
21
22
|
|
|
22
23
|
HEADER_BASE = %w[
|
|
23
24
|
flex items-center gap-(--sp-space-3)
|
|
24
|
-
px-(--sp-space-6)
|
|
25
|
+
px-(--sp-space-6) py-(--sp-space-6)
|
|
25
26
|
].freeze
|
|
26
27
|
|
|
27
28
|
ICON_BASE = %w[
|
|
@@ -33,12 +34,10 @@ module StimulusPlumbers
|
|
|
33
34
|
].freeze
|
|
34
35
|
|
|
35
36
|
BODY_BASE = %w[
|
|
36
|
-
px-(--sp-space-6)
|
|
37
|
+
px-(--sp-space-6) py-(--sp-space-3)
|
|
37
38
|
].freeze
|
|
38
39
|
|
|
39
|
-
ACTION_BASE = %w[
|
|
40
|
-
px-(--sp-space-6) pb-(--sp-space-6) pt-(--sp-space-4)
|
|
41
|
-
].freeze
|
|
40
|
+
ACTION_BASE = %w[w-full justify-start].freeze
|
|
42
41
|
|
|
43
42
|
private
|
|
44
43
|
|
|
@@ -4,8 +4,13 @@ module StimulusPlumbers
|
|
|
4
4
|
module Themes
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Combobox
|
|
7
|
+
# ── Container / popover ───────────────────────────────────────────────
|
|
8
|
+
CONTAINER = %w[relative].freeze
|
|
9
|
+
POPOVER = %w[absolute top-full left-0 min-w-full].freeze
|
|
10
|
+
|
|
11
|
+
# ── Trigger ───────────────────────────────────────────────────────────
|
|
7
12
|
TRIGGER = %w[
|
|
8
|
-
w-full rounded-(--sp-radius-md) border border-(--sp-color-muted-fg)
|
|
13
|
+
w-full rounded-(--sp-radius-md) border border-(--sp-color-muted-fg) hover:border-(--sp-color-fg)
|
|
9
14
|
px-(--sp-space-3) py-(--sp-space-2)
|
|
10
15
|
text-(length:--sp-text-sm) text-(--sp-color-fg) bg-(--sp-color-bg)
|
|
11
16
|
focus:outline-none focus:ring-2 focus:ring-(--sp-focus-ring-color)
|
|
@@ -13,7 +18,7 @@ module StimulusPlumbers
|
|
|
13
18
|
|
|
14
19
|
TRIGGER_GROUP = %w[
|
|
15
20
|
flex items-center gap-(--sp-space-2) overflow-hidden
|
|
16
|
-
rounded-(--sp-radius-md) border border-(--sp-color-muted-fg) bg-(--sp-color-bg)
|
|
21
|
+
rounded-(--sp-radius-md) border border-(--sp-color-muted-fg) hover:border-(--sp-color-fg) bg-(--sp-color-bg)
|
|
17
22
|
px-(--sp-space-3) py-(--sp-space-2)
|
|
18
23
|
focus-within:outline-none focus-within:ring-2 focus-within:ring-(--sp-focus-ring-color)
|
|
19
24
|
[&>input]:border-0 [&>input]:rounded-none
|
|
@@ -22,8 +27,9 @@ module StimulusPlumbers
|
|
|
22
27
|
[&>input]:focus:ring-0
|
|
23
28
|
].freeze
|
|
24
29
|
|
|
30
|
+
# ── Listbox / options ─────────────────────────────────────────────────
|
|
25
31
|
LISTBOX = %w[
|
|
26
|
-
py-(--sp-space-1) overflow-y-auto max-h-60
|
|
32
|
+
py-(--sp-space-1) overflow-y-auto max-h-60 min-h-(--sp-space-6)
|
|
27
33
|
].freeze
|
|
28
34
|
|
|
29
35
|
OPTION_BASE = %w[
|
|
@@ -44,6 +50,7 @@ module StimulusPlumbers
|
|
|
44
50
|
|
|
45
51
|
OPTION_GROUP = %w[py-(--sp-space-1)].freeze
|
|
46
52
|
|
|
53
|
+
# ── Typeahead states ──────────────────────────────────────────────────
|
|
47
54
|
TYPEAHEAD_LOADING = %w[
|
|
48
55
|
flex items-center justify-center
|
|
49
56
|
py-(--sp-space-2) text-(length:--sp-text-sm) text-(--sp-color-muted-fg)
|
|
@@ -54,20 +61,15 @@ module StimulusPlumbers
|
|
|
54
61
|
py-(--sp-space-2) text-(length:--sp-text-sm) text-(--sp-color-muted-fg)
|
|
55
62
|
].freeze
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
DATE_NAV_BTN = [
|
|
62
|
-
*Control::BASE,
|
|
63
|
-
"inline-flex items-center justify-center",
|
|
64
|
-
"size-(--sp-calendar-day-size) rounded-(--sp-radius-md)",
|
|
65
|
-
"text-(--sp-color-fg) hover:bg-(--sp-color-muted)",
|
|
66
|
-
"focus-visible:ring-(--sp-focus-ring-color)"
|
|
67
|
-
].freeze
|
|
64
|
+
# ── Time picker ───────────────────────────────────────────────────────
|
|
65
|
+
TIME = %w[flex gap-(--sp-space-2) overflow-hidden].freeze
|
|
66
|
+
TIME_DRUM_UNIT = %w[flex-1 min-w-0].freeze
|
|
67
|
+
TIME_DRUM_PERIOD = %w[shrink-0].freeze
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
# ── Date navigation ───────────────────────────────────────────────────
|
|
70
|
+
DATE_NAV = %w[flex items-center justify-between gap-(--sp-space-1) mb-(--sp-space-2)].freeze
|
|
71
|
+
DATE_NAV_BTN = %w[].freeze
|
|
72
|
+
DATE_NAV_TITLE = %w[flex-1 text-center].freeze
|
|
71
73
|
|
|
72
74
|
private
|
|
73
75
|
|
|
@@ -110,7 +112,7 @@ module StimulusPlumbers
|
|
|
110
112
|
end
|
|
111
113
|
|
|
112
114
|
def combobox_typeahead_loading_icon_classes
|
|
113
|
-
{ classes: klasses("size-(--sp-icon-size)", "animate-spin") }
|
|
115
|
+
{ classes: klasses("size-(--sp-icon-size-md)", "animate-spin") }
|
|
114
116
|
end
|
|
115
117
|
|
|
116
118
|
def combobox_typeahead_empty_classes
|
|
@@ -121,6 +123,10 @@ module StimulusPlumbers
|
|
|
121
123
|
{ classes: klasses(*TIME) }
|
|
122
124
|
end
|
|
123
125
|
|
|
126
|
+
def combobox_time_drum_classes(type: :unit)
|
|
127
|
+
{ classes: klasses(*(type == :period ? TIME_DRUM_PERIOD : TIME_DRUM_UNIT)) }
|
|
128
|
+
end
|
|
129
|
+
|
|
124
130
|
def combobox_date_navigation_classes
|
|
125
131
|
{ classes: klasses(*DATE_NAV) }
|
|
126
132
|
end
|
|
@@ -128,6 +134,10 @@ module StimulusPlumbers
|
|
|
128
134
|
def combobox_date_navigation_navigator_classes
|
|
129
135
|
{ classes: klasses(*DATE_NAV_BTN) }
|
|
130
136
|
end
|
|
137
|
+
|
|
138
|
+
def combobox_date_navigation_title_classes
|
|
139
|
+
{ classes: klasses(*DATE_NAV_TITLE) }
|
|
140
|
+
end
|
|
131
141
|
end
|
|
132
142
|
end
|
|
133
143
|
end
|