stimulus_plumbers_tailwind 0.3.3 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9538346c119b8c1b5ad69324b708e083393e2ff6c46bd777ff3b4f22833426f
4
- data.tar.gz: ba2636473fbf2f74b3286a09efb10a4f68d5d431236ff70a8f1bd12654feac37
3
+ metadata.gz: f14f719e9c94e67c1b76669ea4a0691c7929e9a2b7df04fda692ce3ea430c4bc
4
+ data.tar.gz: 161c3622b129cbcf3ee49bc304319c691cf09c8c754a01646bc608480b391029
5
5
  SHA512:
6
- metadata.gz: 70224de388f2e9236cdb877212d5aa81d2a386efc98060bfc0bad2c78be686768a6d54eb5647c9a2cb06cc5218bcaa700161dd43b53356e85b99f1d76c3b30d8
7
- data.tar.gz: 72d13eb1f2f751a7240a8af5d4faa47757f75157ab6806a0dd12245fe53f0f5f907d51d8b10508db0a592d7bb84772214c6483655c1e68a2529ead3b4b135f20
6
+ metadata.gz: 606d07453d71bc70cd71560c47ee12a028fbe4ab5ef3150d52024d61eef561f263c12221c73ed8689f56119b8f5b155099bad4526435f3614550b23f2934628c
7
+ data.tar.gz: c4d45c72794f1c0df3310e30f5a95cb3bc3c204c1298eca5c916f645fb530d1bfb4d5ee3ff24c828290ba6e6a75e5980e4d20853eae19b1692ee64007303d60f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,41 @@
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.0](https://github.com/ryancyq/stimulus-plumbers/compare/stimulus-plumbers-tailwind/v0.3.3..stimulus-plumbers-tailwind/v0.4.0) - 2026-06-14
7
+
8
+ ### Bug Fixes
9
+
10
+ - separate form field/choice rendering ([#92](https://github.com/ryancyq/stimulus-plumbers/issues/92)) - ([beedf5f](https://github.com/ryancyq/stimulus-plumbers/commit/beedf5f25849fd8e0411db69733bdb7afda99d9c)) - Ryan Chang
11
+ - redesign combobox + popover integration ([#93](https://github.com/ryancyq/stimulus-plumbers/issues/93)) - ([acffee6](https://github.com/ryancyq/stimulus-plumbers/commit/acffee6e8661daa9245223eb4c95df9d066ff452)) - Ryan Chang
12
+ - avatar image theme ([#102](https://github.com/ryancyq/stimulus-plumbers/issues/102)) - ([8135d9b](https://github.com/ryancyq/stimulus-plumbers/commit/8135d9bf03df72365b66a22d4c4bfad356c3007f)) - Ryan Chang
13
+ - button link with external url will have icon render by default ([#103](https://github.com/ryancyq/stimulus-plumbers/issues/103)) - ([0429cba](https://github.com/ryancyq/stimulus-plumbers/commit/0429cbab170d5a4a7a5009fe0f70023917521725)) - Ryan Chang
14
+ - action list / popover builder ([#105](https://github.com/ryancyq/stimulus-plumbers/issues/105)) - ([fc27045](https://github.com/ryancyq/stimulus-plumbers/commit/fc2704527cec4a8e3f5ea5119de33026c936defb)) - Ryan Chang
15
+ - button group builder ([#107](https://github.com/ryancyq/stimulus-plumbers/issues/107)) - ([c649df2](https://github.com/ryancyq/stimulus-plumbers/commit/c649df22162758958d4bfcd5a13f56c9bbb61eb6)) - Ryan Chang
16
+ - floating label for form inputs ([#109](https://github.com/ryancyq/stimulus-plumbers/issues/109)) - ([16c1c9b](https://github.com/ryancyq/stimulus-plumbers/commit/16c1c9ba2601dbbd9819be2272836a0f56b0b404)) - Ryan Chang
17
+ - calendar + combobox date ([#110](https://github.com/ryancyq/stimulus-plumbers/issues/110)) - ([d47065f](https://github.com/ryancyq/stimulus-plumbers/commit/d47065fc888bd81c2e72066dc98d061ff8a6e5a7)) - Ryan Chang
18
+ - action list with builder ([#111](https://github.com/ryancyq/stimulus-plumbers/issues/111)) - ([8ba6c3f](https://github.com/ryancyq/stimulus-plumbers/commit/8ba6c3f4a4c51d8e95c57fdde5e7ba499cc17e86)) - Ryan Chang
19
+ - icon helper + update doc ([#113](https://github.com/ryancyq/stimulus-plumbers/issues/113)) - ([301adf4](https://github.com/ryancyq/stimulus-plumbers/commit/301adf406102d2d98b8cbd65cb2e3f4f921b5a2e)) - Ryan Chang
20
+
21
+ ### Features
22
+
23
+ - form floating label ([#96](https://github.com/ryancyq/stimulus-plumbers/issues/96)) - ([13e9854](https://github.com/ryancyq/stimulus-plumbers/commit/13e985424cd2460820f5ae0e7d5c6debad6392e4)) - Ryan Chang
24
+ - button variant type ([#97](https://github.com/ryancyq/stimulus-plumbers/issues/97)) - ([c680077](https://github.com/ryancyq/stimulus-plumbers/commit/c680077f14df2aad943c84ed2559d87bcf41e12b)) - Ryan Chang
25
+ - calendar with days/months/years views ([#99](https://github.com/ryancyq/stimulus-plumbers/issues/99)) - ([fa530c8](https://github.com/ryancyq/stimulus-plumbers/commit/fa530c8eea38351e08cc27ad66aa6733fdb44f46)) - Ryan Chang
26
+ - button fab outline ([#104](https://github.com/ryancyq/stimulus-plumbers/issues/104)) - ([ba877d8](https://github.com/ryancyq/stimulus-plumbers/commit/ba877d8312fcb8362ccd287173af12651e6b7627)) - Ryan Chang
27
+
28
+ ### Style
29
+
30
+ - update component styling ([#89](https://github.com/ryancyq/stimulus-plumbers/issues/89)) - ([be240aa](https://github.com/ryancyq/stimulus-plumbers/commit/be240aa2a8e9a92b66c95086a8c5d0cfff067da4)) - Ryan Chang
31
+ - tailwind choice checkbox/radio ([#95](https://github.com/ryancyq/stimulus-plumbers/issues/95)) - ([1c56b75](https://github.com/ryancyq/stimulus-plumbers/commit/1c56b753596f2d28b4d2320004ae32046e474f8a)) - Ryan Chang
32
+ - fix card style across button/link/checkbox/radio ([#108](https://github.com/ryancyq/stimulus-plumbers/issues/108)) - ([6c6f2cc](https://github.com/ryancyq/stimulus-plumbers/commit/6c6f2ccfaca8bffdf186062ad73c38ebee5bdd21)) - Ryan Chang
33
+
34
+ ### Tests
35
+
36
+ - add snapshots coverage ([#91](https://github.com/ryancyq/stimulus-plumbers/issues/91)) - ([bbd6022](https://github.com/ryancyq/stimulus-plumbers/commit/bbd6022ad37af9a1553971b6a4a928786eb7c421)) - Ryan Chang
37
+ - address unit/a11y test gaps ([#101](https://github.com/ryancyq/stimulus-plumbers/issues/101)) - ([68f30e1](https://github.com/ryancyq/stimulus-plumbers/commit/68f30e1ddd1b11a6ab315beb40eb55a4a2946001)) - Ryan Chang
38
+ - update sandbox view and snapshot spec ([#120](https://github.com/ryancyq/stimulus-plumbers/issues/120)) - ([d331248](https://github.com/ryancyq/stimulus-plumbers/commit/d331248a082bbc598cad35d38ab16dbde3563c19)) - Ryan Chang
39
+
5
40
  ---
6
41
  ## [0.3.3](https://github.com/ryancyq/stimulus-plumbers/compare/stimulus-plumbers-tailwind/v0.3.2..stimulus-plumbers-tailwind/v0.3.3) - 2026-05-26
7
42
 
@@ -4,7 +4,7 @@ module StimulusPlumbers
4
4
  module Themes
5
5
  module Tailwind
6
6
  module Avatar
7
- COLORS = {
7
+ VARIANTS = {
8
8
  amber: "text-white bg-amber-600",
9
9
  lime: "text-white bg-lime-600",
10
10
  sky: "text-white bg-sky-600",
@@ -25,27 +25,35 @@ module StimulusPlumbers
25
25
  lg: "size-(--sp-avatar-size-lg)"
26
26
  }.freeze
27
27
 
28
- BASE = %w[rounded-(--sp-radius-full) overflow-hidden inline-flex items-center justify-center].freeze
28
+ BASE = %w[
29
+ rounded-(--sp-radius-full)
30
+ overflow-hidden
31
+ inline-flex items-center justify-center
32
+ ].freeze
29
33
 
30
- def avatar_colors
31
- COLORS
34
+ def avatar_variants
35
+ VARIANTS
32
36
  end
33
37
 
34
- def avatar_color_range
35
- COLORS.values
38
+ def avatar_variant_range
39
+ VARIANTS.values
36
40
  end
37
41
 
38
42
  private
39
43
 
40
- def avatar_classes(size: :md, color: nil)
44
+ def avatar_classes(size: :md, variant: nil)
41
45
  {
42
46
  classes: klasses(
43
47
  SIZES.fetch(size, SIZES[:md]),
44
- COLORS.fetch(color, nil),
48
+ VARIANTS.fetch(variant, nil),
45
49
  *BASE
46
50
  )
47
51
  }
48
52
  end
53
+
54
+ def avatar_image_classes
55
+ { classes: "w-full h-full object-cover" }
56
+ end
49
57
  end
50
58
  end
51
59
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusPlumbers
4
+ module Themes
5
+ module Tailwind
6
+ module Button
7
+ module Group
8
+ LAYOUTS = {
9
+ inline: %w[
10
+ inline-flex rounded-(--sp-radius-md) shadow-(--sp-shadow-xs)
11
+ [&>*:not(:first-child)]:-ml-px
12
+ [&>*]:rounded-none
13
+ [&>*:first-child]:rounded-s-(--sp-radius-md)
14
+ [&>*:last-child]:rounded-e-(--sp-radius-md)
15
+ ].freeze,
16
+ stacked: %w[
17
+ flex flex-col rounded-(--sp-radius-md) shadow-(--sp-shadow-xs)
18
+ [&>*:not(:first-child)]:-mt-px
19
+ [&>*]:rounded-none
20
+ [&>*:first-child]:rounded-t-(--sp-radius-md)
21
+ [&>*:last-child]:rounded-b-(--sp-radius-md)
22
+ ].freeze
23
+ }.freeze
24
+
25
+ private
26
+
27
+ def button_group_classes(layout: :inline)
28
+ {
29
+ classes: klasses(*LAYOUTS.fetch(layout, LAYOUTS[:inline]))
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -6,38 +6,100 @@ module StimulusPlumbers
6
6
  module Button
7
7
  VARIANTS = {
8
8
  primary: %w[
9
- bg-(--sp-color-primary)
10
- text-(--sp-color-primary-fg)
11
- hover:bg-(--sp-color-primary)/90
12
- focus-visible:ring-(--sp-focus-ring-color)
9
+ [--btn-bg:var(--sp-color-primary)]
10
+ [--btn-fg:var(--sp-color-primary-fg)]
11
+ [--btn-accent:var(--sp-color-primary)]
12
+ [--btn-border:var(--sp-color-primary-border)]
13
+ [--btn-ring:var(--sp-color-primary-ring)]
13
14
  ].freeze,
14
15
  secondary: %w[
15
- bg-(--sp-color-muted)
16
- text-(--sp-color-fg)
17
- hover:bg-(--sp-color-border)
16
+ [--btn-bg:var(--sp-color-secondary)]
17
+ [--btn-fg:var(--sp-color-secondary-fg)]
18
+ [--btn-accent:var(--sp-color-secondary)]
19
+ [--btn-border:var(--sp-color-secondary-border)]
20
+ [--btn-ring:var(--sp-color-secondary-ring)]
18
21
  ].freeze,
19
- outline: %w[
20
- border border-(--sp-color-border)
21
- bg-transparent
22
- text-(--sp-color-fg)
23
- hover:bg-(--sp-color-muted)
22
+ tertiary: %w[
23
+ [--btn-bg:var(--sp-color-muted)]
24
+ [--btn-fg:var(--sp-color-muted-fg)]
25
+ [--btn-accent:var(--sp-color-fg)]
26
+ [--btn-border:var(--sp-color-muted-border)]
27
+ [--btn-ring:var(--sp-color-muted-ring)]
28
+ ].freeze,
29
+ success: %w[
30
+ [--btn-bg:var(--sp-color-success)]
31
+ [--btn-fg:var(--sp-color-success-fg)]
32
+ [--btn-accent:var(--sp-color-success)]
33
+ [--btn-border:var(--sp-color-success-border)]
34
+ [--btn-ring:var(--sp-color-success-ring)]
24
35
  ].freeze,
25
36
  destructive: %w[
26
- bg-(--sp-color-destructive)
27
- text-(--sp-color-destructive-fg)
28
- hover:bg-(--sp-color-destructive)/90
37
+ [--btn-bg:var(--sp-color-destructive)]
38
+ [--btn-fg:var(--sp-color-destructive-fg)]
39
+ [--btn-accent:var(--sp-color-destructive)]
40
+ [--btn-border:var(--sp-color-destructive-border)]
41
+ [--btn-ring:var(--sp-color-destructive-ring)]
42
+ ].freeze,
43
+ warning: %w[
44
+ [--btn-bg:var(--sp-color-warning)]
45
+ [--btn-fg:var(--sp-color-warning-fg)]
46
+ [--btn-accent:var(--sp-color-warning)]
47
+ [--btn-border:var(--sp-color-warning-border)]
48
+ [--btn-ring:var(--sp-color-warning-ring)]
49
+ ].freeze,
50
+ info: %w[
51
+ [--btn-bg:var(--sp-color-info)]
52
+ [--btn-fg:var(--sp-color-info-fg)]
53
+ [--btn-accent:var(--sp-color-info)]
54
+ [--btn-border:var(--sp-color-info-border)]
55
+ [--btn-ring:var(--sp-color-info-ring)]
56
+ ].freeze
57
+ }.freeze
58
+
59
+ TYPES = {
60
+ default: %w[
61
+ rounded-(--sp-radius-md)
62
+ bg-(--btn-bg) text-(--btn-fg)
63
+ border border-(--btn-border)
64
+ hover:bg-(--btn-bg)/90
65
+ ].freeze,
66
+ outline: %w[
67
+ rounded-(--sp-radius-md)
68
+ bg-(--sp-color-bg) text-(--btn-accent)
69
+ border border-(--btn-border)
70
+ hover:bg-(--btn-bg)/10
71
+ ].freeze,
72
+ ghost: %w[
73
+ rounded-(--sp-radius-md)
74
+ bg-transparent text-(--btn-accent)
75
+ border border-transparent
76
+ hover:bg-(--btn-bg)/10
29
77
  ].freeze,
30
- ghost: %w[hover:bg-(--sp-color-muted) text-(--sp-color-fg)].freeze,
31
- link: %w[text-(--sp-color-primary) underline-offset-4 hover:underline].freeze,
32
78
  fab: %w[
33
- rounded-full shadow-lg
34
- bg-(--sp-color-primary) text-(--sp-color-primary-fg)
35
- hover:bg-(--sp-color-primary)/90 hover:shadow-xl
79
+ rounded-(--sp-radius-full)
80
+ bg-(--btn-bg) text-(--btn-fg)
81
+ border border-(--btn-border)
82
+ shadow-(--sp-shadow-lg)
83
+ hover:bg-(--btn-bg)/90 hover:shadow-(--sp-shadow-xl)
84
+ ].freeze,
85
+ fab_outline: %w[
86
+ rounded-(--sp-radius-full)
87
+ bg-transparent text-(--btn-accent)
88
+ border border-(--btn-border)
89
+ shadow-(--sp-shadow-lg)
90
+ hover:bg-(--btn-bg) hover:text-(--btn-fg) hover:shadow-(--sp-shadow-xl)
36
91
  ].freeze,
37
92
  dashed: %w[
38
- border border-dashed border-(--sp-color-border)
39
- bg-transparent text-(--sp-color-fg)
40
- hover:bg-(--sp-color-muted)
93
+ rounded-(--sp-radius-md)
94
+ bg-(--sp-color-bg) text-(--btn-accent)
95
+ border border-dashed border-(--btn-border)
96
+ hover:bg-(--btn-bg)/10
97
+ ].freeze,
98
+ card: %w[
99
+ rounded-(--sp-radius-md)
100
+ bg-(--sp-color-bg) text-(--btn-accent)
101
+ border border-(--btn-border) shadow-(--sp-shadow-xs)
102
+ hover:bg-(--btn-bg)/10
41
103
  ].freeze
42
104
  }.freeze
43
105
 
@@ -49,49 +111,33 @@ module StimulusPlumbers
49
111
  xl: %w[h-14 px-(--sp-space-6) text-(length:--sp-text-lg)].freeze
50
112
  }.freeze
51
113
 
52
- FLEX_ALIGN = {
53
- row: {
54
- left: "justify-start",
55
- center: %w[justify-center items-center].freeze,
56
- right: "justify-end",
57
- top: "items-start",
58
- bottom: "items-end"
59
- }.freeze,
60
- col: {
61
- top: "justify-start",
62
- center: %w[justify-center items-center].freeze,
63
- bottom: "justify-end",
64
- left: "items-start",
65
- right: "items-end"
66
- }.freeze
67
- }.freeze
114
+ BASE = [
115
+ *Control::BASE,
116
+ "whitespace-nowrap",
117
+ "focus-visible:ring-(--btn-ring)"
118
+ ].freeze
68
119
 
69
- BASE = %w[
70
- inline-flex items-center justify-center gap-(--sp-space-2) font-medium
71
- rounded-(--sp-radius-md) transition-colors
72
- focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2
73
- disabled:pointer-events-none disabled:opacity-50
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
74
124
  ].freeze
75
125
 
76
- GROUP_BASE = %w[flex gap-(--sp-space-2)].freeze
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
77
130
 
78
131
  private
79
132
 
80
- def button_classes(variant: :primary, size: :md)
133
+ def button_classes(type: :default, variant: :primary, size: :md)
81
134
  {
82
135
  classes: klasses(
83
136
  *BASE,
84
- *VARIANTS.fetch(variant, []),
85
- *SIZES.fetch(size, [])
86
- )
87
- }
88
- end
89
-
90
- def button_group_classes(alignment: :left, direction: :row)
91
- {
92
- classes: klasses(
93
- *GROUP_BASE,
94
- *Array(FLEX_ALIGN.dig(direction, alignment))
137
+ *(type == :card ? CARD : LAYOUT),
138
+ *VARIANTS.fetch(variant, VARIANTS[:primary]),
139
+ *TYPES.fetch(type, TYPES[:default]),
140
+ *(type == :card ? [] : SIZES.fetch(size, []))
95
141
  )
96
142
  }
97
143
  end
@@ -21,17 +21,36 @@ module StimulusPlumbers
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
+ aria-[hidden=true]:pointer-events-none
25
+ aria-[hidden=true]:hover:bg-transparent
24
26
  ].freeze
25
27
 
26
- NAV = %w[flex items-center justify-between gap-(--sp-space-1) mb-(--sp-space-2)].freeze
28
+ QUARTER_GRID = %w[grid grid-cols-4].freeze
27
29
 
28
- NAV_BTN = %w[
29
- inline-flex items-center justify-center
30
- size-(--sp-calendar-day-size) rounded-(--sp-radius-md)
31
- text-(--sp-color-fg) hover:bg-(--sp-color-muted)
32
- focus-visible:outline-none focus-visible:ring-2
33
- focus-visible:ring-(--sp-focus-ring-color)
34
- disabled:pointer-events-none disabled:opacity-50
30
+ MONTHS_OF_YEAR = "contents"
31
+
32
+ MONTH = %w[
33
+ rounded-(--sp-radius-md) flex items-center justify-center
34
+ text-(length:--sp-text-sm) h-10 flex-1
35
+ hover:bg-(--sp-color-muted) cursor-pointer
36
+ aria-selected:bg-(--sp-color-primary)
37
+ aria-selected:text-(--sp-color-primary-fg)
38
+ aria-selected:hover:bg-(--sp-color-primary)/90
39
+ aria-disabled:pointer-events-none aria-disabled:text-(--sp-color-disabled-fg)
40
+ aria-[current=month]:font-bold
41
+ ].freeze
42
+
43
+ YEARS_OF_DECADE = "contents"
44
+
45
+ YEAR = %w[
46
+ rounded-(--sp-radius-md) flex items-center justify-center
47
+ text-(length:--sp-text-sm) h-10 flex-1
48
+ hover:bg-(--sp-color-muted) cursor-pointer
49
+ aria-selected:bg-(--sp-color-primary)
50
+ aria-selected:text-(--sp-color-primary-fg)
51
+ aria-selected:hover:bg-(--sp-color-primary)/90
52
+ aria-disabled:pointer-events-none aria-disabled:text-(--sp-color-disabled-fg)
53
+ aria-[current=year]:font-bold
35
54
  ].freeze
36
55
 
37
56
  private
@@ -44,29 +63,41 @@ module StimulusPlumbers
44
63
  { classes: klasses(*DAYS_OF_WEEK) }
45
64
  end
46
65
 
47
- def calendar_week_classes
48
- { classes: "contents" }
49
- end
50
-
51
66
  def calendar_days_of_month_classes
52
67
  { classes: klasses(*DAYS_OF_MONTH) }
53
68
  end
54
69
 
55
- def calendar_day_classes(outside: false)
70
+ def calendar_months_of_year_classes
71
+ { classes: MONTHS_OF_YEAR }
72
+ end
73
+
74
+ def calendar_years_of_decade_classes
75
+ { classes: YEARS_OF_DECADE }
76
+ end
77
+
78
+ def calendar_row_classes
79
+ { classes: "contents" }
80
+ end
81
+
82
+ def calendar_day_classes(outside: false, **)
56
83
  {
57
84
  classes: klasses(
58
85
  *DAY,
59
- *(outside ? %w[text-(--sp-color-muted-fg) opacity-50] : [])
86
+ *(outside ? %w[text-(--sp-color-disabled-fg)] : [])
60
87
  )
61
88
  }
62
89
  end
63
90
 
64
- def calendar_navigation_classes
65
- { classes: klasses(*NAV) }
91
+ def calendar_month_classes(**)
92
+ { classes: klasses(*MONTH) }
93
+ end
94
+
95
+ def calendar_year_classes(**)
96
+ { classes: klasses(*YEAR) }
66
97
  end
67
98
 
68
- def calendar_navigation_navigator_classes
69
- { classes: klasses(*NAV_BTN) }
99
+ def calendar_quarter_grid_classes
100
+ { classes: klasses(*QUARTER_GRID) }
70
101
  end
71
102
  end
72
103
  end
@@ -5,19 +5,52 @@ module StimulusPlumbers
5
5
  module Tailwind
6
6
  module Card
7
7
  BASE = %w[
8
- rounded-(--sp-radius-lg) border border-(--sp-color-border)
9
- bg-(--sp-color-bg) shadow-(--sp-shadow-sm)
8
+ rounded-(--sp-radius-md) border border-(--card-ring)
9
+ bg-(--sp-color-bg) shadow-(--sp-shadow-xs)
10
+ ].freeze
11
+
12
+ VARIANTS = {
13
+ primary: %w[[--card-ring:var(--sp-color-primary)]].freeze,
14
+ secondary: %w[[--card-ring:var(--sp-color-secondary)]].freeze,
15
+ tertiary: %w[[--card-ring:var(--sp-color-muted-fg)]].freeze,
16
+ success: %w[[--card-ring:var(--sp-color-success)]].freeze,
17
+ destructive: %w[[--card-ring:var(--sp-color-destructive)]].freeze,
18
+ warning: %w[[--card-ring:var(--sp-color-warning)]].freeze,
19
+ info: %w[[--card-ring:var(--sp-color-info)]].freeze
20
+ }.freeze
21
+
22
+ HEADER_BASE = %w[
23
+ flex items-center gap-(--sp-space-3)
24
+ px-(--sp-space-6) pt-(--sp-space-6)
25
+ ].freeze
26
+
27
+ ICON_BASE = %w[
28
+ size-(--sp-space-6) shrink-0 stroke-current text-(--sp-color-muted-fg)
29
+ ].freeze
30
+
31
+ TITLE_BASE = %w[
32
+ text-(length:--sp-text-base) font-semibold text-(--sp-color-fg)
33
+ ].freeze
34
+
35
+ BODY_BASE = %w[
36
+ px-(--sp-space-6) pt-(--sp-space-3)
37
+ ].freeze
38
+
39
+ ACTION_BASE = %w[
40
+ px-(--sp-space-6) pb-(--sp-space-6) pt-(--sp-space-4)
10
41
  ].freeze
11
42
 
12
43
  private
13
44
 
14
- def card_classes
15
- { classes: klasses(*BASE) }
45
+ def card_classes(variant: :tertiary)
46
+ { classes: klasses(*VARIANTS.fetch(variant, VARIANTS[:tertiary]), *BASE) }
16
47
  end
17
48
 
18
- def card_section_classes
19
- { classes: klasses("p-(--sp-space-6)") }
20
- end
49
+ def card_header_classes = { classes: klasses(*HEADER_BASE) }
50
+ def card_icon_classes = { classes: klasses(*ICON_BASE) }
51
+ def card_title_classes = { classes: klasses(*TITLE_BASE) }
52
+ def card_body_classes = { classes: klasses(*BODY_BASE) }
53
+ def card_action_classes = { classes: klasses(*ACTION_BASE) }
21
54
  end
22
55
  end
23
56
  end
@@ -9,14 +9,6 @@ module StimulusPlumbers
9
9
  px-(--sp-space-3) py-(--sp-space-2)
10
10
  text-(length:--sp-text-sm) text-(--sp-color-fg) bg-(--sp-color-bg)
11
11
  focus:outline-none focus:ring-2 focus:ring-(--sp-focus-ring-color)
12
- [.sp-form-combobox_&]:border-0 [.sp-form-combobox_&]:rounded-none
13
- [.sp-form-combobox_&]:px-0 [.sp-form-combobox_&]:py-0
14
- [.sp-form-combobox_&]:bg-transparent [.sp-form-combobox_&]:shadow-none
15
- [.sp-form-combobox_&]:focus:ring-0
16
- [.sp-combobox-group_&]:border-0 [.sp-combobox-group_&]:rounded-none
17
- [.sp-combobox-group_&]:px-0 [.sp-combobox-group_&]:py-0
18
- [.sp-combobox-group_&]:bg-transparent [.sp-combobox-group_&]:shadow-none
19
- [.sp-combobox-group_&]:focus:ring-0
20
12
  ].freeze
21
13
 
22
14
  TRIGGER_GROUP = %w[
@@ -24,9 +16,10 @@ module StimulusPlumbers
24
16
  rounded-(--sp-radius-md) border border-(--sp-color-muted-fg) bg-(--sp-color-bg)
25
17
  px-(--sp-space-3) py-(--sp-space-2)
26
18
  focus-within:outline-none focus-within:ring-2 focus-within:ring-(--sp-focus-ring-color)
27
- sp-combobox-group
28
- [.sp-form-combobox_&]:border-0 [.sp-form-combobox_&]:rounded-none
29
- [.sp-form-combobox_&]:focus-within:ring-0
19
+ [&>input]:border-0 [&>input]:rounded-none
20
+ [&>input]:px-0 [&>input]:py-0
21
+ [&>input]:bg-transparent [&>input]:shadow-none
22
+ [&>input]:focus:ring-0
30
23
  ].freeze
31
24
 
32
25
  LISTBOX = %w[
@@ -63,8 +56,29 @@ module StimulusPlumbers
63
56
 
64
57
  TIME = %w[flex gap-(--sp-space-2) overflow-hidden].freeze
65
58
 
59
+ DATE_NAV = %w[flex items-center justify-between gap-(--sp-space-1) mb-(--sp-space-2)].freeze
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
68
+
69
+ CONTAINER = %w[relative].freeze
70
+ POPOVER = %w[absolute top-full left-0 min-w-full].freeze
71
+
66
72
  private
67
73
 
74
+ def combobox_classes
75
+ { classes: klasses(*CONTAINER) }
76
+ end
77
+
78
+ def combobox_popover_classes
79
+ { classes: klasses(*POPOVER) }
80
+ end
81
+
68
82
  def combobox_trigger_classes
69
83
  { classes: klasses(*TRIGGER) }
70
84
  end
@@ -95,6 +109,10 @@ module StimulusPlumbers
95
109
  { classes: klasses(*TYPEAHEAD_LOADING) }
96
110
  end
97
111
 
112
+ def combobox_typeahead_loading_icon_classes
113
+ { classes: klasses("size-(--sp-icon-size)", "animate-spin") }
114
+ end
115
+
98
116
  def combobox_typeahead_empty_classes
99
117
  { classes: klasses(*TYPEAHEAD_EMPTY) }
100
118
  end
@@ -102,6 +120,14 @@ module StimulusPlumbers
102
120
  def combobox_time_classes
103
121
  { classes: klasses(*TIME) }
104
122
  end
123
+
124
+ def combobox_date_navigation_classes
125
+ { classes: klasses(*DATE_NAV) }
126
+ end
127
+
128
+ def combobox_date_navigation_navigator_classes
129
+ { classes: klasses(*DATE_NAV_BTN) }
130
+ end
105
131
  end
106
132
  end
107
133
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusPlumbers
4
+ module Themes
5
+ module Tailwind
6
+ module Control
7
+ BASE = %w[
8
+ font-medium transition-colors
9
+ focus-visible:outline-none
10
+ focus-visible:ring-(length:--sp-focus-ring-width)
11
+ focus-visible:ring-offset-(length:--sp-focus-ring-offset)
12
+ disabled:pointer-events-none disabled:opacity-50
13
+ ].freeze
14
+ end
15
+ end
16
+ end
17
+ end