stimulus_plumbers_tailwind 0.3.3 → 0.4.2

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.
@@ -4,11 +4,24 @@ module StimulusPlumbers
4
4
  module Themes
5
5
  module Tailwind
6
6
  module Layout
7
- DIVIDER_SEPARATOR = %w[border-t border-(--sp-color-border) my-(--sp-space-1)].freeze
8
- DIVIDER = %w[flex items-center gap-(--sp-space-3)].freeze
9
- DIVIDER_LABEL = %w[text-(length:--sp-text-sm) text-(--sp-color-fg-muted) whitespace-nowrap font-medium].freeze
7
+ # ── Divider ───────────────────────────────────────────────────────────
8
+ DIVIDER = %w[w-full flex items-center gap-(--sp-space-3)].freeze
9
+ DIVIDER_SEPARATOR = %w[flex-1 h-px bg-(--sp-color-border) border-0].freeze
10
+ DIVIDER_LABEL = %w[text-(length:--sp-text-sm) text-(--sp-color-muted-fg) whitespace-nowrap font-medium].freeze
11
+
12
+ # ── Popover ───────────────────────────────────────────────────────────
13
+ POPOVER_WRAPPER = %w[relative inline-block].freeze
14
+ POPOVER_TRIGGER = [
15
+ *Control::BASE,
16
+ "inline-flex items-center justify-center gap-(--sp-space-2)",
17
+ "rounded-(--sp-radius-md)",
18
+ "focus-visible:ring-(--sp-focus-ring-color)",
19
+ "border border-(--sp-color-border) bg-transparent text-(--sp-color-fg)",
20
+ "hover:bg-(--sp-color-muted)",
21
+ "h-9 px-(--sp-space-4) py-(--sp-space-2) text-(length:--sp-text-sm)"
22
+ ].freeze
10
23
  POPOVER = %w[
11
- rounded-(--sp-radius-lg) border border-(--sp-color-border)
24
+ rounded-(--sp-radius-md) border border-(--sp-color-border)
12
25
  bg-(--sp-color-bg) shadow-(--sp-shadow-md) z-(--sp-z-popover)
13
26
  ].freeze
14
27
 
@@ -26,6 +39,14 @@ module StimulusPlumbers
26
39
  { classes: klasses(*DIVIDER_LABEL) }
27
40
  end
28
41
 
42
+ def popover_wrapper_classes
43
+ { classes: klasses(*POPOVER_WRAPPER) }
44
+ end
45
+
46
+ def popover_trigger_classes
47
+ { classes: klasses(*POPOVER_TRIGGER) }
48
+ end
49
+
29
50
  def popover_classes
30
51
  { classes: klasses(*POPOVER) }
31
52
  end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusPlumbers
4
+ module Themes
5
+ module Tailwind
6
+ module Link
7
+ # ── Type styles ───────────────────────────────────────────────────────
8
+ BASE = [
9
+ *Control::BASE,
10
+ "inline-flex items-center gap-(--sp-space-1)",
11
+ "text-(--link-color)",
12
+ "hover:underline",
13
+ "focus-visible:ring-(--link-ring)"
14
+ ].freeze
15
+
16
+ BUTTON = [
17
+ *Control::BASE,
18
+ "whitespace-nowrap",
19
+ "inline-flex items-center justify-center gap-(--sp-space-2)",
20
+ "h-9 px-(--sp-space-4) text-(length:--sp-text-base)",
21
+ "[&:not(:has(>span))]:aspect-square",
22
+ "[&:not(:has(>span))]:px-0",
23
+ "rounded-(--sp-radius-md)",
24
+ "bg-(--sp-color-bg) text-(--link-color)",
25
+ "border border-(--link-color)",
26
+ "hover:bg-(--link-bg)/10",
27
+ "focus-visible:ring-(--link-ring)"
28
+ ].freeze
29
+
30
+ CARD = [
31
+ *Control::BASE,
32
+ "whitespace-nowrap",
33
+ *Button::CARD,
34
+ "rounded-(--sp-radius-md)",
35
+ "bg-(--sp-color-bg) text-(--link-color)",
36
+ "border border-(--link-color) shadow-(--sp-shadow-xs)",
37
+ "hover:bg-(--link-bg)/10",
38
+ "focus-visible:ring-(--link-ring)"
39
+ ].freeze
40
+
41
+ # ── Color tokens ──────────────────────────────────────────────────────
42
+ VARIANTS = {
43
+ default: %w[
44
+ [--link-color:var(--sp-color-primary)]
45
+ [--link-ring:var(--sp-color-primary)]
46
+ [--link-bg:var(--sp-color-primary)]
47
+ ].freeze,
48
+ success: %w[
49
+ [--link-color:var(--sp-color-success)]
50
+ [--link-ring:var(--sp-color-success-ring)]
51
+ [--link-bg:var(--sp-color-success)]
52
+ ].freeze,
53
+ destructive: %w[
54
+ [--link-color:var(--sp-color-destructive)]
55
+ [--link-ring:var(--sp-color-destructive)]
56
+ [--link-bg:var(--sp-color-destructive)]
57
+ ].freeze,
58
+ warning: %w[
59
+ [--link-color:var(--sp-color-warning)]
60
+ [--link-ring:var(--sp-color-warning-ring)]
61
+ [--link-bg:var(--sp-color-warning)]
62
+ ].freeze,
63
+ info: %w[
64
+ [--link-color:var(--sp-color-info)]
65
+ [--link-ring:var(--sp-color-info-ring)]
66
+ [--link-bg:var(--sp-color-info)]
67
+ ].freeze
68
+ }.freeze
69
+
70
+ private
71
+
72
+ def link_classes(type: :default, variant: :default)
73
+ variant_classes = VARIANTS.fetch(variant, VARIANTS[:default])
74
+ case type
75
+ when :button then { classes: klasses(*BUTTON, *variant_classes) }
76
+ when :card then { classes: klasses(*CARD, *variant_classes) }
77
+ else { classes: klasses(*BASE, *variant_classes) }
78
+ end
79
+ end
80
+
81
+ def link_icon_classes
82
+ { classes: klasses("size-(--sp-icon-size-sm)", "stroke-current") }
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusPlumbers
4
+ module Themes
5
+ module Tailwind
6
+ module List
7
+ # ── Section ───────────────────────────────────────────────────────────
8
+ SECTION_TITLE_BASE = %w[
9
+ block px-(--sp-space-2) pb-(--sp-space-1)
10
+ text-(length:--sp-text-xs) font-semibold uppercase tracking-wider
11
+ text-(--sp-color-muted-fg)
12
+ ].freeze
13
+
14
+ SECTION_DESCRIPTION_BASE = %w[
15
+ block px-(--sp-space-2) pb-(--sp-space-1)
16
+ text-(length:--sp-text-xs) text-(--sp-color-muted-fg)
17
+ ].freeze
18
+
19
+ # ── Item ──────────────────────────────────────────────────────────────
20
+ ITEM_BASE = [
21
+ *Control::BASE,
22
+ "flex items-center gap-(--sp-space-2) w-full",
23
+ "px-(--sp-space-2) py-(--sp-space-1)",
24
+ "rounded-(--sp-radius-sm) text-(length:--sp-text-sm)",
25
+ "cursor-pointer select-none",
26
+ "text-(--sp-color-fg)",
27
+ "focus-visible:ring-(--sp-color-primary-ring)",
28
+ "hover:bg-(--sp-color-muted) focus:bg-(--sp-color-muted) focus:text-(--sp-color-fg)",
29
+ "aria-[current]:bg-(--sp-color-primary)/10 aria-[current]:text-(--sp-color-primary)"
30
+ ].freeze
31
+
32
+ ITEM_CONTENT_BASE = %w[
33
+ flex flex-col flex-1 min-w-0
34
+ ].freeze
35
+
36
+ ITEM_TITLE_BASE = %w[
37
+ text-(length:--sp-text-sm) font-medium text-(--sp-color-fg)
38
+ ].freeze
39
+
40
+ ITEM_DESCRIPTION_BASE = %w[
41
+ text-(length:--sp-text-xs) text-(--sp-color-muted-fg)
42
+ ].freeze
43
+
44
+ private
45
+
46
+ def list_classes
47
+ { classes: klasses("py-(--sp-space-1)") }
48
+ end
49
+
50
+ def list_section_classes
51
+ { classes: klasses("py-(--sp-space-2)") }
52
+ end
53
+
54
+ def list_section_title_classes
55
+ { classes: klasses(*SECTION_TITLE_BASE) }
56
+ end
57
+
58
+ def list_section_description_classes
59
+ { classes: klasses(*SECTION_DESCRIPTION_BASE) }
60
+ end
61
+
62
+ def list_item_classes
63
+ { classes: klasses(*ITEM_BASE) }
64
+ end
65
+
66
+ def list_item_icon_classes
67
+ { classes: klasses("size-(--sp-icon-size-sm)", "stroke-current") }
68
+ end
69
+
70
+ def list_item_content_classes
71
+ { classes: klasses(*ITEM_CONTENT_BASE) }
72
+ end
73
+
74
+ def list_item_title_classes
75
+ { classes: klasses(*ITEM_TITLE_BASE) }
76
+ end
77
+
78
+ def list_item_description_classes
79
+ { classes: klasses(*ITEM_DESCRIPTION_BASE) }
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusPlumbers
4
+ module Themes
5
+ module Tailwind
6
+ module Timeline
7
+ module Group
8
+ WRAPPER = %w[space-y-4].freeze
9
+ SECTION = %w[
10
+ p-4
11
+ bg-(--sp-color-bg-muted)
12
+ border border-(--sp-color-border)
13
+ rounded-lg
14
+ ].freeze
15
+ DATE = %w[text-base font-semibold text-(--sp-color-fg)].freeze
16
+ LIST = %w[mt-3 divide-y divide-(--sp-color-border)].freeze
17
+
18
+ private
19
+
20
+ def timeline_group_classes = { classes: klasses(WRAPPER) }
21
+ def timeline_group_section_classes = { classes: klasses(SECTION) }
22
+ def timeline_group_section_date_classes = { classes: klasses(DATE) }
23
+ def timeline_group_section_list_classes = { classes: klasses(LIST) }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "timeline/group"
4
+
5
+ module StimulusPlumbers
6
+ module Themes
7
+ module Tailwind
8
+ module Timeline
9
+ TRACK_VERTICAL = %w[flex flex-col gap-y-10].freeze
10
+ TRACK_HORIZONTAL = %w[flex].freeze
11
+
12
+ TRACK_LINE_VERTICAL = %w[absolute inset-y-0 start-3 w-px bg-(--sp-color-border)].freeze
13
+
14
+ ITEM_VERTICAL = %w[flex gap-x-4 items-start].freeze
15
+ ITEM_HORIZONTAL = %w[relative flex-1].freeze
16
+
17
+ ITEM_INDICATOR_DOT = %w[
18
+ mt-1 flex shrink-0 size-6 items-center justify-center rounded-full z-10
19
+ bg-(--sp-color-bg) ring-4 ring-(--sp-color-bg)
20
+ ].freeze
21
+ ITEM_INDICATOR_DOT_MARK = %w[size-3 rounded-full bg-(--sp-color-indicator)].freeze
22
+
23
+ ITEM_INDICATOR_ICON = %w[
24
+ mt-1 flex shrink-0 size-6 items-center justify-center rounded-full z-10
25
+ bg-(--sp-color-primary) text-(--sp-color-primary-fg)
26
+ ring-4 ring-(--sp-color-bg)
27
+ ].freeze
28
+
29
+ ITEM_INDICATOR_ICON_SLOT = %w[size-(--sp-icon-size-sm) stroke-current].freeze
30
+
31
+ ITEM_INDICATOR_DOT_HORIZONTAL = %w[
32
+ z-10 flex shrink-0 size-6 items-center justify-center rounded-full
33
+ bg-(--sp-color-bg) ring-4 ring-(--sp-color-bg)
34
+ ].freeze
35
+
36
+ ITEM_INDICATOR_ICON_HORIZONTAL = %w[
37
+ z-10 flex shrink-0 size-6 items-center justify-center rounded-full
38
+ bg-(--sp-color-primary) text-(--sp-color-primary-fg)
39
+ ring-4 ring-(--sp-color-bg)
40
+ ].freeze
41
+
42
+ ITEM_CONNECTOR_HORIZONTAL = %w[w-full h-px bg-(--sp-color-border) last:hidden].freeze
43
+ ITEM_CONTENT_HORIZONTAL = %w[mt-3 pe-2].freeze
44
+
45
+ ITEM_TIME = %w[mb-1 block text-sm leading-none text-(--sp-color-muted-fg)].freeze
46
+ ITEM_TIME_BADGE = %w[
47
+ mb-1 inline-block
48
+ bg-(--sp-color-bg-muted) border border-(--sp-color-border)
49
+ text-(--sp-color-fg) text-xs font-medium px-1.5 py-0.5 rounded
50
+ ].freeze
51
+ ITEM_TITLE = %w[mb-1 text-base font-semibold text-(--sp-color-fg)].freeze
52
+ ITEM_HEADING = %w[mb-1].freeze
53
+ ITEM_TRIGGER = %w[
54
+ w-full text-left text-base font-semibold
55
+ text-(--sp-color-fg)
56
+ hover:text-(--sp-color-primary)
57
+ focus-visible:outline-none focus-visible:ring-2
58
+ focus-visible:ring-(--sp-color-primary) focus-visible:rounded-sm
59
+ ].freeze
60
+ ITEM_DESCRIPTION = %w[text-sm text-(--sp-color-muted-fg)].freeze
61
+ ITEM_DETAIL = %w[mt-2 text-sm text-(--sp-color-muted-fg)].freeze
62
+ ITEM_ACTIONS = %w[mt-3 flex flex-wrap items-center gap-2].freeze
63
+
64
+ private
65
+
66
+ def timeline_classes(orientation: :vertical)
67
+ track = orientation.to_sym == :horizontal ? TRACK_HORIZONTAL : TRACK_VERTICAL
68
+ { classes: klasses(track) }
69
+ end
70
+
71
+ def timeline_item_classes(orientation: :vertical)
72
+ item = orientation.to_sym == :horizontal ? ITEM_HORIZONTAL : ITEM_VERTICAL
73
+ { classes: klasses(item) }
74
+ end
75
+
76
+ def timeline_item_indicator_classes(type: :dot, orientation: :vertical)
77
+ base = if orientation.to_sym == :horizontal
78
+ type.to_sym == :icon ? ITEM_INDICATOR_ICON_HORIZONTAL : ITEM_INDICATOR_DOT_HORIZONTAL
79
+ else
80
+ type.to_sym == :icon ? ITEM_INDICATOR_ICON : ITEM_INDICATOR_DOT
81
+ end
82
+ { classes: klasses(base) }
83
+ end
84
+
85
+ def timeline_item_time_classes(type: :default)
86
+ base = type.to_sym == :badge ? ITEM_TIME_BADGE : ITEM_TIME
87
+ { classes: klasses(base) }
88
+ end
89
+
90
+ def timeline_item_title_classes = { classes: klasses(ITEM_TITLE) }
91
+ def timeline_item_heading_classes = { classes: klasses(ITEM_HEADING) }
92
+ def timeline_item_trigger_classes = { classes: klasses(ITEM_TRIGGER) }
93
+ def timeline_item_description_classes = { classes: klasses(ITEM_DESCRIPTION) }
94
+ def timeline_item_detail_classes = { classes: klasses(ITEM_DETAIL) }
95
+ def timeline_item_actions_classes = { classes: klasses(ITEM_ACTIONS) }
96
+ def timeline_item_indicator_dot_classes = { classes: klasses(ITEM_INDICATOR_DOT_MARK) }
97
+ def timeline_item_connector_classes = { classes: klasses(ITEM_CONNECTOR_HORIZONTAL) }
98
+ def timeline_item_content_classes = { classes: klasses(ITEM_CONTENT_HORIZONTAL) }
99
+ def timeline_track_line_classes = { classes: klasses(TRACK_LINE_VERTICAL) }
100
+ def timeline_item_indicator_icon_slot_classes = { classes: klasses(ITEM_INDICATOR_ICON_SLOT) }
101
+ end
102
+ end
103
+ end
104
+ end
@@ -1,27 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "tailwind/action_list"
3
+ require_relative "tailwind/control"
4
+ require_relative "tailwind/list"
4
5
  require_relative "tailwind/avatar"
5
6
  require_relative "tailwind/button"
7
+ require_relative "tailwind/button/group"
6
8
  require_relative "tailwind/calendar"
7
9
  require_relative "tailwind/card"
8
10
  require_relative "tailwind/combobox"
9
11
  require_relative "tailwind/form"
12
+ require_relative "tailwind/form/field"
13
+ require_relative "tailwind/form/input"
10
14
  require_relative "tailwind/icon"
11
15
  require_relative "tailwind/layout"
16
+ require_relative "tailwind/link"
17
+ require_relative "tailwind/timeline"
12
18
 
13
19
  module StimulusPlumbers
14
20
  module Themes
15
21
  class TailwindTheme < Base
16
- include Tailwind::ActionList
22
+ include Tailwind::List
17
23
  include Tailwind::Combobox
18
24
  include Tailwind::Avatar
19
25
  include Tailwind::Button
26
+ include Tailwind::Button::Group
20
27
  include Tailwind::Calendar
21
28
  include Tailwind::Card
22
29
  include Tailwind::Form
30
+ include Tailwind::Form::Field
31
+ include Tailwind::Form::Input
23
32
  include Tailwind::Icon
24
33
  include Tailwind::Layout
34
+ include Tailwind::Link
35
+ include Tailwind::Timeline
36
+ include Tailwind::Timeline::Group
25
37
 
26
38
  private
27
39
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StimulusPlumbersTailwind
4
- VERSION = "0.3.3"
4
+ VERSION = "0.4.2"
5
5
  end
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.3.3
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Chang
@@ -33,13 +33,16 @@ files:
33
33
  - CHANGELOG.md
34
34
  - LICENSE-DEPENDENCIES
35
35
  - README.md
36
- - lib/stimulus_plumbers/themes/tailwind/action_list.rb
37
36
  - lib/stimulus_plumbers/themes/tailwind/avatar.rb
38
37
  - lib/stimulus_plumbers/themes/tailwind/button.rb
38
+ - lib/stimulus_plumbers/themes/tailwind/button/group.rb
39
39
  - lib/stimulus_plumbers/themes/tailwind/calendar.rb
40
40
  - lib/stimulus_plumbers/themes/tailwind/card.rb
41
41
  - lib/stimulus_plumbers/themes/tailwind/combobox.rb
42
+ - lib/stimulus_plumbers/themes/tailwind/control.rb
42
43
  - lib/stimulus_plumbers/themes/tailwind/form.rb
44
+ - lib/stimulus_plumbers/themes/tailwind/form/field.rb
45
+ - lib/stimulus_plumbers/themes/tailwind/form/input.rb
43
46
  - lib/stimulus_plumbers/themes/tailwind/icon.rb
44
47
  - lib/stimulus_plumbers/themes/tailwind/icons/custom.rb
45
48
  - lib/stimulus_plumbers/themes/tailwind/icons/customs/spinner.svg
@@ -693,6 +696,10 @@ files:
693
696
  - lib/stimulus_plumbers/themes/tailwind/icons/heroicons/solid/x-circle.svg
694
697
  - lib/stimulus_plumbers/themes/tailwind/icons/heroicons/solid/x-mark.svg
695
698
  - lib/stimulus_plumbers/themes/tailwind/layout.rb
699
+ - lib/stimulus_plumbers/themes/tailwind/link.rb
700
+ - lib/stimulus_plumbers/themes/tailwind/list.rb
701
+ - lib/stimulus_plumbers/themes/tailwind/timeline.rb
702
+ - lib/stimulus_plumbers/themes/tailwind/timeline/group.rb
696
703
  - lib/stimulus_plumbers/themes/tailwind_theme.rb
697
704
  - lib/stimulus_plumbers_tailwind.rb
698
705
  - lib/stimulus_plumbers_tailwind/engine.rb
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module StimulusPlumbers
4
- module Themes
5
- module Tailwind
6
- module ActionList
7
- LIST_ITEM_ACTIVE = %w[bg-(--sp-color-primary)/10 text-(--sp-color-primary)].freeze
8
- LIST_ITEM_BASE = %w[
9
- flex items-center gap-(--sp-space-2) w-full
10
- px-(--sp-space-2) py-(--sp-space-1)
11
- rounded-(--sp-radius-sm) text-(length:--sp-text-sm)
12
- cursor-pointer select-none outline-none
13
- hover:bg-(--sp-color-muted) focus:bg-(--sp-color-muted) focus:text-(--sp-color-fg)
14
- ].freeze
15
-
16
- private
17
-
18
- def action_list_classes
19
- { classes: klasses("py-(--sp-space-1)") }
20
- end
21
-
22
- def action_list_item_classes(active: false)
23
- {
24
- classes: klasses(
25
- *LIST_ITEM_BASE,
26
- *(active ? LIST_ITEM_ACTIVE : [])
27
- )
28
- }
29
- end
30
- end
31
- end
32
- end
33
- end