protos 0.7.0 → 1.0.1
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 +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +37 -68
- data/lib/protos/alert.rb +1 -4
- data/lib/protos/avatar.rb +2 -10
- data/lib/protos/badge.rb +33 -37
- data/lib/protos/card.rb +29 -16
- data/lib/protos/carousel.rb +7 -5
- data/lib/protos/chat_bubble/content.rb +8 -16
- data/lib/protos/chat_bubble.rb +6 -4
- data/lib/protos/collapse.rb +22 -4
- data/lib/protos/component.rb +10 -34
- data/lib/protos/diff/item.rb +34 -0
- data/lib/protos/diff/resizer.rb +19 -0
- data/lib/protos/diff.rb +30 -0
- data/lib/protos/dropdown/menu.rb +2 -5
- data/lib/protos/list/item.rb +7 -3
- data/lib/protos/list.rb +1 -1
- data/lib/protos/menu/item.rb +23 -0
- data/lib/protos/menu.rb +56 -0
- data/lib/protos/mix.rb +3 -5
- data/lib/protos/popover/content.rb +1 -1
- data/lib/protos/status.rb +46 -0
- data/lib/protos/steps/step.rb +1 -12
- data/lib/protos/table/caption.rb +3 -1
- data/lib/protos/table.rb +8 -6
- data/lib/protos/tabs.rb +24 -18
- data/lib/protos/tailwind_merge.rb +65 -0
- data/lib/protos/theme.rb +29 -28
- data/lib/protos/types.rb +11 -0
- data/lib/protos/version.rb +1 -1
- data/lib/protos.rb +4 -0
- data/protos.gemspec +4 -5
- metadata +17 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b32fe1cc6562526ba55c1d834a5a8964d4ca2073d778f6dee06359ccd80cf802
|
4
|
+
data.tar.gz: c7e29d3aea869133073515fab05cf8c7450e637f83ad138526fe51ecdc72eb2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6767d43e60fc7a1e143f148a34039ba88db6a88ba8ebacb76f8daa5d4bf128f87ec88f318c692d033efd53ffc3c2135686576aa8c8e0d6404af4073f9c7a497
|
7
|
+
data.tar.gz: a0a64cb4af640ca9aae2fd81642cd7206b73f8389e5103f1c288c7d91225d876e7054391fa48585b1d3d7b50d15da671717ab2f7c1bbab103170099bdb78724c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.0.1] - 2025-03-01
|
4
|
+
|
5
|
+
- Fixes a bug with inherited classes not finding their defined keys
|
6
|
+
|
7
|
+
## [1.0.0] - 2025-03-01
|
8
|
+
|
9
|
+
- Adds `Protos::Status` component
|
10
|
+
- Adds `Protos::Diff` component
|
11
|
+
- Adds `Protos::Menu` component
|
12
|
+
- Adds `state` and `icon` options to `Protos::Collapse`
|
13
|
+
- Changes `dash` option to `dashed` on `Protos::Card`
|
14
|
+
- Adds `dashed` and `soft` to `Protos::Badge`
|
15
|
+
- Adds `xl` size to `Protos::Badge`
|
16
|
+
- Updates to Phlex `v2`
|
17
|
+
- Updates to new DaisyUI `v5.0` styles
|
18
|
+
- Performance improvements to `Protos::Theme`
|
19
|
+
- Removes redefining `default_attrs` and `theme` methods. Didn't want the
|
20
|
+
overhead of this completely unused feature. This removes `dry-core` as
|
21
|
+
a dependency
|
22
|
+
|
23
|
+
## [0.7.0] - 2025-01-13
|
24
|
+
|
3
25
|
- Changes passing an `input_id` to accordions. Replaced with the more accurate
|
4
26
|
`input_name` (optional) parameter. There was no point in having different
|
5
27
|
name attributes for the different radio buttons
|
data/README.md
CHANGED
@@ -11,14 +11,12 @@ You can see a full list of the components at
|
|
11
11
|
[tailwind\_merge](https://github.com/gjtorikian/tailwind_merge).
|
12
12
|
- Uses [tippy.js](https://atomiks.github.io/tippyjs/v6/getting-started/) for
|
13
13
|
dropdowns, combobox, and popovers
|
14
|
-
- All components avoid using
|
15
|
-
[`Phlex::DeferredRender`](https://www.phlex.fun/#slots)
|
16
|
-
so you can reorder components exactly how you like them.
|
17
14
|
|
18
15
|
Other Phlex based UI libraries worth checking out:
|
19
16
|
|
20
17
|
- [PhlexUI](https://phlexui.com/)
|
21
18
|
- [ZestUI](https://zestui.com/)
|
19
|
+
- [Nitro Kit](https://github.com/mikker/nitro_kit)
|
22
20
|
|
23
21
|
Thinking of making your next static site using Phlex? Check out
|
24
22
|
[staticky](https://github.com/nolantait/staticky). The protos docs were
|
@@ -206,26 +204,6 @@ The new `css[:item]` slot would be:
|
|
206
204
|
<li class="font-bold">Item 1</li>
|
207
205
|
```
|
208
206
|
|
209
|
-
If you want to change the method we define our default theme under you can
|
210
|
-
override the `theme_method` on the class:
|
211
|
-
|
212
|
-
```ruby
|
213
|
-
class List < Protos::Component
|
214
|
-
theme_method :custom_theme
|
215
|
-
|
216
|
-
# ...
|
217
|
-
|
218
|
-
private
|
219
|
-
|
220
|
-
def custom_theme
|
221
|
-
{
|
222
|
-
list: "space-y-4",
|
223
|
-
item: ["font-bold", "text-2xl"]
|
224
|
-
}
|
225
|
-
end
|
226
|
-
end
|
227
|
-
```
|
228
|
-
|
229
207
|
Slots can also take multiple arguments, and even inline styles:
|
230
208
|
|
231
209
|
```ruby
|
@@ -302,23 +280,6 @@ That would output both controllers to the DOM element:
|
|
302
280
|
This makes it very convenient to add functionality to basic components without
|
303
281
|
overriding their core behavior or having to modify/override their class.
|
304
282
|
|
305
|
-
If we wanted to, just like for our theme we can change the method from
|
306
|
-
`default_attrs` by defining the `default_attrs_method` on the class:
|
307
|
-
|
308
|
-
```ruby
|
309
|
-
class List < Protos::Component
|
310
|
-
default_attrs_method :custom_attrs
|
311
|
-
|
312
|
-
private
|
313
|
-
|
314
|
-
def custom_attrs
|
315
|
-
{
|
316
|
-
data: { controller: "list" }
|
317
|
-
}
|
318
|
-
end
|
319
|
-
end
|
320
|
-
```
|
321
|
-
|
322
283
|
### Params and options
|
323
284
|
|
324
285
|
Components extend
|
@@ -523,16 +484,24 @@ module Components
|
|
523
484
|
end
|
524
485
|
```
|
525
486
|
|
526
|
-
You could use `Proto::List` to create your own list and even use
|
527
|
-
`
|
487
|
+
You could use `Proto::List` to create your own list and even use some kind of
|
488
|
+
[`DeferredRender`](https://www.phlex.fun/miscellaneous/v2-upgrade.html#removed-deferredrender)
|
489
|
+
to make the API more convenient.
|
528
490
|
|
529
491
|
Let's create a list component with headers and actions:
|
530
492
|
|
531
493
|
```ruby
|
494
|
+
module DeferredRender
|
495
|
+
def before_template(&)
|
496
|
+
vanish(&)
|
497
|
+
super
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
532
501
|
module Ui
|
533
502
|
class List < Protos::Component
|
534
503
|
include Protos::Typography
|
535
|
-
include
|
504
|
+
include DeferredRender
|
536
505
|
|
537
506
|
option :title, default: -> {}
|
538
507
|
option :ordered, default: -> { false }
|
@@ -603,8 +572,7 @@ Or here is another example of a table:
|
|
603
572
|
module Ui
|
604
573
|
class Table < ApplicationComponent
|
605
574
|
include Protos::Typography
|
606
|
-
include
|
607
|
-
include Actionable
|
575
|
+
include DeferredRender
|
608
576
|
|
609
577
|
class Column
|
610
578
|
attr_reader :title
|
@@ -622,6 +590,7 @@ module Ui
|
|
622
590
|
option :title, default: -> {}
|
623
591
|
option :collection, default: -> { [] }, reader: false
|
624
592
|
option :columns, default: -> { [] }, reader: false
|
593
|
+
option :actions, default: -> { [] }, reader: false
|
625
594
|
|
626
595
|
def template
|
627
596
|
article(**attrs) do
|
@@ -729,29 +698,29 @@ end
|
|
729
698
|
|
730
699
|
## Missing components
|
731
700
|
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
-
|
736
|
-
- Checkbox
|
737
|
-
- File input
|
738
|
-
- Indicator
|
739
|
-
- Join
|
740
|
-
- Kbd
|
741
|
-
- Link
|
742
|
-
- Loading
|
743
|
-
- Mask
|
744
|
-
- Progress
|
745
|
-
- Radial progress
|
746
|
-
- Radio
|
747
|
-
- Range
|
748
|
-
- Select
|
749
|
-
- Skeleton
|
750
|
-
- Stack
|
751
|
-
- Text input
|
752
|
-
- Textarea
|
753
|
-
- Toggle
|
754
|
-
- Tooltip
|
701
|
+
Here is a list that we don't yet have components for:
|
702
|
+
|
703
|
+
- [ ] Buttons
|
704
|
+
- [ ] Calendar
|
705
|
+
- [ ] Checkbox
|
706
|
+
- [ ] File input
|
707
|
+
- [ ] Indicator
|
708
|
+
- [ ] Join
|
709
|
+
- [ ] Kbd
|
710
|
+
- [ ] Link
|
711
|
+
- [ ] Loading
|
712
|
+
- [ ] Mask
|
713
|
+
- [ ] Progress
|
714
|
+
- [ ] Radial progress
|
715
|
+
- [ ] Radio
|
716
|
+
- [ ] Range
|
717
|
+
- [ ] Select
|
718
|
+
- [ ] Skeleton
|
719
|
+
- [ ] Stack
|
720
|
+
- [ ] Text input
|
721
|
+
- [ ] Textarea
|
722
|
+
- [ ] Toggle
|
723
|
+
- [ ] Tooltip
|
755
724
|
|
756
725
|
## Development
|
757
726
|
|
data/lib/protos/alert.rb
CHANGED
data/lib/protos/avatar.rb
CHANGED
@@ -17,10 +17,6 @@ module Protos
|
|
17
17
|
:diamond,
|
18
18
|
:square,
|
19
19
|
:circle,
|
20
|
-
:parallelogram,
|
21
|
-
:parallelogram2,
|
22
|
-
:parallelogram3,
|
23
|
-
:parallelogram4,
|
24
20
|
:star,
|
25
21
|
:star2,
|
26
22
|
:triangle,
|
@@ -42,10 +38,6 @@ module Protos
|
|
42
38
|
diamond: "mask mask-diamond",
|
43
39
|
square: "mask mask-square",
|
44
40
|
circle: "mask mask-circle",
|
45
|
-
parallelogram: "mask mask-parallelogram",
|
46
|
-
parallelogram2: "mask mask-parallelogram-2",
|
47
|
-
parallelogram3: "mask mask-parallelogram-3",
|
48
|
-
parallelogram4: "mask mask-parallelogram-4",
|
49
41
|
star: "mask mask-star",
|
50
42
|
star2: "mask mask-star-2",
|
51
43
|
triangle: "mask mask-triangle",
|
@@ -58,8 +50,8 @@ module Protos
|
|
58
50
|
|
59
51
|
INDICATORS = {
|
60
52
|
none: "",
|
61
|
-
online: "online",
|
62
|
-
offline: "offline"
|
53
|
+
online: "avatar-online",
|
54
|
+
offline: "avatar-offline"
|
63
55
|
}.freeze
|
64
56
|
|
65
57
|
option :placeholder, type: Types::Bool, default: -> { false }
|
data/lib/protos/badge.rb
CHANGED
@@ -2,22 +2,38 @@
|
|
2
2
|
|
3
3
|
module Protos
|
4
4
|
class Badge < Component
|
5
|
-
|
6
|
-
|
7
|
-
:neutral,
|
8
|
-
:success,
|
9
|
-
:primary,
|
10
|
-
:secondary,
|
11
|
-
:info,
|
12
|
-
:error,
|
13
|
-
:warning,
|
5
|
+
Styles = Types::Coercible::Symbol.enum(
|
6
|
+
*Types::Styles.values,
|
14
7
|
:ghost
|
15
8
|
)
|
16
9
|
|
17
|
-
Sizes = Types::Coercible::Symbol.enum(:default, :xs, :sm, :md, :lg)
|
18
|
-
|
19
|
-
|
10
|
+
Sizes = Types::Coercible::Symbol.enum(:default, :xs, :sm, :md, :lg, :xl)
|
11
|
+
|
12
|
+
STYLES = {
|
13
|
+
default: "",
|
14
|
+
neutral: "badge-neutral",
|
15
|
+
success: "badge-success",
|
16
|
+
primary: "badge-primary",
|
17
|
+
secondary: "badge-secondary",
|
18
|
+
info: "badge-info",
|
19
|
+
error: "badge-error",
|
20
|
+
warning: "badge-warning",
|
21
|
+
ghost: "badge-ghost"
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
SIZES = {
|
25
|
+
default: "badge-md",
|
26
|
+
xs: "badge-xs",
|
27
|
+
sm: "badge-sm",
|
28
|
+
md: "badge-md",
|
29
|
+
lg: "badge-lg",
|
30
|
+
xl: "badge-xl"
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
option :type, type: Styles, default: -> { :default }
|
20
34
|
option :outline, default: -> { false }
|
35
|
+
option :dashed, default: -> { false }
|
36
|
+
option :soft, default: -> { false }
|
21
37
|
option :size, type: Sizes, default: -> { :default }
|
22
38
|
|
23
39
|
def view_template(&)
|
@@ -26,35 +42,15 @@ module Protos
|
|
26
42
|
|
27
43
|
private
|
28
44
|
|
29
|
-
def badge_style
|
30
|
-
{
|
31
|
-
neutral: "badge-neutral",
|
32
|
-
success: "badge-success",
|
33
|
-
primary: "badge-primary",
|
34
|
-
secondary: "badge-secondary",
|
35
|
-
info: "badge-info",
|
36
|
-
error: "badge-error",
|
37
|
-
warning: "badge-warning",
|
38
|
-
ghost: "badge-ghost"
|
39
|
-
}
|
40
|
-
end
|
41
|
-
|
42
|
-
def badge_size
|
43
|
-
{
|
44
|
-
xs: "badge-xs",
|
45
|
-
sm: "badge-sm",
|
46
|
-
md: "badge-md",
|
47
|
-
lg: "badge-lg"
|
48
|
-
}
|
49
|
-
end
|
50
|
-
|
51
45
|
def theme
|
52
46
|
{
|
53
47
|
container: [
|
54
48
|
"badge",
|
55
|
-
|
56
|
-
|
57
|
-
("badge-outline" if outline)
|
49
|
+
STYLES.fetch(type),
|
50
|
+
SIZES.fetch(size),
|
51
|
+
("badge-outline" if outline),
|
52
|
+
("badge-dashed" if dashed),
|
53
|
+
("badge-soft" if soft)
|
58
54
|
].compact
|
59
55
|
}
|
60
56
|
end
|
data/lib/protos/card.rb
CHANGED
@@ -10,20 +10,35 @@ module Protos
|
|
10
10
|
autoload :Actions, "protos/card/actions"
|
11
11
|
autoload :Image, "protos/card/image"
|
12
12
|
|
13
|
-
|
13
|
+
Sizes = Types::Coercible::Symbol.enum(
|
14
|
+
:default,
|
15
|
+
:xs,
|
16
|
+
:sm,
|
17
|
+
:md,
|
18
|
+
:lg,
|
19
|
+
:xl
|
20
|
+
)
|
14
21
|
|
15
|
-
|
16
|
-
default: "",
|
17
|
-
|
18
|
-
|
22
|
+
SIZES = {
|
23
|
+
default: "card-md",
|
24
|
+
xs: "card-xs",
|
25
|
+
sm: "card-sm",
|
26
|
+
md: "card-md",
|
27
|
+
lg: "card-lg",
|
28
|
+
xl: "card-xl"
|
19
29
|
}.freeze
|
20
30
|
|
31
|
+
option :size, type: Sizes, default: -> { :default }, reader: :private
|
32
|
+
option :image_side,
|
33
|
+
type: Types::Bool,
|
34
|
+
default: -> { false },
|
35
|
+
reader: :private
|
36
|
+
option :image_full,
|
37
|
+
type: Types::Bool,
|
38
|
+
default: -> { false },
|
39
|
+
reader: :private
|
21
40
|
option :border, type: Types::Bool, default: -> { true }, reader: :private
|
22
|
-
option :
|
23
|
-
option :image_display,
|
24
|
-
ImageDisplays,
|
25
|
-
default: -> { :default },
|
26
|
-
reader: false
|
41
|
+
option :dashed, type: Types::Bool, default: -> { false }, reader: :private
|
27
42
|
|
28
43
|
def view_template(&)
|
29
44
|
article(**attrs, &)
|
@@ -39,17 +54,15 @@ module Protos
|
|
39
54
|
|
40
55
|
private
|
41
56
|
|
42
|
-
def image_display
|
43
|
-
IMAGE_DISPLAYS.fetch(@image_display)
|
44
|
-
end
|
45
|
-
|
46
57
|
def theme
|
47
58
|
{
|
48
59
|
container: [
|
49
60
|
"card",
|
50
|
-
|
61
|
+
SIZES[size],
|
51
62
|
("card-bordered" if border),
|
52
|
-
("card-
|
63
|
+
("card-dash" if dashed),
|
64
|
+
("image-full" if image_full),
|
65
|
+
("card-side" if image_side)
|
53
66
|
]
|
54
67
|
}
|
55
68
|
end
|
data/lib/protos/carousel.rb
CHANGED
@@ -9,6 +9,12 @@ module Protos
|
|
9
9
|
autoload :Item, "protos/carousel/item"
|
10
10
|
autoload :Actions, "protos/carousel/actions"
|
11
11
|
|
12
|
+
Positions = Types::Coercible::Symbol.enum(
|
13
|
+
:none,
|
14
|
+
:center,
|
15
|
+
:end
|
16
|
+
)
|
17
|
+
|
12
18
|
SNAP_POINTS = {
|
13
19
|
none: "",
|
14
20
|
center: "carousel-center",
|
@@ -19,11 +25,7 @@ module Protos
|
|
19
25
|
option :snap_to,
|
20
26
|
default: -> { :none },
|
21
27
|
reader: false,
|
22
|
-
type:
|
23
|
-
:none,
|
24
|
-
:center,
|
25
|
-
:end
|
26
|
-
)
|
28
|
+
type: Positions
|
27
29
|
|
28
30
|
def view_template(&)
|
29
31
|
div(**attrs, &)
|
@@ -7,29 +7,21 @@ module Protos
|
|
7
7
|
# content of the message. It will be colored according to the type.
|
8
8
|
|
9
9
|
STYLES = {
|
10
|
-
|
11
|
-
primary: "chat-bubble-primary",
|
12
|
-
secondary: "chat-bubble-secondary",
|
10
|
+
default: "",
|
13
11
|
accent: "chat-bubble-accent",
|
12
|
+
error: "chat-bubble-error",
|
14
13
|
info: "chat-bubble-info",
|
14
|
+
neutral: "chat-bubble-neutral",
|
15
|
+
primary: "chat-bubble-primary",
|
16
|
+
secondary: "chat-bubble-secondary",
|
15
17
|
success: "chat-bubble-success",
|
16
|
-
warning: "chat-bubble-warning"
|
17
|
-
error: "chat-bubble-error"
|
18
|
+
warning: "chat-bubble-warning"
|
18
19
|
}.freeze
|
19
20
|
|
20
21
|
option :type,
|
21
|
-
default: -> { :
|
22
|
+
default: -> { :default },
|
22
23
|
reader: false,
|
23
|
-
type: Types::
|
24
|
-
:none,
|
25
|
-
:primary,
|
26
|
-
:secondary,
|
27
|
-
:accent,
|
28
|
-
:info,
|
29
|
-
:success,
|
30
|
-
:warning,
|
31
|
-
:error
|
32
|
-
)
|
24
|
+
type: Types::Styles
|
33
25
|
|
34
26
|
def view_template(&)
|
35
27
|
div(**attrs, &)
|
data/lib/protos/chat_bubble.rb
CHANGED
@@ -12,6 +12,11 @@ module Protos
|
|
12
12
|
autoload :Header, "protos/chat_bubble/header"
|
13
13
|
autoload :Footer, "protos/chat_bubble/footer"
|
14
14
|
|
15
|
+
Positions = Types::Coercible::Symbol.enum(
|
16
|
+
:start,
|
17
|
+
:end
|
18
|
+
)
|
19
|
+
|
15
20
|
ALIGNMENTS = {
|
16
21
|
start: "chat-start",
|
17
22
|
end: "chat-end"
|
@@ -20,10 +25,7 @@ module Protos
|
|
20
25
|
option :align,
|
21
26
|
default: -> { :start },
|
22
27
|
reader: false,
|
23
|
-
type:
|
24
|
-
:start,
|
25
|
-
:end
|
26
|
-
)
|
28
|
+
type: Positions
|
27
29
|
|
28
30
|
def view_template(&)
|
29
31
|
div(**attrs, &)
|
data/lib/protos/collapse.rb
CHANGED
@@ -9,6 +9,23 @@ module Protos
|
|
9
9
|
autoload :Title, "protos/collapse/title"
|
10
10
|
autoload :Content, "protos/collapse/content"
|
11
11
|
|
12
|
+
Icons = Types::Coercible::Symbol.enum(:arrow, :plus)
|
13
|
+
|
14
|
+
ICONS = {
|
15
|
+
arrow: "collapse-arrow",
|
16
|
+
plus: "collapse-plus"
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
States = Types::Coercible::Symbol.enum(:default, :open, :close)
|
20
|
+
|
21
|
+
STATES = {
|
22
|
+
default: "",
|
23
|
+
open: "collapse-open",
|
24
|
+
close: "collapse-close"
|
25
|
+
}.freeze
|
26
|
+
|
27
|
+
option :state, type: States, default: -> { :default }, reader: false
|
28
|
+
option :icon, type: Icons, default: -> { :arrow }, reader: false
|
12
29
|
option :input_type, default: -> { :checkbox }, reader: false
|
13
30
|
option :input_name,
|
14
31
|
reader: false,
|
@@ -23,6 +40,7 @@ module Protos
|
|
23
40
|
id: @input_name,
|
24
41
|
name: @input_name,
|
25
42
|
autocomplete: :off,
|
43
|
+
aria_label: "Toggle accordion",
|
26
44
|
# form: "" prevents the radio button from being submitted if its
|
27
45
|
# within a form
|
28
46
|
form: ""
|
@@ -40,10 +58,10 @@ module Protos
|
|
40
58
|
|
41
59
|
def theme
|
42
60
|
{
|
43
|
-
container:
|
44
|
-
collapse
|
45
|
-
|
46
|
-
|
61
|
+
container: [
|
62
|
+
"collapse",
|
63
|
+
ICONS.fetch(@icon),
|
64
|
+
STATES.fetch(@state)
|
47
65
|
]
|
48
66
|
}
|
49
67
|
end
|
data/lib/protos/component.rb
CHANGED
@@ -5,36 +5,20 @@ module Protos
|
|
5
5
|
# DOCS: Base component for all Protos::Components. You can inherit from this
|
6
6
|
# class to gain flexible components you can style from the outside using css
|
7
7
|
# slots, default attrs and themes.
|
8
|
-
#
|
9
|
-
# This component extends Dry::Initializer and Dry::Core::ClassAttributes to
|
10
|
-
# make configuring each class much easier. It also enables gathering up all
|
11
|
-
# undefined options and adding them to the html_options hash.
|
12
8
|
|
13
9
|
extend Dry::Initializer[undefined: false]
|
14
|
-
extend Dry::Core::ClassAttributes
|
15
|
-
|
16
|
-
# Define methods for css and attrs. Each is expected to return a hash
|
17
|
-
defines :theme_method, type: Types::Symbol
|
18
|
-
defines :default_attrs_method, type: Types::Symbol
|
19
|
-
|
20
|
-
theme_method :theme
|
21
|
-
default_attrs_method :default_attrs
|
22
10
|
|
23
11
|
# Theme can override the css hash and add additional styles
|
24
12
|
option :theme, as: :theme_override, default: -> { {} }, reader: false
|
25
13
|
# Class becomes the :container key in the css hash
|
26
|
-
option :class, as: :container_class, default: -> {
|
27
|
-
option :html_options, default: -> { {} }, reader: false
|
14
|
+
option :class, as: :container_class, default: -> { }, reader: false
|
28
15
|
|
29
16
|
# Adds non-defined options to the html_options hash
|
30
17
|
def initialize(*, **kwargs, &)
|
18
|
+
super
|
31
19
|
defined_keys = self.class.dry_initializer.definitions.keys
|
32
|
-
|
33
|
-
|
34
|
-
.partition { |key, _| defined_keys.include?(key) }
|
35
|
-
.map!(&:to_h)
|
36
|
-
|
37
|
-
super(*, html_options: undefined, **defined, &)
|
20
|
+
extra_keys = kwargs.keys - defined_keys
|
21
|
+
@html_options = kwargs.slice(*extra_keys)
|
38
22
|
end
|
39
23
|
|
40
24
|
private
|
@@ -48,35 +32,27 @@ module Protos
|
|
48
32
|
end
|
49
33
|
|
50
34
|
def build_attrs(...)
|
51
|
-
defaults = if respond_to?(default_attrs_method, :include_private)
|
52
|
-
send(default_attrs_method)
|
53
|
-
end
|
54
|
-
|
55
35
|
Attributes
|
56
36
|
.new(...)
|
57
|
-
.merge(
|
37
|
+
.merge(default_attrs)
|
58
38
|
.merge(@html_options)
|
59
39
|
.merge(class: css[:container])
|
60
40
|
end
|
61
41
|
|
62
42
|
def build_theme(...)
|
63
|
-
component_style = if respond_to?(theme_method, :include_private)
|
64
|
-
send(theme_method)
|
65
|
-
end
|
66
|
-
|
67
43
|
Theme
|
68
44
|
.new(...)
|
69
|
-
.merge(
|
45
|
+
.merge(theme)
|
70
46
|
.merge(@theme_override)
|
71
47
|
.merge(container: @container_class)
|
72
48
|
end
|
73
49
|
|
74
|
-
def
|
75
|
-
|
50
|
+
def default_attrs
|
51
|
+
{}
|
76
52
|
end
|
77
53
|
|
78
|
-
def
|
79
|
-
|
54
|
+
def theme
|
55
|
+
{}
|
80
56
|
end
|
81
57
|
end
|
82
58
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Protos
|
4
|
+
class Diff
|
5
|
+
class Item < Component
|
6
|
+
Order = Types::Coercible::Symbol.enum(:one, :two)
|
7
|
+
|
8
|
+
ORDER = {
|
9
|
+
one: "diff-item-1",
|
10
|
+
two: "diff-item-2"
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
option :order, type: Order, default: -> { :one }, reader: false
|
14
|
+
|
15
|
+
def view_template(&)
|
16
|
+
div(**attrs, &)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def default_attrs
|
22
|
+
{
|
23
|
+
role: :img
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def theme
|
28
|
+
{
|
29
|
+
container: ORDER.fetch(@order)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|