protos 0.1.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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +12 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +150 -0
- data/Rakefile +12 -0
- data/examples/navbar.rb +43 -0
- data/lib/protos/accordion/item.rb +33 -0
- data/lib/protos/accordion.rb +34 -0
- data/lib/protos/alert/actions.rb +19 -0
- data/lib/protos/alert/icon.rb +19 -0
- data/lib/protos/alert.rb +46 -0
- data/lib/protos/attributes.rb +42 -0
- data/lib/protos/avatar.rb +71 -0
- data/lib/protos/card/actions.rb +19 -0
- data/lib/protos/card/body.rb +19 -0
- data/lib/protos/card/image.rb +11 -0
- data/lib/protos/card/title.rb +19 -0
- data/lib/protos/card.rb +55 -0
- data/lib/protos/collapse/content.rb +19 -0
- data/lib/protos/collapse/title.rb +19 -0
- data/lib/protos/collapse.rb +31 -0
- data/lib/protos/combobox.rb +53 -0
- data/lib/protos/command/dialog.rb +32 -0
- data/lib/protos/command/empty.rb +25 -0
- data/lib/protos/command/group.rb +13 -0
- data/lib/protos/command/input.rb +44 -0
- data/lib/protos/command/item.rb +19 -0
- data/lib/protos/command/list.rb +19 -0
- data/lib/protos/command/title.rb +19 -0
- data/lib/protos/command/trigger.rb +19 -0
- data/lib/protos/command.rb +49 -0
- data/lib/protos/component.rb +79 -0
- data/lib/protos/drawer/content.rb +19 -0
- data/lib/protos/drawer/side.rb +25 -0
- data/lib/protos/drawer/trigger.rb +21 -0
- data/lib/protos/drawer.rb +35 -0
- data/lib/protos/dropdown/item.rb +11 -0
- data/lib/protos/dropdown/menu.rb +25 -0
- data/lib/protos/dropdown/trigger.rb +11 -0
- data/lib/protos/dropdown.rb +59 -0
- data/lib/protos/engine.rb +7 -0
- data/lib/protos/list/item.rb +22 -0
- data/lib/protos/list.rb +30 -0
- data/lib/protos/modal/close_button.rb +16 -0
- data/lib/protos/modal/dialog.rb +30 -0
- data/lib/protos/modal/trigger.rb +19 -0
- data/lib/protos/modal.rb +31 -0
- data/lib/protos/popover/content.rb +19 -0
- data/lib/protos/popover/trigger.rb +11 -0
- data/lib/protos/popover.rb +54 -0
- data/lib/protos/table/body.rb +11 -0
- data/lib/protos/table/caption.rb +19 -0
- data/lib/protos/table/cell.rb +11 -0
- data/lib/protos/table/footer.rb +11 -0
- data/lib/protos/table/head.rb +11 -0
- data/lib/protos/table/header.rb +11 -0
- data/lib/protos/table/row.rb +11 -0
- data/lib/protos/table.rb +48 -0
- data/lib/protos/theme.rb +76 -0
- data/lib/protos/timeline/center.rb +19 -0
- data/lib/protos/timeline/item.rb +11 -0
- data/lib/protos/timeline/left.rb +19 -0
- data/lib/protos/timeline/right.rb +19 -0
- data/lib/protos/timeline.rb +38 -0
- data/lib/protos/token_list.rb +41 -0
- data/lib/protos/types.rb +32 -0
- data/lib/protos/typography/heading.rb +44 -0
- data/lib/protos/typography/inline_link.rb +24 -0
- data/lib/protos/typography/paragraph.rb +22 -0
- data/lib/protos/typography.rb +29 -0
- data/lib/protos/version.rb +5 -0
- data/lib/protos.rb +94 -0
- data/protos.gemspec +45 -0
- metadata +180 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Collapse
|
5
|
+
class Title < Component
|
6
|
+
def template(&block)
|
7
|
+
div(**attrs, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def theme
|
13
|
+
{
|
14
|
+
container: tokens("collapse-title")
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Collapse < Component
|
5
|
+
def template(&block)
|
6
|
+
div(**attrs, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def title(...)
|
10
|
+
Title.new(...)
|
11
|
+
end
|
12
|
+
|
13
|
+
def content(...)
|
14
|
+
Content.new(...)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def theme
|
20
|
+
{
|
21
|
+
container: tokens("collapse", "collapse-arrow", "bg-base-100")
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_attrs
|
26
|
+
{
|
27
|
+
tabindex: 0
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Combobox < Component
|
5
|
+
def template
|
6
|
+
div(**attrs) do
|
7
|
+
render Popover.new do
|
8
|
+
yield if block_given?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def trigger(...)
|
14
|
+
Popover::Trigger.new(...)
|
15
|
+
end
|
16
|
+
|
17
|
+
def content(...)
|
18
|
+
Popover::Content.new(...)
|
19
|
+
end
|
20
|
+
|
21
|
+
def input(...)
|
22
|
+
Command::Input.new(...)
|
23
|
+
end
|
24
|
+
|
25
|
+
def group(...)
|
26
|
+
Command::Group.new(...)
|
27
|
+
end
|
28
|
+
|
29
|
+
def item(...)
|
30
|
+
Command::Item.new(...)
|
31
|
+
end
|
32
|
+
|
33
|
+
def list(...)
|
34
|
+
Command::List.new(...)
|
35
|
+
end
|
36
|
+
|
37
|
+
def title(...)
|
38
|
+
Command::Title.new(...)
|
39
|
+
end
|
40
|
+
|
41
|
+
def empty(...)
|
42
|
+
Command::Empty.new(...)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def default_attrs
|
48
|
+
{
|
49
|
+
data: { controller: "protos--command" }
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Command
|
5
|
+
class Dialog < Component
|
6
|
+
def template(&block)
|
7
|
+
dialog(**attrs) do
|
8
|
+
div(class: css[:modal], &block)
|
9
|
+
form(method: :dialog, class: css[:form]) do
|
10
|
+
button { "close" }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def default_attrs
|
18
|
+
{
|
19
|
+
data: { "protos--modal-target": "modal" }
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def theme
|
24
|
+
{
|
25
|
+
container: tokens("modal", "modal-bottom", "sm:modal-middle"),
|
26
|
+
modal: tokens("modal-box", "p-0"),
|
27
|
+
form: tokens("modal-backdrop")
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Command
|
5
|
+
class Empty < Component
|
6
|
+
def template(&block)
|
7
|
+
li(**attrs, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def default_attrs
|
13
|
+
{
|
14
|
+
data: { "protos--command-target": "empty" }
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def theme
|
19
|
+
{
|
20
|
+
container: tokens("hidden", "px-xs", "py-sm")
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Command
|
5
|
+
class Input < Component
|
6
|
+
option :placeholder,
|
7
|
+
default: -> {
|
8
|
+
"Type a command or search..."
|
9
|
+
},
|
10
|
+
reader: :private
|
11
|
+
|
12
|
+
def template(&block)
|
13
|
+
div(**attrs) do
|
14
|
+
label(class: css[:label]) do
|
15
|
+
div(class: css[:icon], &block) if block
|
16
|
+
input(
|
17
|
+
type: :text,
|
18
|
+
data: { action: "protos--command#filter" },
|
19
|
+
class: css[:input],
|
20
|
+
placeholder:
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def theme
|
29
|
+
{
|
30
|
+
container: tokens("form-control"),
|
31
|
+
label: tokens(
|
32
|
+
"input",
|
33
|
+
"input-bordered",
|
34
|
+
"flex",
|
35
|
+
"items-center",
|
36
|
+
"gap-2"
|
37
|
+
),
|
38
|
+
input: tokens("grow", "bg-transparent"),
|
39
|
+
icon: tokens("flex", "place-items-center")
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Command
|
5
|
+
class Item < Component
|
6
|
+
def template(&block)
|
7
|
+
li(**attrs, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def default_attrs
|
13
|
+
{
|
14
|
+
data: { "protos--command-target": "item" }
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Command
|
5
|
+
class Trigger < Component
|
6
|
+
def template(&block)
|
7
|
+
button(**attrs, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def default_attrs
|
13
|
+
{
|
14
|
+
data: { action: "protos--modal#open" }
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Command < Component
|
5
|
+
def template(&block)
|
6
|
+
div(**attrs, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def input(...)
|
10
|
+
Input.new(...)
|
11
|
+
end
|
12
|
+
|
13
|
+
def list(...)
|
14
|
+
List.new(...)
|
15
|
+
end
|
16
|
+
|
17
|
+
def trigger(...)
|
18
|
+
Trigger.new(...)
|
19
|
+
end
|
20
|
+
|
21
|
+
def dialog(...)
|
22
|
+
Dialog.new(...)
|
23
|
+
end
|
24
|
+
|
25
|
+
def title(...)
|
26
|
+
Title.new(...)
|
27
|
+
end
|
28
|
+
|
29
|
+
def group(...)
|
30
|
+
Group.new(...)
|
31
|
+
end
|
32
|
+
|
33
|
+
def item(...)
|
34
|
+
Item.new
|
35
|
+
end
|
36
|
+
|
37
|
+
def empty(...)
|
38
|
+
Empty.new(...)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def default_attrs
|
44
|
+
{
|
45
|
+
data: { controller: "protos--command protos--modal" }
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Component < Phlex::HTML
|
5
|
+
# DOCS: Base component
|
6
|
+
|
7
|
+
extend Dry::Initializer
|
8
|
+
extend Dry::Core::ClassAttributes
|
9
|
+
|
10
|
+
# Define methods for css and attrs. Each is expected to return a hash
|
11
|
+
defines :css_method, type: Types::Symbol
|
12
|
+
defines :attrs_method, type: Types::Symbol
|
13
|
+
|
14
|
+
css_method :theme
|
15
|
+
attrs_method :default_attrs
|
16
|
+
|
17
|
+
# Theme can override the css hash and add additional styles
|
18
|
+
option :theme, as: :theme_override, default: -> { {} }, reader: :private
|
19
|
+
# Class becomes the :container key in the css hash
|
20
|
+
option :class, as: :container_class, default: -> { "" }, reader: :private
|
21
|
+
option :html_options, default: -> { {} }, reader: :private
|
22
|
+
|
23
|
+
# Adds non-defined options to the html_options hash
|
24
|
+
def initialize(*args, **kwargs, &block)
|
25
|
+
raise_block_in_initializer_error if block
|
26
|
+
|
27
|
+
defined_keys = self.class.dry_initializer.definitions.keys
|
28
|
+
defined, undefined =
|
29
|
+
kwargs
|
30
|
+
.partition { |key, _| defined_keys.include?(key) }
|
31
|
+
.map(&:to_h)
|
32
|
+
|
33
|
+
super(*args, html_options: undefined, **defined)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def raise_block_in_initializer_error
|
39
|
+
raise(
|
40
|
+
ArgumentError,
|
41
|
+
"It is unexpected to pass a block to the initializer of a component. " \
|
42
|
+
"You might have tried to render and passed a block but it went to " \
|
43
|
+
"the component.new. Check your render call."
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def attrs
|
48
|
+
@attrs ||= build_attrs
|
49
|
+
end
|
50
|
+
|
51
|
+
def css
|
52
|
+
@css ||= build_theme
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_attrs(...)
|
56
|
+
defaults = if respond_to?(self.class.attrs_method, :include_private)
|
57
|
+
send(self.class.attrs_method)
|
58
|
+
end
|
59
|
+
|
60
|
+
Attributes
|
61
|
+
.new(...)
|
62
|
+
.merge(defaults)
|
63
|
+
.merge(html_options)
|
64
|
+
.merge(class: css[:container])
|
65
|
+
end
|
66
|
+
|
67
|
+
def build_theme(...)
|
68
|
+
component_style = if respond_to?(self.class.css_method, :include_private)
|
69
|
+
send(self.class.css_method)
|
70
|
+
end
|
71
|
+
|
72
|
+
Theme
|
73
|
+
.new(...)
|
74
|
+
.merge(component_style)
|
75
|
+
.merge(theme_override)
|
76
|
+
.merge(container: container_class)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Drawer
|
5
|
+
class Content < Component
|
6
|
+
def template(&block)
|
7
|
+
div(**attrs, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def theme
|
13
|
+
{
|
14
|
+
container: tokens("drawer-content")
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Drawer
|
5
|
+
class Side < Component
|
6
|
+
option :id, type: Types::Coercible::String
|
7
|
+
|
8
|
+
def template
|
9
|
+
aside(**attrs) do
|
10
|
+
label(for: id, aria_label: "close sidebar", class: css[:toggle])
|
11
|
+
yield if block_given?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def theme
|
18
|
+
{
|
19
|
+
container: tokens("drawer-side", "z-20"),
|
20
|
+
toggle: tokens("drawer-overlay")
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Drawer
|
5
|
+
class Trigger < Component
|
6
|
+
option :id, type: Types::Coercible::String
|
7
|
+
|
8
|
+
def template(&block)
|
9
|
+
label(for: id, **attrs, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def theme
|
15
|
+
{
|
16
|
+
container: tokens("drawer-button")
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Drawer < Component
|
5
|
+
option :id, type: Types::Coercible::String
|
6
|
+
|
7
|
+
def template
|
8
|
+
div(**attrs) do
|
9
|
+
input(id:, type: :checkbox, class: css[:toggle])
|
10
|
+
yield if block_given?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def content(...)
|
15
|
+
Content.new(...)
|
16
|
+
end
|
17
|
+
|
18
|
+
def side(*args, **kwargs, &block)
|
19
|
+
Side.new(*args, id:, **kwargs, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def trigger(*args, **kwargs, &block)
|
23
|
+
Trigger.new(*args, id:, **kwargs, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def theme
|
29
|
+
{
|
30
|
+
container: tokens("drawer"),
|
31
|
+
toggle: tokens("drawer-toggle")
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Dropdown
|
5
|
+
class Menu < Component
|
6
|
+
def template(&block)
|
7
|
+
ul(**attrs, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def theme
|
13
|
+
{
|
14
|
+
container: tokens(
|
15
|
+
"menu",
|
16
|
+
"dropdown-content",
|
17
|
+
"z-10",
|
18
|
+
"bg-base-100",
|
19
|
+
"rounded-box"
|
20
|
+
)
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Dropdown < Component
|
5
|
+
PositionTypes = Types::Coercible::Symbol.enum(
|
6
|
+
:top,
|
7
|
+
:bottom,
|
8
|
+
:left,
|
9
|
+
:right,
|
10
|
+
:start,
|
11
|
+
:end
|
12
|
+
)
|
13
|
+
|
14
|
+
option :position,
|
15
|
+
type: PositionTypes,
|
16
|
+
default: -> { :bottom },
|
17
|
+
reader: false
|
18
|
+
option :hover, type: Types::Bool, default: -> { false }
|
19
|
+
|
20
|
+
def template(&block)
|
21
|
+
details(**attrs, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def item(...)
|
25
|
+
Item.new(...)
|
26
|
+
end
|
27
|
+
|
28
|
+
def menu(...)
|
29
|
+
Menu.new(...)
|
30
|
+
end
|
31
|
+
|
32
|
+
def trigger(...)
|
33
|
+
Trigger.new(...)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def position
|
39
|
+
{
|
40
|
+
bottom: "dropdown-bottom",
|
41
|
+
top: "dropdown-top",
|
42
|
+
left: "dropdown-left",
|
43
|
+
right: "dropdown-right",
|
44
|
+
end: "dropdown-end",
|
45
|
+
start: "dropdown-start"
|
46
|
+
}.fetch(@position)
|
47
|
+
end
|
48
|
+
|
49
|
+
def theme
|
50
|
+
{
|
51
|
+
container: tokens(
|
52
|
+
"dropdown",
|
53
|
+
position,
|
54
|
+
hover: "dropdown-hover"
|
55
|
+
)
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class List
|
5
|
+
class Item < Component
|
6
|
+
def template(&block)
|
7
|
+
li(**attrs, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def theme
|
13
|
+
{
|
14
|
+
container: tokens(
|
15
|
+
"join-item",
|
16
|
+
"[&:not(:first-child)]:border-t-0"
|
17
|
+
)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|