phlexy_ui 0.1.1 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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