Skip to content

Commit 09b383d

Browse files
authored
Merge pull request #456 from matestack/next-release
1.0.0 Release
2 parents 4a93fd3 + 4849d22 commit 09b383d

File tree

15 files changed

+212
-77
lines changed

15 files changed

+212
-77
lines changed

Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ group :development, :test do
2525
gem 'simplecov', require: false, group: :test
2626
gem 'byebug'
2727
gem 'webmock'
28-
gem 'pry-rails'
29-
gem 'pry-byebug'
3028
gem 'turbolinks'
3129
end
3230

3331
group :test do
32+
gem 'pry-rails'
33+
gem 'pry-byebug'
3434
gem "generator_spec"
3535
gem "rspec-retry" # repeating flaky tests
3636
gem "rspec-wait", "~> 0.0.9"

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
![](https://github.com/matestack/matestack-ui-core/workflows/specs/badge.svg)
1+
[![Specs](https://github.com/matestack/matestack-ui-core/workflows/specs/badge.svg)](https://github.com/matestack/matestack-ui-core/actions)
22
[![Gitter](https://badges.gitter.im/basemate/community.svg)](https://gitter.im/basemate/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
33
[![Gem Version](https://badge.fury.io/rb/matestack-ui-core.svg)](https://badge.fury.io/rb/matestack-ui-core)
44
[![Docs](https://img.shields.io/badge/docs-matestack-blue.svg)](https://docs.matestack.io/docs/guides/1-installation/README.md)
5+
[![Twitter Follow](https://img.shields.io/twitter/follow/matestack.svg?style=social)](https://twitter.com/matestack)
56

67
![matestack logo](./logo.png)
78

89
# matestack-ui-core
910

10-
**Note:**
11-
The master branch is representing the latest release. Currently this is the `1.0.0.rc.1` release. We will publish `1.0.0` in September after a bit more testing.
12-
1311
## Escape the frontend hustle & easily create interactive web apps in pure Ruby
1412

1513
`matestack-ui-core` is a Rails engine for Ruby on Rails developers.
@@ -42,7 +40,6 @@ Documentation can be found [here](https://docs.matestack.io/docs/guides/1-instal
4240

4341
Changelog can be found [here](./CHANGELOG.md)
4442

45-
4643
## Community
4744

4845
As a low-barrier feedback channel for our early users, we have set up a Gitter chat that can be found [here](https://gitter.im/basemate/community). You are very welcome to ask questions and send us feedback there!

app/concepts/matestack/ui/core/isolated/isolated.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class Isolated < Matestack::Ui::Core::Component::Dynamic
44

55
def initialize(*args)
66
super
7-
@public_options = args.map { |hash| hash[:public_options] }[0]
7+
@public_options = args.map { |hash| hash&.dig(:public_options) }[0]
88
end
99

1010
def public_options

app/lib/matestack/ui/core/html_attributes.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def self.included(base)
1919
module ClassMethods
2020

2121
def inherited(subclass)
22+
super
2223
subclass.html_attributes *self.allowed_html_attributes
2324
end
2425

app/lib/matestack/ui/core/properties.rb

Lines changed: 95 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,63 @@ def self.included(base)
1818
module Initializer
1919
def initialize(model=nil, options={})
2020
options = model.dup if options.empty? && model.is_a?(Hash)
21-
required_hooks(options)
22-
optional_hooks(options)
21+
# required_hooks(options)
22+
# optional_hooks(options)
23+
set_values(options) unless options[:skip_set_values]
2324
super
2425
end
2526
end
2627

2728
module ClassMethods
29+
30+
def inherited(subclass)
31+
super
32+
# self.new(nil, skip_set_values: true)
33+
subclass.property_keys *self.all_property_keys
34+
subclass.all_required_properties.concat(self.all_required_properties)
35+
subclass.created_properties.concat(self.created_properties)
36+
end
37+
38+
# contains all property keys, or property hashes regardless of wheter they are optional or required
39+
# used in order to initialize values of properties correctly for subclasses and make properties inheritable
40+
def all_property_keys
41+
@all_properties.flatten!&.uniq! if defined? @all_properties
42+
@all_properties ||= []
43+
end
44+
45+
def all_required_properties
46+
@all_required_properties ||= []
47+
end
48+
49+
def created_properties
50+
@created_properties ||= []
51+
end
52+
53+
# add property keys to array containing all property keys
54+
def property_keys(*attributes)
55+
attributes.each do |attribute|
56+
if attribute.is_a?(Hash)
57+
attribute.each do |temp|
58+
all_property_keys.push({ "#{temp.first}": temp.last})
59+
end
60+
else
61+
all_property_keys.push(attribute)
62+
end
63+
end
64+
end
65+
2866
# define optinoal properties for custom components with `optional :foo, :bar`
2967
def optional(*properties)
68+
property_keys *properties
3069
add_properties_to_list(optional_properties, properties)
70+
optional_hooks
3171
end
3272

3373
# define required properties for custom components with `requires :title, :foo, :bar`
3474
def requires(*properties)
75+
property_keys *properties
3576
add_properties_to_list(requires_properties, properties)
77+
required_hooks
3678
end
3779

3880
def add_properties_to_list(list, properties)
@@ -47,42 +89,73 @@ def add_properties_to_list(list, properties)
4789

4890
# array of properties created from the component
4991
def optional_properties
50-
@component_properties ||= []
92+
@optional_properties ||= []
5193
end
5294

5395
# array of required properties from the component
5496
def requires_properties
5597
@requires_properties ||= []
5698
end
57-
end
5899

59-
def optional_hooks(options)
60-
self.class.optional_properties.compact.each do |prop|
61-
if prop.is_a? Array
62-
hash = prop.flatten
63-
options[hash.last[:as]] = options[hash.first]
64-
prop = hash.last[:as]
100+
def optional_hooks
101+
self.optional_properties.compact.each do |prop|
102+
prop = extract_property_key({}, prop)
103+
define_getter_and_setter_for_property(prop)
65104
end
66-
raise PropertyOverwritingExistingMethodException, "Optional property #{prop} would overwrite already defined instance method for #{self.class}" if self.respond_to? prop
67-
send(:define_singleton_method, prop) do
68-
options[prop]
105+
end
106+
107+
def required_hooks
108+
self.requires_properties.compact.each do |prop|
109+
prop = extract_property_key({}, prop)
110+
self.all_required_properties.push(prop).uniq!
111+
define_getter_and_setter_for_property(prop)
69112
end
70113
end
71-
end
72114

73-
def required_hooks(options)
74-
self.class.requires_properties.compact.each do |prop|
75-
if prop.is_a? Array
115+
def extract_property_key(options, prop)
116+
if prop.is_a?(Array) || prop.is_a?(Hash)
76117
hash = prop.flatten
77-
options[hash.last[:as]] = options[hash.first]
78118
prop = hash.last[:as]
79119
end
80-
raise PropertyMissingException, "Required property #{prop} is missing for #{self.class}" if options[prop].nil?
81-
raise PropertyOverwritingExistingMethodException, "Required property #{prop} would overwrite already defined instance method for #{self.class}" if self.respond_to? prop
82-
send(:define_singleton_method, prop) do
83-
options[prop]
120+
prop
121+
end
122+
123+
def define_getter_and_setter_for_property(prop)
124+
self.created_properties.push(prop)
125+
self.send(:define_method, prop) do
126+
self.instance_variable_get(:"@#{prop}")
127+
end
128+
self.send(:define_method, :"#{prop}=") do |value|
129+
self.instance_variable_set(:"@#{prop}", value)
130+
end
131+
end
132+
133+
def method_added(name)
134+
if all_property_keys.include?(name) && !created_properties.include?(name)
135+
raise PropertyOverwritingExistingMethodException, "Property \"#{name}\" would overwrite already defined instance method for #{self}"
136+
end
137+
end
138+
end
139+
140+
def set_values(options)
141+
self.class.all_property_keys.compact.each do |prop|
142+
value_key = prop
143+
prop = extract_property_key(options, prop)
144+
if self.class.all_required_properties.include?(prop) && options[prop].nil?
145+
raise PropertyMissingException, "Required property #{prop} is missing for #{self.class}"
84146
end
147+
send(:"#{prop}=", options[prop])
148+
end
149+
end
150+
151+
# returns property key and sets alias if hash with as option is given
152+
def extract_property_key(options, prop)
153+
if prop.is_a?(Array) || prop.is_a?(Hash)
154+
hash = prop.flatten
155+
options[hash.last[:as]] = options[hash.first]
156+
prop = hash.last[:as]
85157
end
158+
prop
86159
end
87160

88161
end

docs/guides/1-installation/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Rails 6+ apps, by default, use webpacker, rails 5 apps, by default, use the asse
2727
Add 'matestack-ui-core' to your `package.json` by running:
2828

2929
```
30-
$ yarn add https://github.com/matestack/matestack-ui-core#v1.0.0.rc.1
30+
$ yarn add https://github.com/matestack/matestack-ui-core#v1.0.0
3131
$ yarn install
3232
```
3333

lib/matestack/ui/core/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Matestack
22
module Ui
33
module Core
4-
VERSION = '1.0.0.rc.1'
4+
VERSION = '1.0.0'
55
end
66
end
77
end

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "matestack-ui-core",
3-
"version": "1.0.0-rc.1",
3+
"version": "1.0.0",
44
"main": "app/javascript/matestack-ui-core",
55
"private": true,
66
"dependencies": {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
class Components::Fancy::Card < Matestack::Ui::StaticComponent
22

3+
optional :foobar
34

45
end

0 commit comments

Comments
 (0)