phlexy_ui 0.1.1 → 0.1.5

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.
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ class Drawer < Base
5
+ def initialize(*, id:, as: :section, **)
6
+ super(*, **)
7
+ @as = as
8
+ @id = id
9
+ end
10
+
11
+ def view_template(&)
12
+ generate_classes!(
13
+ component_html_class: :drawer,
14
+ modifiers_map: DRAWER_MODIFIERS_MAP,
15
+ base_modifiers:,
16
+ options:
17
+ ).then do |classes|
18
+ public_send(as, class: classes, **options, &)
19
+ end
20
+ end
21
+
22
+ def toggle(**options, &)
23
+ generate_classes!(
24
+ component_html_class: :"drawer-toggle",
25
+ options:
26
+ ).then do |classes|
27
+ input(id:, type: :checkbox, class: classes, **options, &)
28
+ end
29
+ end
30
+
31
+ def content(as: :div, **options, &)
32
+ generate_classes!(
33
+ component_html_class: :"drawer-content",
34
+ options:
35
+ ).then do |classes|
36
+ public_send(as, class: classes, **options, &)
37
+ end
38
+ end
39
+
40
+ def side(as: :div, **options, &)
41
+ generate_classes!(
42
+ component_html_class: :"drawer-side",
43
+ options:
44
+ ).then do |classes|
45
+ public_send(as, class: classes, **options, &)
46
+ end
47
+ end
48
+
49
+ def overlay(**options, &)
50
+ generate_classes!(
51
+ component_html_class: :"drawer-overlay",
52
+ options:
53
+ ).then do |classes|
54
+ label(for: id, class: classes, **options, &)
55
+ end
56
+ end
57
+
58
+ def button(*, **, &)
59
+ render Button.new(*, as: :label, for: id, **, &)
60
+ end
61
+
62
+ private
63
+
64
+ DRAWER_MODIFIERS_MAP = {
65
+ # "sm:drawer-end",
66
+ # "md:drawer-end",
67
+ # "lg:drawer-end",
68
+ end: "drawer-end",
69
+ # "sm:drawer-open",
70
+ # "md:drawer-open",
71
+ # "lg:drawer-open",
72
+ open: "drawer-open"
73
+ }.freeze
74
+ end
75
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ class Dropdown < Base
5
+ def initialize(*, as: :div, **)
6
+ super(*, **)
7
+ @as = as
8
+ end
9
+
10
+ def view_template(&)
11
+ generate_classes!(
12
+ component_html_class: :dropdown,
13
+ modifiers_map: DROPDOWN_MODIFIERS_MAP,
14
+ base_modifiers:,
15
+ options:
16
+ ).then do |classes|
17
+ if base_modifiers.include?(:tap_to_close)
18
+ details(class: classes, **options, &)
19
+ else
20
+ public_send(as, class: classes, **options, &)
21
+ end
22
+ end
23
+ end
24
+
25
+ def button(*, **, &)
26
+ if base_modifiers.include?(:tap_to_close)
27
+ render Button.new(*, as: :summary, **, &)
28
+ else
29
+ render Button.new(*, as: :div, role: :button, tabindex: 0, **, &)
30
+ end
31
+ end
32
+
33
+ def content(*, as: :div, **options, &)
34
+ generate_classes!(
35
+ component_html_class: :"dropdown-content",
36
+ options:
37
+ ).then do |classes|
38
+ if base_modifiers.include?(:tap_to_close)
39
+ render_as(*, as:, class: classes, **options, &)
40
+ else
41
+ render_as(*, as:, tabindex: 0, class: classes, **options, &)
42
+ end
43
+ end
44
+ end
45
+
46
+ def menu(*, **options, &)
47
+ generate_classes!(
48
+ component_html_class: :"dropdown-content",
49
+ options:
50
+ ).then do |classes|
51
+ if base_modifiers.include?(:tap_to_close)
52
+ render Menu.new(*, class: classes, **options, &)
53
+ else
54
+ render Menu.new(*, tabindex: 0, class: classes, **options, &)
55
+ end
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ DROPDOWN_MODIFIERS_MAP = {
62
+ # "sm:dropdown-end"
63
+ # "md:dropdown-end"
64
+ # "lg:dropdown-end"
65
+ end: "dropdown-end",
66
+ # "sm:dropdown-top"
67
+ # "md:dropdown-top"
68
+ # "lg:dropdown-top"
69
+ top: "dropdown-top",
70
+ # "sm:dropdown-bottom"
71
+ # "md:dropdown-bottom"
72
+ # "lg:dropdown-bottom"
73
+ bottom: "dropdown-bottom",
74
+ # "sm:dropdown-left"
75
+ # "md:dropdown-left"
76
+ # "lg:dropdown-left"
77
+ left: "dropdown-left",
78
+ # "sm:dropdown-right"
79
+ # "md:dropdown-right"
80
+ # "lg:dropdown-right"
81
+ right: "dropdown-right",
82
+ # "sm:dropdown-hover"
83
+ # "md:dropdown-hover"
84
+ # "lg:dropdown-hover"
85
+ hover: "dropdown-hover",
86
+ # "sm:dropdown-open"
87
+ # "md:dropdown-open"
88
+ # "lg:dropdown-open"
89
+ open: "dropdown-open"
90
+ }.freeze
91
+ end
92
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ class Link < Base
5
+ def view_template(&)
6
+ generate_classes!(
7
+ modifiers_map: LINK_MODIFIERS_MAP,
8
+ base_modifiers:,
9
+ options:
10
+ ).then do |classes|
11
+ a(class: classes, **options, &)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :link_to_name
18
+
19
+ LINK_MODIFIERS_MAP = {
20
+ # "sm:link"
21
+ # "md:link"
22
+ # "lg:link"
23
+ underlined: "link",
24
+ # "sm:link-hover"
25
+ # "md:link-hover"
26
+ # "lg:link-hover"
27
+ hover: "link-hover",
28
+ # "sm:active"
29
+ # "md:active"
30
+ # "lg:active"
31
+ active: "active",
32
+ # "sm:image-full"
33
+ # "md:image-full"
34
+ # "lg:image-full"
35
+ image_full: "image-full",
36
+ # "sm:card-bordered"
37
+ # "md:card-bordered"
38
+ # "lg:card-bordered"
39
+ bordered: "card-bordered",
40
+ # "sm:card-normal"
41
+ # "md:card-normal"
42
+ # "lg:card-normal"
43
+ normal: "card-normal",
44
+ # "sm:card-compact"
45
+ # "md:card-compact"
46
+ # "lg:card-compact"
47
+ compact: "card-compact",
48
+ # "sm:card-side"
49
+ # "md:card-side"
50
+ # "lg:card-side"
51
+ side: "card-side",
52
+ # "sm:glass"
53
+ # "md:glass"
54
+ # "lg:glass"
55
+ glass: "glass",
56
+ # "sm:link-primary"
57
+ # "md:link-primary"
58
+ # "lg:link-primary"
59
+ primary: "link-primary",
60
+ # "sm:link-secondary"
61
+ # "md:link-secondary"
62
+ # "lg:link-secondary"
63
+ secondary: "link-secondary",
64
+ # "sm:link-accent"
65
+ # "md:link-accent"
66
+ # "lg:link-accent"
67
+ accent: "link-accent",
68
+ # "sm:link-neutral"
69
+ # "md:link-neutral"
70
+ # "lg:link-neutral"
71
+ neutral: "link-neutral",
72
+ # "sm:link-info"
73
+ # "md:link-info"
74
+ # "lg:link-info"
75
+ info: "link-info",
76
+ # "sm:link-success"
77
+ # "md:link-success"
78
+ # "lg:link-success"
79
+ success: "link-success",
80
+ # "sm:link-warning"
81
+ # "md:link-warning"
82
+ # "lg:link-warning"
83
+ warning: "link-warning",
84
+ # "sm:link-error"
85
+ # "md:link-error"
86
+ # "lg:link-error"
87
+ error: "link-error"
88
+ }.freeze
89
+ end
90
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ class Loading < Base
5
+ def initialize(*, as: :span, **)
6
+ super(*, **)
7
+ @as = as
8
+ end
9
+
10
+ def view_template(&)
11
+ generate_classes!(
12
+ component_html_class: :loading,
13
+ modifiers_map: LOADING_MODIFIERS_MAP,
14
+ base_modifiers:,
15
+ options:
16
+ ).then do |classes|
17
+ public_send(as, class: classes, **options, &)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ LOADING_MODIFIERS_MAP = {
24
+ # "sm:loading-spinner"
25
+ # "md:loading-spinner"
26
+ # "lg:loading-spinner"
27
+ spinner: "loading-spinner",
28
+ # "sm:loading-dots"
29
+ # "md:loading-dots"
30
+ # "lg:loading-dots"
31
+ dots: "loading-dots",
32
+ # "sm:loading-ring"
33
+ # "md:loading-ring"
34
+ # "lg:loading-ring"
35
+ ring: "loading-ring",
36
+ # "sm:loading-ball"
37
+ # "md:loading-ball"
38
+ # "lg:loading-ball"
39
+ ball: "loading-ball",
40
+ # "sm:loading-bars"
41
+ # "md:loading-bars"
42
+ # "lg:loading-bars"
43
+ bars: "loading-bars",
44
+ # "sm:loading-infinity"
45
+ # "md:loading-infinity"
46
+ # "lg:loading-infinity"
47
+ infinity: "loading-infinity",
48
+ # "sm:loading-xs"
49
+ # "md:loading-xs"
50
+ # "lg:loading-xs"
51
+ xs: "loading-xs",
52
+ # "sm:loading-sm"
53
+ # "md:loading-sm"
54
+ # "lg:loading-sm"
55
+ sm: "loading-sm",
56
+ # "sm:loading-md"
57
+ # "md:loading-md"
58
+ # "lg:loading-md"
59
+ md: "loading-md",
60
+ # "sm:loading-lg"
61
+ # "md:loading-lg"
62
+ # "lg:loading-lg"
63
+ lg: "loading-lg",
64
+ # "sm:text-primary"
65
+ # "md:text-primary"
66
+ # "lg:text-primary"
67
+ primary: "text-primary",
68
+ # "sm:text-secondary"
69
+ # "md:text-secondary"
70
+ # "lg:text-secondary"
71
+ secondary: "text-secondary",
72
+ # "sm:text-accent"
73
+ # "md:text-accent"
74
+ # "lg:text-accent"
75
+ accent: "text-accent",
76
+ # "sm:text-neutral"
77
+ # "md:text-neutral"
78
+ # "lg:text-neutral"
79
+ neutral: "text-neutral",
80
+ # "sm:text-info"
81
+ # "md:text-info"
82
+ # "lg:text-info"
83
+ info: "text-info",
84
+ # "sm:text-success"
85
+ # "md:text-success"
86
+ # "lg:text-success"
87
+ success: "text-success",
88
+ # "sm:text-warning"
89
+ # "md:text-warning"
90
+ # "lg:text-warning"
91
+ warning: "text-warning",
92
+ # "sm:text-error"
93
+ # "md:text-error"
94
+ # "lg:text-error"
95
+ error: "text-error"
96
+ }.freeze
97
+ end
98
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ class Menu < Base
5
+ def view_template(&)
6
+ generate_classes!(
7
+ component_html_class: :menu,
8
+ modifiers_map: MENU_MODIFIERS_MAP,
9
+ base_modifiers:,
10
+ options:
11
+ ).then do |classes|
12
+ ul(class: classes, **options, &)
13
+ end
14
+ end
15
+
16
+ def title(*, as: :li, **options, &)
17
+ generate_classes!(
18
+ component_html_class: :"menu-title",
19
+ options:
20
+ ).then do |classes|
21
+ public_send(as, class: classes, **options, &)
22
+ end
23
+ end
24
+
25
+ def item(*, **, &)
26
+ render MenuItem.new(*, **, &)
27
+ end
28
+
29
+ def submenu(*base_modifiers, **, &)
30
+ if base_modifiers.include?(:collapsible)
31
+ li do
32
+ render CollapsibleSubMenu.new(*base_modifiers, **, &)
33
+ end
34
+ else
35
+ li do
36
+ render SubMenu.new(*base_modifiers, **, &)
37
+ end
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ MENU_MODIFIERS_MAP = {
44
+ # "sm:menu-xs"
45
+ # "md:menu-xs"
46
+ # "lg:menu-xs"
47
+ xs: "menu-xs",
48
+ # "sm:menu-sm"
49
+ # "md:menu-sm"
50
+ # "lg:menu-sm"
51
+ sm: "menu-sm",
52
+ # "sm:menu-md"
53
+ # "md:menu-md"
54
+ # "lg:menu-md"
55
+ md: "menu-md",
56
+ # "sm:menu-lg"
57
+ # "md:menu-lg"
58
+ # "lg:menu-lg"
59
+ lg: "menu-lg",
60
+ # "sm:menu-vertical"
61
+ # "md:menu-vertical"
62
+ # "lg:menu-vertical"
63
+ vertical: "menu-vertical",
64
+ # "sm:menu-horizontal"
65
+ # "md:menu-horizontal"
66
+ # "lg:menu-horizontal"
67
+ horizontal: "menu-horizontal",
68
+ # "sm:bg-primary sm:text-primary-content"
69
+ # "md:bg-primary md:text-primary-content"
70
+ # "lg:bg-primary lg:text-primary-content"
71
+ primary: "bg-primary text-primary-content",
72
+ # "sm:bg-secondary sm:text-secondary-content"
73
+ # "md:bg-secondary md:text-secondary-content"
74
+ # "lg:bg-secondary lg:text-secondary-content"
75
+ secondary: "bg-secondary text-secondary-content",
76
+ # "sm:bg-accent sm:text-accent-content"
77
+ # "md:bg-accent md:text-accent-content"
78
+ # "lg:bg-accent lg:text-accent-content"
79
+ accent: "bg-accent text-accent-content",
80
+ # "sm:bg-neutral sm:text-neutral-content"
81
+ # "md:bg-neutral md:text-neutral-content"
82
+ # "lg:bg-neutral lg:text-neutral-content"
83
+ neutral: "bg-neutral text-neutral-content",
84
+ # "sm:bg-base-100 sm:text-base-content"
85
+ # "md:bg-base-100 md:text-base-content"
86
+ # "lg:bg-base-100 lg:text-base-content"
87
+ base_100: "bg-base-100 text-base-content",
88
+ # "sm:bg-base-200 sm:text-base-content"
89
+ # "md:bg-base-200 md:text-base-content"
90
+ # "lg:bg-base-200 lg:text-base-content"
91
+ base_200: "bg-base-200 text-base-content",
92
+ # "sm:bg-base-300 sm:text-base-content"
93
+ # "md:bg-base-300 md:text-base-content"
94
+ # "lg:bg-base-300 lg:text-base-content"
95
+ base_300: "bg-base-300 text-base-content",
96
+ # "sm:bg-info sm:text-info-content"
97
+ # "md:bg-info sm:text-info-content"
98
+ # "lg:bg-info sm:text-info-content"
99
+ info: "bg-info text-info-content",
100
+ # "sm:bg-success sm:text-success-content"
101
+ # "md:bg-success md:text-success-content"
102
+ # "lg:bg-success lg:text-success-content"
103
+ success: "bg-success text-success-content",
104
+ # "sm:bg-warning sm:text-warning-content"
105
+ # "md:bg-warning md:text-warning-content"
106
+ # "lg:bg-warning lg:text-warning-content"
107
+ warning: "bg-warning text-warning-content",
108
+ # "sm:bg-error sm:text-error-content"
109
+ # "md:bg-error md:text-error-content"
110
+ # "lg:bg-error lg:text-error-content"
111
+ error: "bg-error text-error-content"
112
+ }.freeze
113
+ end
114
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ # @private
5
+ class MenuItem < Base
6
+ def view_template(&)
7
+ generate_classes!(
8
+ modifiers_map: MENU_ITEM_MODIFIERS_MAP,
9
+ base_modifiers:,
10
+ options:
11
+ ).then do |classes|
12
+ li(class: classes, &)
13
+ end
14
+ end
15
+
16
+ def title(*, **options, &block)
17
+ generate_classes!(
18
+ component_html_class: :"menu-title",
19
+ options:
20
+ ).then do |classes|
21
+ h2(class: classes, **options, &block)
22
+ end
23
+ end
24
+
25
+ def submenu(*base_modifiers, **, &)
26
+ if base_modifiers.include?(:collapsible)
27
+ render CollapsibleSubMenu.new(*base_modifiers, **, &)
28
+ else
29
+ render SubMenu.new(*base_modifiers, **, &)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ MENU_ITEM_MODIFIERS_MAP = {
36
+ # "sm:disabled"
37
+ # "md:disabled"
38
+ # "lg:disabled"
39
+ disabled: "disabled",
40
+ # "sm:active"
41
+ # "md:active"
42
+ # "lg:active"
43
+ active: "active",
44
+ # "sm:focus"
45
+ # "md:focus"
46
+ # "lg:focus"
47
+ focus: "focus"
48
+ }.freeze
49
+ end
50
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ class Navbar < Base
5
+ def initialize(*, as: :nav, **)
6
+ super(*, **)
7
+ @as = as
8
+ end
9
+
10
+ def view_template(&)
11
+ generate_classes!(
12
+ component_html_class: :navbar,
13
+ base_modifiers:,
14
+ options:
15
+ ).then do |classes|
16
+ public_send(as, class: classes, **options, &)
17
+ end
18
+ end
19
+
20
+ def start(&)
21
+ div(class: :"navbar-start", &)
22
+ end
23
+
24
+ def center(&)
25
+ div(class: :"navbar-center", &)
26
+ end
27
+
28
+ def end(&)
29
+ div(class: :"navbar-end", &)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ # @private
5
+ class SubMenu < Base
6
+ include Phlex::DeferredRender
7
+
8
+ def initialize(*, **)
9
+ super
10
+ @items ||= []
11
+ end
12
+
13
+ def view_template(&)
14
+ if @title
15
+ div do
16
+ render @title
17
+ end
18
+ end
19
+
20
+ if @items.any?
21
+ ul do
22
+ @items.each do |item|
23
+ render item
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def title(&block)
30
+ @title = block
31
+ end
32
+
33
+ def item(*, **, &)
34
+ @items << MenuItem.new(*, **, &)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ # @private
5
+ class Tab < Base
6
+ include Phlex::DeferredRender
7
+
8
+ def initialize(*, id: nil, **)
9
+ super(*, **)
10
+ @id = id
11
+ end
12
+
13
+ def view_template(&)
14
+ if @content
15
+ render TabWithContent.new(
16
+ *base_modifiers,
17
+ id:,
18
+ content: @content,
19
+ **options,
20
+ &
21
+ )
22
+ else
23
+ render TabWithoutContent.new(*base_modifiers, id:, **options, &)
24
+ end
25
+ end
26
+
27
+ def content(*, **options, &)
28
+ unless id
29
+ raise ArgumentError,
30
+ "You must pass an id to Tabs#new if you want to add content"
31
+ end
32
+
33
+ @content = -> do
34
+ generate_classes!(
35
+ component_html_class: :"tab-content",
36
+ options:
37
+ ).then do |classes|
38
+ div role: :tabpanel, class: classes, **options, &
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ TAB_MODIFIERS_CLASSES = {
46
+ # "sm:tab-active"
47
+ # "md:tab-active"
48
+ # "lg:tab-active"
49
+ active: "tab-active",
50
+ # "sm:tab-disabled"
51
+ # "md:tab-disabled"
52
+ # "lg:tab-disabled"
53
+ disabled: "tab-disabled"
54
+ }.freeze
55
+ end
56
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PhlexyUI
4
+ # @private
5
+ class TabWithContent < Base
6
+ def initialize(*base_modifiers, content:, id: nil, **)
7
+ super(*base_modifiers, **)
8
+ @title = title
9
+ @id = id
10
+ @content = content
11
+ end
12
+
13
+ def view_template(&)
14
+ title, *base_modifiers = @base_modifiers
15
+
16
+ attributes = generate_attributes(
17
+ base_modifiers,
18
+ ATTRIBUTES_MAP
19
+ )
20
+
21
+ generate_classes!(
22
+ component_html_class: :tab,
23
+ modifiers_map: Tab::TAB_MODIFIERS_CLASSES,
24
+ base_modifiers:,
25
+ options:
26
+ ).then do |classes|
27
+ input(
28
+ type: :radio,
29
+ name: id,
30
+ class: classes,
31
+ role: :tab,
32
+ aria_label: title,
33
+ **attributes,
34
+ **options
35
+ )
36
+ end
37
+
38
+ @content&.call
39
+ end
40
+
41
+ private
42
+
43
+ attr_reader :title
44
+
45
+ ATTRIBUTES_MAP = {
46
+ open: {checked: true},
47
+ closed: true
48
+ }.freeze
49
+ end
50
+ end