Full Code of basemate/matestack-ui-core for AI

main aaa4800119a7 cached
206 files
302.9 KB
85.2k tokens
527 symbols
1 requests
Download .txt
Showing preview only (352K chars total). Download the full file or copy to clipboard to get everything.
Repository: basemate/matestack-ui-core
Branch: main
Commit: aaa4800119a7
Files: 206
Total size: 302.9 KB

Directory structure:
gitextract_mexlutwf/

├── .dockerignore
├── .gitattributes
├── .gitbook.yaml
├── .github/
│   ├── FUNDING.yml
│   ├── issue_template.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── dockerpush.yml
├── .gitignore
├── .rspec
├── .ruby-version
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── Dockerfile.dev
├── Dockerfile.test
├── Gemfile
├── LICENSE
├── README.md
├── Rakefile
├── bin/
│   └── rails
├── ci/
│   ├── Dockerfile.test_5_2_ruby_2_6
│   ├── Dockerfile.test_6_0_ruby_2_6
│   ├── Dockerfile.test_6_1_ruby_2_7
│   ├── Dockerfile.test_6_1_ruby_3_0
│   ├── Dockerfile.test_7_0_ruby_3_0
│   ├── Gemfile.5.2
│   ├── Gemfile.6.0
│   ├── Gemfile.6.1
│   ├── Gemfile.7.0
│   ├── artifacts/
│   │   └── .keep
│   └── docker-compose.ci.yml
├── docker-compose.yml
├── docs/
│   ├── README.md
│   ├── SUMMARY.md
│   ├── components/
│   │   ├── api.md
│   │   ├── registry.md
│   │   ├── usage-in-isolation.md
│   │   ├── usage-on-matestack-layouts.md
│   │   ├── usage-on-matestack-pages.md
│   │   └── usage-on-rails-views.md
│   ├── getting-started/
│   │   ├── hello-world.md
│   │   └── installation-update.md
│   ├── html-rendering/
│   │   ├── html-rendering.md
│   │   ├── integrating-action-view-helpers.md
│   │   └── reusing-views-or-partials.md
│   ├── layouts/
│   │   ├── api.md
│   │   └── rails-controller-integration.md
│   ├── migrate-from-2.x-to-3.0.md
│   └── pages/
│       ├── api.md
│       └── rails-controller-integration.md
├── entrypoint.sh
├── lib/
│   └── matestack/
│       └── ui/
│           ├── component.rb
│           ├── core/
│           │   ├── base.rb
│           │   ├── component.rb
│           │   ├── context.rb
│           │   ├── helper.rb
│           │   ├── layout.rb
│           │   ├── page.rb
│           │   ├── properties.rb
│           │   ├── slots.rb
│           │   ├── tag_helper.rb
│           │   └── version.rb
│           ├── core.rb
│           ├── layout.rb
│           └── page.rb
├── matestack-ui-core.gemspec
├── results.txt
└── spec/
    ├── core_spec_helper.rb
    ├── dummy/
    │   ├── Rakefile
    │   ├── app/
    │   │   ├── assets/
    │   │   │   ├── config/
    │   │   │   │   └── manifest.js
    │   │   │   └── images/
    │   │   │       └── .keep
    │   │   ├── channels/
    │   │   │   └── application_cable/
    │   │   │       ├── channel.rb
    │   │   │       └── connection.rb
    │   │   ├── controllers/
    │   │   │   ├── application_controller.rb
    │   │   │   ├── concerns/
    │   │   │   │   └── .keep
    │   │   │   ├── demo_core_controller.rb
    │   │   │   └── legacy_views/
    │   │   │       ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │   │       └── pages_controller.rb
    │   │   ├── helpers/
    │   │   │   └── application_helper.rb
    │   │   ├── javascript/
    │   │   │   ├── channels/
    │   │   │   │   ├── consumer.js
    │   │   │   │   └── index.js
    │   │   │   └── packs/
    │   │   │       ├── application.js
    │   │   │       └── application_core.js
    │   │   ├── jobs/
    │   │   │   └── application_job.rb
    │   │   ├── mailers/
    │   │   │   └── application_mailer.rb
    │   │   ├── matestack/
    │   │   │   ├── components/
    │   │   │   │   └── legacy_views/
    │   │   │   │       └── pages/
    │   │   │   │           ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │   │   │           └── viewcontext.rb
    │   │   │   └── demo/
    │   │   │       └── core/
    │   │   │           ├── components/
    │   │   │           │   └── static_component.rb
    │   │   │           ├── layout.rb
    │   │   │           └── pages/
    │   │   │               ├── first_page.rb
    │   │   │               └── second_page.rb
    │   │   ├── models/
    │   │   │   ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │   │   ├── application_record.rb
    │   │   │   ├── concerns/
    │   │   │   │   └── .keep
    │   │   │   ├── dummy_child_model.rb
    │   │   │   ├── dummy_model.rb
    │   │   │   └── test_model.rb
    │   │   └── views/
    │   │       ├── _some_partial.html.erb
    │   │       ├── demo/
    │   │       │   ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │       │   ├── _header.html.erb
    │   │       │   └── header.html.erb
    │   │       ├── layouts/
    │   │       │   ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │       │   ├── application.html.erb
    │   │       │   ├── application_core.html.erb
    │   │       │   └── legacy_views.erb
    │   │       ├── legacy_views/
    │   │       │   └── pages/
    │   │       │       ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │       │       └── viewcontext_custom_component.html.erb
    │   │       ├── rails/
    │   │       │   ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │       │   ├── _some_partial.html.erb
    │   │       │   └── index.html.erb
    │   │       └── some_view.html.erb
    │   ├── bin/
    │   │   ├── bundle
    │   │   ├── rails
    │   │   ├── rake
    │   │   ├── setup
    │   │   ├── update
    │   │   ├── webpack
    │   │   ├── webpack-dev-server
    │   │   └── yarn
    │   ├── config/
    │   │   ├── application.5.2_rb
    │   │   ├── application.6.0_rb
    │   │   ├── application.6.1_rb
    │   │   ├── application.7.0_rb
    │   │   ├── application.rb
    │   │   ├── boot.rb
    │   │   ├── cable.yml
    │   │   ├── database.yml
    │   │   ├── environment.rb
    │   │   ├── environments/
    │   │   │   ├── development.rb
    │   │   │   ├── production.rb
    │   │   │   └── test.rb
    │   │   ├── initializers/
    │   │   │   ├── application_controller_renderer.rb
    │   │   │   ├── assets.rb
    │   │   │   ├── backtrace_silencers.rb
    │   │   │   ├── content_security_policy.rb
    │   │   │   ├── cookies_serializer.rb
    │   │   │   ├── filter_parameter_logging.rb
    │   │   │   ├── inflections.rb
    │   │   │   ├── matestack.rb
    │   │   │   ├── mime_types.rb
    │   │   │   ├── nested_attrs_error_index_patch.rb
    │   │   │   └── wrap_parameters.rb
    │   │   ├── locales/
    │   │   │   └── en.yml
    │   │   ├── puma.rb
    │   │   ├── routes.rb
    │   │   ├── spring.rb
    │   │   ├── storage.yml
    │   │   ├── webpack/
    │   │   │   ├── development.js
    │   │   │   ├── environment.js
    │   │   │   ├── production.js
    │   │   │   └── test.js
    │   │   └── webpacker.yml
    │   ├── config.ru
    │   ├── db/
    │   │   ├── migrate/
    │   │   │   ├── 20190419174203_create_test_models.rb
    │   │   │   ├── 20190427134012_create_dummy_models.rb
    │   │   │   ├── 20190908153924_create_dummy_child_models.rb
    │   │   │   ├── 20200427170812_create_active_storage_tables.active_storage.rb
    │   │   │   ├── 20201222161321_add_boolean_value_to_test_models.rb
    │   │   │   ├── 20210204135043_add_service_name_to_active_storage_blobs.active_storage.rb
    │   │   │   └── 20210204135044_create_active_storage_variant_records.active_storage.rb
    │   │   └── schema.rb
    │   ├── lib/
    │   │   └── assets/
    │   │       └── .keep
    │   ├── log/
    │   │   └── .keep
    │   ├── package.json
    │   ├── postcss.config.js
    │   └── public/
    │       ├── 404.html
    │       ├── 422.html
    │       └── 500.html
    ├── rails_core_spec_helper.rb
    ├── spec_helper.rb
    └── test/
        └── core/
            ├── base/
            │   ├── component/
            │   │   ├── argument_spec.rb
            │   │   ├── conditional_rendering_spec.rb
            │   │   ├── core_namespaces_spec.rb
            │   │   ├── custom_namespaces_spec.rb
            │   │   ├── options_spec.rb
            │   │   ├── partials_spec.rb
            │   │   ├── prepare_spec.rb
            │   │   ├── properties_spec.rb
            │   │   ├── slots_spec.rb
            │   │   ├── static_rendering_spec.rb
            │   │   ├── url_params_access_spec.rb
            │   │   ├── view_context_access_spec.rb
            │   │   └── yield_spec.rb
            │   ├── layout/
            │   │   ├── layout_resolving_spec.rb
            │   │   └── layout_spec.rb
            │   └── page/
            │       ├── controller_instance_access_spec.rb
            │       ├── orchestrates_components_spec.rb
            │       ├── partials_spec.rb
            │       ├── prepare_spec.rb
            │       ├── slots_spec.rb
            │       ├── url_params_access_spec.rb
            │       └── view_context_access_spec.rb
            ├── custom_component_spec.rb
            ├── html_rendering/
            │   ├── action_view_integration.rb
            │   ├── default_tags_spec.rb
            │   └── link_spec.rb
            ├── rails_render_spec.rb
            ├── support/
            │   ├── capybara.rb
            │   ├── core_spec_utils.rb
            │   ├── example_controller.rb
            │   ├── layout.rb
            │   ├── matestack_components_controller.rb
            │   ├── matestack_wrapper_layout.rb
            │   ├── matestack_wrapper_page.rb
            │   ├── test_controller.rb
            │   └── xss.rb
            └── xss_spec.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
node_modules/
spec/dummy/db/*.sqlite3
spec/dummy/db/*.sqlite3-journal
spec/dummy/log/*.log
spec/dummy/node_modules/
spec/dummy/public/packs/
spec/dummy/public/packs-test/
spec/dummy/yarn-error.log
spec/dummy/storage/
spec/dummy/tmp/
builder/db/*.sqlite3
builder/db/*.sqlite3-journal
builder/log/*.log
builder/node_modules/
builder/yarn-error.log
builder/storage/
builder/tmp/
builder/public/packs
.idea/
.vscode
.byebug_history

/coverage


================================================
FILE: .gitattributes
================================================
docs/* linguist-documentation


================================================
FILE: .gitbook.yaml
================================================
root: ./docs/

structure:
  readme: README.md
  summary: SUMMARY.md


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: [matestack]


================================================
FILE: .github/issue_template.md
================================================
<!-- This is a template only, remove/add sections below as appropriate (e.g. for a new feature, there might be no 'current behavior'.) -->

<!-- First indicate whether you want to request an ENHANCEMENT or report a BUG by using the correct Github label in the side panel* -->

**What is the current behavior?**

<!-- add current behavior here -->

**If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug might get fixed faster if we can run your code and it doesn't have extra dependencies. Add a link to a sample repo and/or any relevant code below:**

<!-- add additional links/info here -->

**What is the expected behavior?**

<!-- add expected behavior here -->

**Which versions of Matestack, and which browser/OS are affected by this issue? Did this work in previous versions of Matestack?**

<!-- add version and browser(s) affected, where relevant -->


================================================
FILE: .github/pull_request_template.md
================================================
**Note:** If you submit a feature or bugfix PR, pick **develop** as target branch (and delete this line afterwards).

## Issue https://github.com/matestack/matestack-ui-core/issues/XXX: Short description here

### Changes

- [ ] Describe the changes in one or more bulletpoints

### Notes

- Let the reviewers know something special


================================================
FILE: .github/workflows/dockerpush.yml
================================================
name: specs

on:
  push:
    paths-ignore:
      - 'docs/**'
      - 'README.md'
      - 'CHANGELOG.md'

jobs:
  test_7_0_ruby_3_0:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: |
          docker-compose -f ./ci/docker-compose.ci.yml run --rm test_7_0_ruby_3_0
      - name: Upload lock files
        uses: actions/upload-artifact@v2
        with:
          name: lockfiles_test_7_0_ruby_3_0
          path: |
            ./ci/artifacts/Gemfile.lock
  test_6_1_ruby_3_0:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: |
          docker-compose -f ./ci/docker-compose.ci.yml run --rm test_6_1_ruby_3_0
      - name: Upload lock files
        uses: actions/upload-artifact@v2
        with:
          name: lockfiles_test_6_1_ruby_3_0
          path: |
            ./ci/artifacts/Gemfile.lock
  test_6_1_ruby_2_7:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: |
          docker-compose -f ./ci/docker-compose.ci.yml run --rm test_6_1_ruby_2_7
      - name: Upload lock files
        uses: actions/upload-artifact@v2
        with:
          name: lockfiles_test_6_1_ruby_2_7
          path: |
            ./ci/artifacts/Gemfile.lock
  test_6_0_ruby_2_6:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: |
          docker-compose -f ./ci/docker-compose.ci.yml run --rm test_6_0_ruby_2_6
      - name: Upload lock files
        uses: actions/upload-artifact@v2
        with:
          name: lockfiles_test_6_0_ruby_2_6
          path: |
            ./ci/artifacts/Gemfile.lock
  test_5_2_ruby_2_6:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: |
          docker-compose -f ./ci/docker-compose.ci.yml run --rm test_5_2_ruby_2_6
      - name: Upload lock files
        uses: actions/upload-artifact@v2
        with:
          name: lockfiles_test_5_2_ruby_2_6
          path: |
            ./ci/artifacts/Gemfile.lock


================================================
FILE: .gitignore
================================================
.bundle/
log/*.log
node_modules/
coverage/
spec/dummy/db/*.sqlite3
spec/dummy/db/*.sqlite3-journal
spec/dummy/log/*.log
spec/dummy/node_modules/
spec/dummy/public/packs/
spec/dummy/public/packs-test/
spec/dummy/yarn-error.log
spec/dummy/storage/
spec/dummy/tmp/
.idea/
.vscode
.byebug_history


================================================
FILE: .rspec
================================================
--require spec_helper


================================================
FILE: .ruby-version
================================================
2.6.5


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## v3.0.1 Release - 2022-04-29

### Bugfixes

- fixing layout resolving issue when using the `turbo-rails` gem (like seen in a fresh Rails 7 setup)

## v3.0.0 Release - 2022-03-04

- same as v3.0.0.rc2

## v3.0.0.rc2 Release - 2022-02-15

### Bugfixes

- fixing ActionView integration when using Ruby 3.x

## v3.0.0.rc1 Release - 2022-02-11

- Please read the [migration guide](docs/migrate-from-2.x-to-3.0.md)

## v2.1.1 Release - 2021-06-30

### Bugfixes

- Fixed clientside Data Access form new nested forms

## v2.1.0 Release - 2021-06-28

### Improvements

- Nested Form Support #558
- Component render? Method #553
- Page Component Cleanup
- Docs Cleanup

### Bugfixes

- Form Error Reset #539 via #558
- Form File Upload Init File Value #550


## v2.0.0 Release - 2021-04-12

Please refer to the [migration guide](./docs/migrate-from-1.x-to-2.0.md)

## v1.5.0 Release - 2021-03-07

### Improvements

- NPM package usage

## v1.4.0 Release - 2021-02-05

### Improvements

- Ruby 3 support
- Vue update to 2.6.12
- Vuex update to 3.6.2
- Gemspec update clarifying that Rails below 5.2 is not supported (EOL versions anyway!)
- CI test runs against multiple Rails/Ruby version combination

### Bugfixes

- Webpacker 6 support #500

### Security bumps

- Various version bumps triggered through dependabot

## v1.3.2 Release - 2021-01-11

### Bugfixes

- Fixes #503 new vue-turbolinks v2.2.0 causes error on webpacker compile

### Security bumps

- Various version bumps triggered through dependabot

## v1.3.1 Release - 2020-12-28

### Bugfixes

- Fixes #497 Cable component throws browser error when initial content contains form component

## v1.3.0 Release - 2020-12-22

### Potential breaking change

If you have used a `form_submit` component like this:

```ruby
form_submit do
  button text: "Submit me!", attributes: { "v-bind:disabled": "loading" }
end
```

in order to disable the the button during submission of the form, please turn `loading` into `loading()`:


```ruby
form_submit do
  button text: "Submit me!", attributes: { "v-bind:disabled": "loading()" }
end
```

If you have implemented your own form components, please adjust them as described in the customize section of each form component. Most likely, you now have to provide exactly one root element per form component due to the reworked form components.

### Improvements

- Splitted form API docs into multiple files
- Implements #474 Add HTML `<select>` tag to core components
- Implements #492 Enable extendability of `form_*` components
  - Reworked `form_*` components in order to provide a better API for custom form components
  - `form_*` components are separate Vue.js components now
  - Each `form_*` uses a Vue.js mixin and a Ruby base class. This mixin and base class can be used in custom components in order to easy create own form components

## Bugfixes

- Fixes #490 Custom classes for checkboxes
- Fixes #494 true/false checkboxes are initialized incorrectly


## v1.2.0 Release - 2020-11-20

### Improvements

* Enable usage of Rails view/route helpers on standalone components used via matestack_component helper #476

## v1.1.0 Release - 2020-10-16

### Improvements

* added the `cable` component in order to use ActionCable to update the DOM

## v1.0.1 Release - 2020-10-07

This release contains bugfixes.

### Bugfixes

*  Fixed javascript automatic scroll top on page transition for short pages #462
*  Enable async components on app level, only usable in pages and components before #458
*  Fixed duplicate directory error when using matestack-ui-core with webpacker #460


## v1.0.0 Release - 2020-09-10

Please note that this release contains breaking changes and soft deprecations. To make things easy for users of the current `v0.7.*` version, we have provided **Migration TODOs** at the end of each chapter.

### Migration guide for 0.7.x users

#### 1. Using `render Pages::X` instead of `responder_for(Pages::X)` in controllers

Instead of:

```ruby
class SomeController < ApplicationController
  include Matestack::Ui::Core::ApplicationHelper

  def some_page
    responder_for(Pages::SomePage)
  end

end
```

write now:

```ruby
class SomeController < ApplicationController
  include Matestack::Ui::Core::ApplicationHelper

  def some_page
    render Pages::SomePage
  end

end
```

Please note that while the `responder_for` method is still being supported, it will be removed in a future release.

**Migration TODOs:**

- [ ] Replace `responder_for` with `render` in your controllers

#### 2. App/Page structure and namespacing

Until `0.7.x`, matestack-ui-core enforced the user to keep apps and pages in a specific folder structure. An app like `Apps::MyApp` had to be stored in `app/matestack/apps/my_app.rb` and an associated page like `Pages::MyApp::MyPage` lived in `app/matestack/pages/my_app/my_page.rb`. The namespace `Pages::MyApp` determined that the page `MyPage` should be wrapped with the layout coming from `Apps::MyApp`.

We changed this behavior in favor of more intuitive namespacing and more control/flexibility on namespaces and folder structure:

**Flexible folder structure and namespacing of apps and pages**

Apps and pages can now actually live anywhere within your project - but we still recommend sticking to some best practices, shown further below. The relation between apps and pages is no longer derived from the (folder) namespace.

**Explicit app/page relation on controller level**

Within a controller, you can now set the desired `matestack_app` that then wraps all pages used in this controller. This definition is inheritable - therefore, you can set in on an `ApplicationController` to make it a default for all controllers and actions, and overwrite it if needed.

Both "global" and "controller-level" `matestack_app` settings can be overwritten on "action-level" using an additional parameter for the `render` method.

The code snippet below shows some common use cases:

```ruby
class SomeController < ApplicationController
  include Matestack::Ui::Core::ApplicationHelper

  matestack_app MyApp #default for all action on this controller and inherited ones

  def some_page
    render SomePage
  end

  def some_page_with_other_app
    render SomePage, matestack_app: SomeOtherApp #overwrite controller level matestack_app
  end

  def some_page_with_other_app
    render SomePage, matestack_app: :none #overwrite controller level matestack_app and set to no app at all
  end

end
```

**Default App**
If no `matestack_app` is defined or it is deliberately set to `:none` as demonstrated above, matestack-ui-core will by default render the page wrapped by a minimal app. This happens in order to provide basic app-related matestack-ui-core features like `transition` and others.

It is possible to explicitly prevent this behavior by setting `matestack_app` to false:

```ruby
class SomeController < ApplicationController
  include Matestack::Ui::Core::ApplicationHelper


  def some_page
    render SomePage #will render with minimal default app if no app is specified on action or controller level
  end

  def some_page_with_no_app
    render SomePage, matestack_app: false #set to no app at all
  end

end
```

**Recommended best practice for app/page folder structure and namespacing**

Imagine your project has two "apps". An "admin" area and a public "website" area. Your folder structure could look like this:

```
app/matestack/
|
└───admin/
│   │   app.rb (`Admin::App < Matestack::Ui::App`)
│   └───pages/
│   │   │   dashboard.rb  (`Admin::Pages::Dashboard < Matestack::Ui::Page`)
|
└───website/
│   │   app.rb (`Website::App < Matestack::Ui::App`)
│   └───pages/
│   │   │   home.rb  (`Website::Pages::Home < Matestack::Ui::Page`)
```

and your corresponding controllers could look like this:

`app/controllers/admin_controller.rb`

```ruby
class AdminController < ApplicationController
  include Matestack::Ui::Core::ApplicationHelper

  matestack_app Admin::App

  before_action :authenticate_admin! # for example

  def dashboard
    render Admin::Pages::Dashboard
  end

end
```

`app/controllers/website_controller.rb`

```ruby
class WebsiteController < ApplicationController
  include Matestack::Ui::Core::ApplicationHelper

  matestack_app Website::App

  def home
    render Website::Pages::Home
  end

end
```

**Migration TODOs:**

You can decide to either
- [ ] keep the `0.7.x` folder structure if you want
- [ ] and set the related app on your controllers via `matestack_app` (as it will no longer be derived automatically from the page namespace)

or

- [ ] refactor your app/page structure according to your needs, and set the related apps on a controller level

#### 3. Base component class name adjustments

We decided to rename the base component class names in order to create a better understanding of what they are:

* `Matestack::Ui::StaticComponent` --> `Matestack::Ui::Component`
* `Matestack::Ui::DynamicComponent` --> `Matestack::Ui::VueJsComponent`

**Migration TODOs:**

You can decide to either
- [ ] we still keep the old class names, but we recommend to adjust the base class names as described above

#### 3. Explicit component registration

A major change happened to the component resolving approach. Until `0.7.x`, matestack-ui-core automatically translated core component calls like `some_component` to a class like `Matestack::Ui::Core::Some::Component`, which had to be defined within the core library at `CORE_ROOT/app/concepts/matestack/ui/core/some/component.rb`. The same applied for custom component calls like `custom_my_component` which resolved to a class `Components::My::Component` which had to be defined within the user's application at `APP_ROOT/app/matestack/components/my/component.rb`.

This auto resolving is being completely removed in the `1.0.0` release. All components (core, custom and add-on-engine) have to be registered explicitly as described below:

*Core components*

`CORE_ROOT/lib/matestack/ui/core/components.rb`

```ruby
module Matestack::Ui::Core::Components
  #...
  require_core_component "some/new/component"
  #...
end

Matestack::Ui::Core::Component::Registry.register_components(
  #...
  some_new_component: Matestack::Ui::Core::Some::New::Component,
  #...
)
```

The registered DSL method `some_new_component` does not have to match the components namespace structure.

*Custom components*

Create a registry module like:

`APP_ROOT/app/matestack/components/registry.rb`

```ruby
module Components::Registry

  Matestack::Ui::Core::Component::Registry.register_components(
    #...
    my_component: Components::MyOwnComponent,
    #...
  )

end
```

and make sure to include this module in your base controller like:

```ruby
class ApplicationController < ActionController::Base

  include Matestack::Ui::Core::ApplicationHelper
  include Components::Registry

end
```

Like in the core, the registered DSL method `my_component` does not have to match the component's namespace structure. In this example, the custom `MyOwnComponent` lives in `app/matestack/components/my_own_component.rb` and is being referenced as `my_component`.

TBD:

Please be aware that once the component registry was loaded, the initially registered dsl_methods are cached. Removing a dsl_method from the registry will not have an effect until the server gets reloaded. Added dsl_methods however will be available without having to restart the server.

*AddOn engine component*

TODO

**Migration TODOs:**

If you are already using custom components:
- [ ] Add a component registry in `APP_ROOT/app/matestack/components/registry.rb`
- [ ] Register your existing components like `    my_component: Components::MyOwnComponent`, respecting their namespaces and setting dls_methods of your choice. The obligation of prefixing them with a `custom_` does no longer apply.
- [ ] Since the new dls_methods may differ from the former method calls, you need to refactor the custom component usage on existing apps and pages (e.g. formerly `custom_my_own_component` should now be called `my_component`)

#### 4.1 Dynamic (Vue.js) core component naming

Until `1.0.0`, dynamic core components created the Vue.js component name automatically by deriving it from their class name. `Matestack::Ui::Core::Collection::Filter::Filter`, for example, was translated to the Vue.js componente name `matestack-ui-core-collection-filter`. The two occurrences of `Filter` at the end of the class name (which comes from the folder structure and namespacing constraints) was automatically detected and taken care of, so the Vue.js component name only had one occurrence of `filter` in it.

This behavior changes in `1.0.0`:

* `Matestack::Ui::Core::Collection::Filter::Filter` will be translated to `matestack-ui-core-collection-filter-filter` without any further processing per default
* It is now possible to set the Vue.js component name manually within the component configuration:

```ruby
class Matestack::Ui::Core::Collection::Filter::Filter < Matestack::Ui::VueJsComponent
  vue_js_component_name "matestack-ui-core-collection-filter"

  #...

end
```

**Migration Todos:**

Core developers only:
-[ ] set Vue.js component name explicitly in order to match current Vue.js component names of all dynamic core components

#### 4.2 Dynamic (Vue.js) custom component naming

Formerly, custom components behaved differently than core components. `Components::Some::Component` was translated to a Vue.js component named `custom-some-component`, in order to match their (now changed) dsl method name `custom_some_component`

This behavior changes in `1.0.0`:

* Without any further default processing, `Components::Some::Component` will be translated into `components-some-component`
* It is now possible to set the Vue.js component name manually:

```ruby
class Components::Some::Component < Matestack::Ui::VueJsComponent
  vue_js_component_name "some-component"

  #...

end
```

**Migration Todos:**

Please note that you have two options, but an action is required to make the new release work with existing custom dynamic components. Either you

- [ ] set Vue.js component name explicitly in order to match current Vue.js component naming of all custom components

OR

- [ ] adapt the name of your custom Vue.js components to the new naming schema demonstrated above


#### 5. No more components block wrapping in Pages/Components/Apps

Instead of:

```ruby
def response
  components {
    div do
      plain "hello!"
    end
  }
end
```

you can now write:

```ruby
def response
  div do
    plain "hello!"
  end
end
```

Please note that the `components` block is still supported, but will be removed in a `1.0` release.

**Migration Todos:**

- [ ] To be on the safe side, remove all the `components {}` wrapping blocks in your apps and pages


#### 6. Partials are now normal method calls and don't need a block

Instead of writing:

```ruby
def response
  components {
    div do
      partial :my_partial, "foo"
    end
  }
end

def my_partial param
  partial {
    plain param
  }
end
```

you can now write:

```ruby
def response
  div do
    my_partial "foo" #normal method call with optional params
  end
end

def my_partial param
  plain param # no more partial {} block
end
```

Please note that the old `partial` block and method call approach are still supported but will be removed in a `1.0` release.

**Migration Todos:**

- [ ] To be on the safe side, remove all the `partial {}` wrapping blocks in the partials on your apps, pages and custom components

#### 7. Slot syntax stays the same

We still need the `slot` block wrapping around slot content

```ruby
def response
  div do
    some_static_component my_first_slot: my_simple_slot
  end
end

def my_simple_slot
  slot do
    span id: "my_simple_slot" do
      plain "some content"
    end
  end
end
```

#### 8. `page_content` should now be `yield_page`

We changed the naming to be more expressive and in order to align with the existing `yield_components`

**Migration Todos:**

- [ ] On an app layout, you should now use `yield_page` instead of `page_component`

#### 9. Wrapping DOM structure of pages has changed

We changed the DOM structure around pages in order to enable better page loading state implementations.
We also changed the class names of these wrapping divs in order to better match css naming conventions

```html
<!-- some layout markup -->
<div class="matestack-page-container">
  <div class="matestack-page-wrapper">
    <div><!--this div is necessary for conditional switch to async template via v-if -->
      <div class="matestack-page-root">
        your page markup
      </div>
    </div>
  </div>
</div>
<!-- some layout markup -->
```

**Migration Todos:**

- [ ] If you used the old DOM structure and css class names of the wrapping elements for styling, please adjust your CSS accordingly

#### 10. `yield_page` can now take a loading_state slot

In order to simplify the implementation of page loading state effects, we added an optional loading_state slot for `yield_page`:

`app/matestack/example_app/app.rb`

```ruby
class ExampleApp::App < Matestack::Ui::App

  def response
    # some layout stuff
    main do
      yield_page slots: { loading_state: my_loading_state_slot }
    end
    # some layout stuff
  end

  def my_loading_state_slot
    slot do
      span class: "some-loading-spinner" do
        plain "loading..."
      end
    end
  end

end
```

which will render:

```html
<main>
  <div class="matestack-page-container">
    <div class="loading-state-element-wrapper">
      <span class="some-loading-spinner">
        loading...
      </span>
    </div>
    <div class="matestack-page-wrapper">
      <div><!--this div is necessary for conditional switch to async template via v-if -->
        <div class="matestack-page-root">
          your page markup
        </div>
      </div>
    </div>
  </div>
</end>
```

and during async page request triggered via transition:

```html
<main>
  <div class="matestack-page-container loading">
    <div class="loading-state-element-wrapper loading">
      <span class="some-loading-spinner">
        loading...
      </span>
    </div>
    <div class="matestack-page-wrapper loading">
      <div><!--this div is necessary for conditional switch to async template via v-if -->
        <div class="matestack-page-root">
          your page markup
        </div>
      </div>
    </div>
  </div>
</end>
```

You can use the `loading` class and your loading state element to implement CSS based loading state effects.

#### 11. `async` component now requires an ID

We changed the way how matestack resolves the content of an `async` component on rerender calls. It is now required to apply an ID to the `async` component

```ruby
async rerender_on: "some-event", id: "my-unique-id" do
  plain hello!
end
```

**Migration Todos:**

- [ ] Please add an unique ID to each `async` component usage, even if matestack is currently auto-generating an ID if not applied. This will be removed in future releases

#### 12. New `toggle` component is replacing `async` shown_on, hide_on, hide_after...

We decided to move all pure clientside view state manipulation logic from the `async` component to a new component called `toggle`. `async` should now only take care of serverside rerendering based on events.

```ruby
async show_on: "some-event" do
  plain hello!
end
# should now be:
toggel show_on: "some-event" do
  plain hello!
end
```

**Migration Todos:**

- [ ] Please use the new `toggle` component wherever you used `async show_on/hide_on/hide_after`

#### 13. `async` DOM structure and loading state

The `async` components wrapping DOM structure has changed in order to align with the wrapping DOM structure of pages and isolated components:

```ruby
async rerender_on: "some-event", id: "my-unique-id" do
  plain hello!
end
```

will render to:

```html
<div class="matestack-async-component-container">
  <div class="matestack-async-component-wrapper">
    <div id="my-unique-id" class="matestack-async-component-root">
      hello!
    </div>
  </div>
</div>
```

and during rerender:

```html
<div class="matestack-async-component-container loading">
  <div class="matestack-async-component-wrapper loading">
    <div id="my-unique-id" class="matestack-async-component-root" >
      hello!
    </div>
  </div>
</div>
```

**Migration Todos:**

- [ ] If you used the old DOM structure and css class names of the wrapping elements for styling, please adjust your CSS accordingly


#### 14. `form` component changes

We reworked the form components quite a bit:

- `include` keyword is no longer required
- `form_input` component no longer supports the input type textarea.
- Textareas were extracted in a component and can be used as standalone`textarea` or in forms with `form_textarea`.
- `form_input`component now supports all types according to W3Cs possible types.
- `form_select` is now only used for HTML select dropdowns
- `form_radio` is used for rendering radio button inputs
- `form_checkbox` is used for rendering checkbox inputs, either a single (true/false) checkbox or multiple checkboxes
- options passed as hashes in to `form_select`, `form_radio` and `form_checkbox` are now expected to be { label_value: input_value } and thus the other way around. Until 0.7.6 it was { input_value: label_value }
- and added a lot of new features, such as customizing the error rendering.

We invested a lot of time to improve the `form` API docs found [here](/docs/api/100-components/form.md).

- [ ] Please make sure to read through the docs and migrate your forms accordingly!

#### 15. New approach towards isolated components

We completely rethought the way we approached isolated components.

The old approach:

```ruby
def response
  #...
  isolate :my_isolated_scope
  #...
end

def my_isolated_scope
  isolate {
    plain "I'm isolated"
  }
end
```
is removed.

Instead, we created a new component class `Matestack::Ui::IsolatedComponent`. You can build custom component which inherits from this class in order to create components, which will be resolved completely isolated on rerender calls:

```ruby
class MyPage < Matestack::Ui::Page

  def response
    #...
    my_isolated_component defer: true, public_params: { id: 1 }
    #...
  end

end
```

```ruby
class MyIsolatedComponent < Matestack::Ui::IsolatedComponent

  def prepare
    my_model = MyModel.find public_params[:id]
  end

  def response
    div do
      plain "#{my_model} was resolved isolated within in a separate http request after page load"
    end
  end

  def authorized?
    true
    # check access here using current_user for example when using Devise
    # true means, this isolated component is public
  end
end
```

Using an isolated component with `defer` speeds up the init page load on complex UIs.

**Migration Todos:**

- [ ] Create custom isolated components wherever you used the old approach towards isolate

#### 16. Params access from apps, pages and components

In order to access to request params like we do on controller level, we added the `params` method to apps, pages and components:

```ruby
def response
  plain context[:params][:id]
  #or
  plain @url_params[:id]
end

# should now be:
def response
  plain params[:id]
end
```

**Migration Todos:**

- [ ] Switch to the new `params` method in order to access request params. `@url_params` will be deprecated in future releases

#### 16. LICENSE change

As we're performing a major release from 0.7.6 to 1.0.0, we're able to switch the license. We decided to go for the [LGPLv3 license](http://www.gnu.org/licenses/lgpl-3.0.html) following the example of Sidekiq or Trailblazer. That won't have an effect on users of our library as long as you're just using `matestack-ui-core` and not creating/publishing a derivative work. You can use `matestack-ui-core` in commercial closed source applications without any issues.Trailblazer has a comprehensive article on that [topic](https://trailblazer.to/2.1/docs/pro.html#pro-license).

Our goal is to create a sustainable open source project. Therefore we need to secure funding. Selling commercial licenses on top of the LGPLv3 license for companies wanting to create/sell closed source derivative work of `matestack-ui-core` should be one pillar of that funding.

#### 17. Wrap-up

After following all the **Migration Todos**, your application should work just fine. If that's not the case, please [open a GitHub issue](https://github.com/matestack/matestack-ui-core/issues/new) and/or improve this guide!

### Improvements

#### Using matestack components in Rails Views

It is now possible to use `matestack-ui-core` core and custom components in your Rails legacy views. Matestack provides a `matestack_component` helper to use components in views and partials.

Create a custom component like
```ruby
class HeaderComponent < Matestack::Ui::Component
  requires :title

  def response
    header id: 'my-page-header', text: title
  end

end
```

and register it in your registry
```ruby
module Components::Registry
  Matestack::Ui::Core::Component::Registry.register_components(
    header_component: HeaderComponent,
  )
end
```

Now, you can go ahead and use it in your views as shown below, even passing arguments works:
```html
<%= matestack_component(:header_component, title: 'A Title') %>
```

### Using Rails Views in Matestack Pages/Components

To render existing rails views inside your components or pages, use the new `rails_view` component. It replaces the old `html` component.
You can render existing partials and views with this helper anywhere in your app. For further information read the `rails_view` documentation.

Let's say you have an old view file in `app/views/example/partial.html.erb`

```html
<p>An example text in a Rails view</p>
```

You could go ahead and re-use it in a component (or simply add it to a page) like:
```ruby
class TextComponent < Matestack::Ui::Component

  def response
    paragraph text: 'Example text directly in the component'
    rails_view path: `example/partial.html.erb`
  end

end
```

### Collection select



### Removed Components

#### 1. Inline Component

The Form Inline Component has been removed and can no longer be used.

#### 2. Absolute Component

The Absolute Component has been removed and can no longer be used.

## v0.7.6 - 2020-05-06

[Merged PRs](https://github.com/basemate/matestack-ui-core/pulls?q=is%3Apr+is%3Aclosed+milestone%3A0.7.6)

[Solved Issues](https://github.com/basemate/matestack-ui-core/issues?q=is%3Aissue+is%3Aclosed+milestone%3A0.7.6)

### Security Fixes

* Various dependency version bumps by dependabot

### Bugfixes

* Radio button groups with same values on single page #399
* Async rerendered components have access to ActionView context #405
* Transition component `active` class fixed #408 #410
* Query params were missing in async page load request when using browser history navigation #409

### Improvements

* Apps now have access to ActionView context #405
* Transition component `active-child` class added #410
* Added specs for ActionView context access #411
* Added file upload feature to form (single and multiple) #413
* Added form, transition, action `delay` option #412
* Added form, action `emit` option #412
* Added multi event listening to `async` component option #412 #147
* Added Rails 6 support
* Updated core dev and test environment to Rails 6
* Added form/action `redirect_to` option #415

## v0.7.5 - 2020-03-11

[Merged PRs](https://github.com/basemate/matestack-ui-core/pulls?q=is%3Apr+is%3Aclosed+milestone%3A0.7.5)

[Solved Issues](https://github.com/basemate/matestack-ui-core/issues?q=is%3Aissue+is%3Aclosed+milestone%3A0.7.5)

### Security Fixes

* Various dependency version bumps by dependabot

### Improvements

* Added `datalist` component
* Added `range` type for `form_input`
* Integrated generator specs in CI spec run
* Added `turbolinks` support
* Form component: Add support for `redirect_to` in the controller
* HasViewContext: Check in advance whether the view context would respond to a missing method.

### Bugfixes

* Fixed broken history button behavior introduced in `0.7.4` #386

## v0.7.4 2020-02-10

[Merged PRs](https://github.com/basemate/matestack-ui-core/pulls?q=is%3Apr+is%3Aclosed+milestone%3A0.7.4)

[Solved Issues](https://github.com/basemate/matestack-ui-core/issues?q=is%3Aissue+is%3Aclosed+milestone%3A0.7.4)

### Security Fixes

XSS/Script injection vulnerablilty fixed in 0.7.4

* matestack-ui-core was vulnerable to XSS/Script injection
* matestack-ui-core did not escape strings by default and did not cover this in the docs
* matestack-ui-core should have escaped strings by default in order to prevent XSS/Script injection vulnerability
* 0.7.4 fixes that by performing string escaping by default now
* a new component `unescaped` (like `plain` before) allows to render unescaped strings, but forces the developer to explicitly make a concious decision about that

```ruby
class Pages::MyApp::MyExamplePage < Matestack::Ui::Page

  class FakeUser < Struct.new(:name)
  end

  def prepare
    @user = FakeUser.new("<script>alert('such hack many wow')</script>")
  end

  def response
    components {
      div do
        heading size: 1, text: "Hello #{@user.name}" # was not escaped , from 0.7.4 on it's escaped
        plain "Hello #{@user.name}" # was not escaped, from 0.7.4 on it's escaped
        unescaped "Hello #{@user.name}" # is not escaped, as intended
      end
    }
  end
end

```

Affected Versions

<= 0.7.3

Patched Versions

>= 0.7.4 --> please update!

Workarounds

escape string explicitly/manually

reported by @PragTob

### Improvements

* On form submit, matestack form values are reset to previous values by fiedl

--> The form component now does not reset itself when using `put`

--> The reset behavior can now be configured (described in `form` component docs)

* Dockerized core dev and test environment by jonasjabari

--> easy local dev and test setup, cross-platform default for dev and testing

--> CI is configured to run tests via dockerized test suite; same as local testing and good base for matrix testing (upcoming)

--> Usage described in contribution docs

* Add `follow_response` option to action component by fiedl

--> same behavior enhancement as added to the `form` component in 0.7.3

--> server may now decide where the transition should navigate to

--> described in `action` component docs

* Add confirm option to action component by fiedl

--> easily add confirmation before performing an action

--> prevent unintended delete action for example

--> described in `action` component docs

* New webpacker features by fiedl

  * make webpacker create es5 code instead of es6 code

  * Switch to Vue Production Mode if RAILS_ENV=staging or production

  * Establish webpack(er) and asset-pipeline workflows

--> webpacker now builds assets for asset pipline usage AND webpacker usage (both usage approaches are described in the installation docs)

--> webpacker now builds minified versions of matestack-ui-core.js (great improvement in file size!)

--> webpacker now builds es5 code, which is compatible with IE11

--> when used via asset pipeline, the minified version of matestack-ui-core together with the production build of vue.js is automatically required

--> when used via webpacker, matestack-ui-core can be used within a modern javascript workflow, importing and extending
single matestack module for example

* New components
  * Add HTML `<picture>` tag to core components by pascalwengerter
  * Add HTML `<option>` tag to core components by pascalwengerter
  * Add HTML `<optgroup>` tag to core components by pascalwengerter
  * Add HTML `<iframe>` tag to core components by pascalwengerter
  * Add HTML `<dfn>` tag to core components by pascalwengerter
  * Add HTML `<del>` tag to core components by pascalwengerter
  * Add HTML `<data>` tag to core components by pascalwengerter
  * Add HTML `<bdo>` tag to core components by pascalwengerter
  * Add HTML `<bdi>` tag to core components by pascalwengerter
  * Add HTML `<wbr>` tag to core components by pascalwengerter
  * Add HTML `<samp>` tag to core components by pascalwengerter
  * Add HTML `<u>` tag to core components by pascalwengerter
  * Add HTML `<template>` tag to core components by pascalwengerter


### Bugfixes

* Anchor Link Click triggers full page transition by PragTob


## v0.7.3 - 2019-11-10

[Merged PRs](https://github.com/basemate/matestack-ui-core/pulls?q=is%3Apr+is%3Aclosed+milestone%3A0.7.3)

[Solved Issues](https://github.com/basemate/matestack-ui-core/issues?q=is%3Aissue+is%3Aclosed+milestone%3A0.7.3)

### Potential Breaking Change - Migration Note

Until `0.7.2.1`, we included all `ActionView` modules in `Matestack::Ui::StaticComponent` and `Matestack::Ui::DynamicComponent`. As we didn't use these modules in all of our core components, we decided to move the `ActionView` modules to the new `Matestack::Ui::StaticActionviewComponent` and `Matestack::Ui::DynamicActionviewComponent` class. If you use `ActionView` modules in your components, you have to change the class you inherit from. This might be a potential breaking change for some users - we are not bumping to 0.8.0 as we don't break explicit specified behavior. If you have any problems, reach out via gitter!

### Security Fixes

none

### Improvements

* Move ActionView dependencies to separate, custom-core-component by pascalwengerter
* Add documentation for testing on macOS by marcoroth
* Add HTML `<ruby>` tag to core components by stiwwelll
* Add HTML `<rt>` tag to core components by stiwwelll
* Add HTML `<rp>` tag to core components by stiwwelll
* Add HTML `<q>` tag to core components by GrantBarry
* Add HTML `<pre>` tag to core components by tae8838
* Add HTML `<param>` tag to core components by marcoroth
* Add HTML `<output>` tag to core components by marcoroth
* Add HTML `<object>` tag to core components by pascalwengerter
* Add HTML `<noscript>` tag to core components by stiwwelll
* Add HTML `<meter>` tag to core components by bdlb77
* Add HTML `<mark>` tag to core components by marcoroth
* Add HTML `<map>` tag to core components by pascalwengerter
* Add HTML `<legend>` tag to core components by stiwwelll
* Add HTML `<kbd>` tag to core components by marcoroth
* Add HTML `<ins>` tag to core components by lumisce
* Add HTML `<figure>` tag to core components by lumisce
* Add HTML `<em>` tag to core components by citizen428
* Add HTML `<dt>` tag to core components by mayanktap
* Add HTML `<dl>` tag to core components by mayanktap
* Add HTML `<dd>` tag to core components by mayanktap
* Add HTML `<code>` tag to core components by pascalwengerter
* Add HTML `<cite>` tag to core components by cameronnorman
* Add HTML `<var>` tag to core components by pascalwengerter
* Add HTML `<s>` tag to core components by Manukam
* Add HTML `<bold>` tag to core components by GrantBarry
* Add HTML `<area>` tag to core components by pascalwengerter
* Add tests for video component by MarcoBomfim
* Usage of RecordTagHelper by pascalwengerter
* Add HTML `<aside>` tag to core components by borref
* Add HTML `<address>` tag to core components by michaelrevans
* Add HTML `<sup>` tag to core components by borref
* Add params options to link component documentation by pascalwengerter

### Bugfixes

* Unexpected behavior when creating a record in progress by jonasjabari
* couldn't find file 'matestack_ui_core_manifest.js' on dummy app by jonasjabari
* Add For Attribute to Stand Alone Label Component by bdlb77
* Form component doesn't work on component-level by jonasjabari
* Async component doesn't work on component-level by jonasjabari


## v0.7.2.1 - 2019-09-10

[Merged PRs](https://github.com/basemate/matestack-ui-core/milestone/5?closed=1)

### Security Fixes

- Dependency version bump (nokogiri) by dependabot

### Bugfixes

- Fixed image component 157 #158 by jonasjabari

## v0.7.2 - 2019-09-05

[Merged PRs](https://github.com/basemate/matestack-ui-core/milestone/4?closed=1)

### Security Fixes

- Various dependency version bumps by dependabot

### Improvements

- Add Isolation Component #154 by jonasjabari
- Update integration docs #149 by pascalwengerter
- Add youtube component #144 by pascalwengerter
- Support new Doc App #143 by jonasjabari
- Add class option to dropdown form selects  enhancement#135 by 3wille
- Refactor core components v2  enhancement#134 by pascalwengerter
- add sub tag  enhancement#132 by pascalwengerter
- Add article component with docs and specs #127 by michaelrevans
- Add address tag, specs and documentation #126 by michaelrevans
- Extra table components #125 by michaelrevans
- Add abbr component with specs and documentation #124 by michaelrevans
- Add article component with docs and specs #122 by michaelrevans
- Add address tag, specs and documentation #121 by michaelrevans
- Add abbr component #120 by michaelrevans
- Add thead, tbody and tfoot components

### Bugfixes

- Add init_show state to async component 140 #152 by jonasjabari
- added missing @tag_attributes #151 by jonasjabari
- update yarn and fix controller action name #141 by pascalwengerter

## v0.7.1 - 2019-08-01

[Merged PRs](https://github.com/basemate/matestack-ui-core/milestone/3?closed=1)

### Improvements

- Introduce scaffolder #72 by PasWen
- Make buttons disableable  enhancement by PasWen
- Collection Component #98 by jonasjabari
- Added Async Defer Feature #100 by jonasjabari
- Added blockquote tag to main component #88 by cameronnorman
- Added small tags #87 by cameronnorman
- Added strong tag #93 by cameronnorman
- Added Infos that async component can currently only be used on page leve #85 by jonasjabari was merged 10
- Update span component in 0.7.0 #74 by PasWen
- Add documented, untested video component #70 by PasWen
- Added summary details components #76 by bdlb77
- Add caption with doc and specs  enhancement #68 by michaelrevans

### Bugfixes

- Fixed Link Component #84 by jonasjabari

## v0.7.0 - 2019-06-25

### Breaking changes for users

* new base class names for pages, components and apps, issue #36 (@jonasjabari)
* simplified custom component structure/class names #39 (@jonasjabari)
* improved vue.js component naming convention #41 (@jonasjabari)
* `pg` component is now called `paragraph`, issue #47, pull #48 (@PasWen)

### Improvements for users

* added `hr` component, pull #49, (@michaelrevans)
* allow actions to accept id and class attributes, issue #44, pull #50 (@michaelrevans)

### Breaking changes for core developers

* namespaced core components using `Matestack::Ui::Core` module/folder, pull #64 (@jonasjabari)
* simplified core components folder structure, (aligned with issue #39), pull #64 (@jonasjabari)
* changed vue.js component naming, (aligned with issue #41), pull #64 (@jonasjabari)
* add-on engine components now need `Matestack::Ui` namespacing, pull #64 (@jonasjabari)

### Improvements for core developers

* started to move business logic out of `app/concepts` into `app/lib` folder in order to create a better structure (in progress --> core refactoring)

### Migration guide for users from v0.6.0

#### App base class name

***OLD:***

`app/matestack/app/example_app.rb`

```ruby
class Apps::ExampleApp < App::Cell::App end
```

***NEW:***

`app/matestack/app/example_app.rb`

```ruby
class Apps::ExampleApp < Matestack::Ui::App end
```

#### Page base class name

***OLD:***

`app/matestack/pages/example_app/example_page.rb`

```ruby
class Pages::ExampleApp::ExamplePage < Page::Cell::Page end
```

***NEW:***

`app/matestack/pages/example_app/example_page.rb`

```ruby
class Pages::ExampleApp::ExamplePage < Matestack::Ui::Page end
```

#### Custom STATIC component base class name / folder structure

***OLD:***

`app/matestack/components/card/cell/card.rb`

```ruby
class Components::Card::Cell::Card < Component::Cell::Static end
```

***NEW:***

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::StaticComponent end
```

#### Custom DYNAMIC component base class name / folder structure / vue.js naming

***OLD:***

`app/matestack/components/card/cell/card.rb`

```ruby
class Components::Card::Cell::Card < Component::Cell::Dynamic end
```

`app/matestack/components/card/cell/card.js`

```javascript
MatestackUiCore.Vue.component('custom-card-cell', { ... });
```

***NEW:***

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::DynamicComponent end
```

`app/matestack/components/card.js`

```javascript
MatestackUiCore.Vue.component('custom-card', { ... }); //no -cell postfix
```

#### Paragraph component

***OLD:***

`app/matestack/pages/example_app/example_page.rb`

```ruby
class Pages::ExampleApp::ExamplePage < Matestack::Ui::Page

  def response
    components {
      pg do
        plain "some text"
      end
    }
  end

end
```

***NEW:***

`app/matestack/pages/example_app/example_page.rb`

```ruby
class Pages::ExampleApp::ExamplePage < Matestack::Ui::Page

  def response
    components {
      paragraph do
        plain "some text"
      end
    }
  end

end
```

### Migration guide for core developers from v0.6.0

If you are not a CORE contributor, this part might not be relevant for you ;)

#### Namespaced core components + simplified core components folder/module structure

The core components are moved from `app/concepts` to `app/concepts/matestack/ui/core` in order to stick to the engine namespacing (used in helpers etc...) and therefore scoped like:

```
app/concepts/matestack/ui/core
|
└───div
│   │   div.rb (no cell folder anymore!)
│   │   div.haml (no view folder anymore!)
```

`app/concepts/matestack/ui/core/div/div.rb`

```ruby
module Matestack::Ui::Core::Div
  class Div < Matestack::Ui::Core::Component::Static


  end
end
```

We also removed the `Cell` module (`cell` folder) and the separate `js` and `view` folders in each component folder in order to simplify folder structure (as we did for custom component development as well)

**Note**

Last module name and class name of CORE components have to be the same. That doesn't apply for CUSTOM components:

`app/matestack/pages/example_app/example_page.rb`

```ruby
class Pages::ExampleApp::ExamplePage < Matestack::Ui::Page

  def response
    components {
      #CORE
      div
      # looking for 'Matestack::Ui::Core::Div::Div'
      # defined in 'app/concepts/matestack/ui/core/div/div.rb'
      form_input
      # looking for 'Matestack::Ui::Core::Form::Input::Input'
      # defined in 'app/concepts/matestack/ui/core/form/input/input.rb'

      #CUSTOM
      custom_card
      # looking for 'Components::Card'
      # defined in 'app/matestack/components/card.rb'
      custom_fancy_card
      # looking for 'Components::Fancy::Card'
      # defined in 'app/matestack/components/fancy/card.rb'
    }
  end

end
```

The reasons why we decided to resolve core components a bit different than custom components are simple:
* we want to make it as easy as possible to create custom components
  * we therefore removed the obligatory `Cell` module
  * we do not want to force the user to create a subfolder (and therefore module/namespace) in their `components` folder resulting in a class like:
  `Components::Card::Card`. It should be as simple as `Components::Card` which is good and intuitive!
* if we would use that simple approach for all our core components, it would lead to a messy code base, as all component cells, views and javascripts live in one big folder.
  * we therefore enforce more structure inside the core, using a subfolder for each component within `app/concepts/matestack/ui/core` resulting in a class name for a component like: `Matestack::Ui::Core::Div::Div` (double DIV at the end --> subfolder(module name) :: class)

#### Changed vue.js component naming

Scoping all core components within `Matestack::Ui::Core` is reflected in different vue.js component name as well:

Example: `async` core component

`app/concepts/matestack/ui/core/async`

```javascript
//old
Vue.component('async-cell', componentDef)
//new
Vue.component('matestack-ui-core-async', componentDef)
```

We also removed the `-cell` postfix.

#### Add-on-engine component namespacing

Add-on-engine components now need `Matestack::Ui` namespacing:

Example:

```
ADDON_ENGINE_ROOT/app/concepts/matestack/ui/materialize
|
└───row
│   │   row.rb
│   │   row.haml
```

`ADDON_ENGINE_ROOT/app/concepts/matestack/ui/materialize/row/row.rb`

```ruby
module Matestack::Ui::Materialize::Row
  class Row < Matestack::Ui::Core::Component::Static

    def response
      components {
        div class: "row" do
          yield_components
        end
      }
    end

  end
end
```
Usage:

`app/matestack/pages/example_app/example_page.rb`

```ruby
class Pages::ExampleApp::ExamplePage < Matestack::Ui::Page

  def response
    components {
      #CORE
      div
      # looking for 'Matestack::Ui::Core::Div::Div'
      # defined in 'CORE_ENGINE_ROOT/app/concepts/matestack/ui/core/div/div.rb'

      #ENGINE
      materialize_row
      # looking for 'Matestack::Ui::Materialize::Row::Row'
      # defined in 'ADDON_ENGINE_ROOT/app/concepts/matestack/ui/materialize/row/row.rb'
    }
  end

end
```

## v0.6.0 - 2019-04-27

### Improvements

* added documentation
* added tests

## v0.6.0.pre.1 - 2019-02-26

This release is marked as PRE. Test coverage is not sufficient at the moment.

### Breaking Changes

* Form component now need the ':include' keyword in order to populate the form config to its children
* Input components are now renamed to form_* in order to show their dependency to a parent form component

### Improvements

* partials may now be defined in modules and used across multiple page classes
* components may now define required attributes, which get validated automatically
* components now raises more specific error messages


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
 advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
 address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
 professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at pascal@matestack.io. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


================================================
FILE: Dockerfile.dev
================================================
FROM ruby:3.0-alpine3.12

RUN gem install bundler:2.1.4

RUN apk update --no-cache && \
    apk add build-base postgresql-dev git nodejs yarn tzdata bash sqlite-dev npm libtool && \
    mkdir -p /app

WORKDIR /app

COPY ./lib/ /app/lib/
COPY matestack-ui-core.gemspec /app/
COPY Gemfile* /app/
RUN bundle install


================================================
FILE: Dockerfile.test
================================================
FROM ruby:3.0-alpine3.12

RUN gem install bundler:2.1.4

RUN apk update --no-cache && \
    apk add build-base postgresql-dev git nodejs yarn tzdata bash sqlite-dev npm libtool && \
    mkdir -p /app

WORKDIR /app

COPY ./lib/ /app/lib/
COPY matestack-ui-core.gemspec /app/
COPY Gemfile* /app/
RUN bundle install

RUN apk update && apk upgrade \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories \
    && apk add --no-cache \
    chromium=86.0.4240.111-r0 \
    nss@edge \
    && rm -rf /var/lib/apt/lists/* \
    /var/cache/apk/* \
    /usr/share/man \
    /tmp/*

RUN apk add chromium-chromedriver=86.0.4240.111-r0

ENV CHROME_BIN=/usr/bin/chromium-browser \
    CHROME_PATH=/usr/lib/chromium/


================================================
FILE: Gemfile
================================================
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

# Declare your gem's dependencies in matestack-ui-core.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec

# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.

gem 'rails', '~> 7.0.1'

gem 'turbo-rails'

group :development, :test do
  gem 'rspec-rails', '~> 4.0.2'
  gem 'capybara'
  gem 'webpacker', '~> 5.0'
  gem 'pg', '>= 0.18', '< 2.0'
  gem 'selenium-webdriver'
  gem 'puma'
  gem 'simplecov', require: false, group: :test
  gem 'byebug'
  gem 'webmock'
end

group :test do
  gem 'pry-rails'
  gem 'pry-byebug'
  gem "generator_spec"
  # gem "rspec-retry" # repeating flaky tests
  # gem "rspec-wait", "~> 0.0.9"
end


================================================
FILE: LICENSE
================================================
Copyright (c) MateLab GmbH

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
[![Specs](https://github.com/matestack/matestack-ui-core/workflows/specs/badge.svg)](https://github.com/matestack/matestack-ui-core/actions)
[![Discord](https://img.shields.io/discord/771413294136426496.svg)](https://discord.com/invite/c6tQxFG)
[![Gem Version](https://badge.fury.io/rb/matestack-ui-core.svg)](https://badge.fury.io/rb/matestack-ui-core)
[![Docs](https://img.shields.io/badge/docs-matestack-blue.svg)](https://docs.matestack.io)
[![Twitter Follow](https://img.shields.io/twitter/follow/matestack.svg?style=social)](https://twitter.com/matestack)

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

# matestack-ui-core | Component based web UIs in pure Ruby for Rails

Boost your productivity & easily create component based web UIs in pure Ruby.

`matestack-ui-core` enables you to craft maintainable web UIs in pure Ruby, skipping ERB and HTML. UI code becomes a native and fun part of your Rails app. `matestack-ui-core` can progressively replace the classic Rails-View-Layer. You are able to use
it alongside your classic views.

## Compatibility

`matestack-ui-core` is tested against:

- Rails 7.0.1 + Ruby 3.0.0
- Rails 6.1.1 + Ruby 3.0.0
- Rails 6.1.1 + Ruby 2.7.2
- Rails 6.0.3.4 + Ruby 2.6.6
- Rails 5.2.4.4 + Ruby 2.6.6

Rails versions below 5.2 are not supported.

## Documentation/Installation

Documentation can be found [here](https://docs.matestack.io/matestack-ui-core)

## Getting started

A getting started guide can be found [here](https://docs.matestack.io/matestack-ui-core/getting-started/hello-world)

## Changelog

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

## Community

As a low-barrier feedback channel for our early users, we have set up a Discord server that can be found [here](https://discord.com/invite/c6tQxFG). You are very welcome to ask questions and send us feedback there!

## Contribution

We are happy to accept contributors of any kind! In order to make it as easy and fun as possible to contribute to `matestack-ui-core`, we would like to onboard contributors personally! Best way to become a contributor: Ping us on Discord! We will schedule a video call with you and show you, how and what to work on :)

## Feature walk-through

### 1. Create UI components in pure Ruby

Craft your UI based on your components written in pure Ruby. Utilizing Ruby's amazing language features, you're able to create a cleaner and more maintainable UI implementation.

#### Implement UI components in pure Ruby

Create Ruby classes within your Rails project and call matestack's core components through a Ruby DSL in order to craft your UIs.
The Ruby method \"div\" for example calls one of the static core components, responsible for rendering HTML tags. A component can take Strings, Integers Symbols, Arrays or Hashes (...) as optional properties (e.g. \"title\") or require them (e.g. \"body\").

`app/matestack/components/card.rb`

```ruby

class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      div class: "card-body" do
        h5 context.title if context.title.present?
        paragraph context.body, class: "card-text"
      end
    end
  end

end

```

#### Use your Ruby UI components on your existing Rails views

Components can be then called on Rails views (not only! see below), enabling you to create a reusable card components, abstracting UI complexity in your own components.

`app/views/your_view.html.erb`

```erb

<!-- some other erb markup -->
<%= Components::Card.call(title: "hello", body: "world") %>
<!-- some other erb markup -->

```


#### Use Ruby methods as partials

Split your UI implementation into multiple small chunks helping others (and yourself) to better understand your implementation.
Using this approach helps you to create a clean, readable and maintainable codebase.

`app/matestack/components/card.rb`

```ruby

class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image
  optional :footer

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      card_content
      card_footer if context.footer.present?
    end
  end

  def card_content
    div class: "card-body" do
      h5 context.title if context.title.present?
      paragraph context.body, class: "card-body"
    end
  end

  def card_footer
    div class: "card-footer text-muted" do
      plain context.footer
    end
  end

end

```

`app/views/your_view.html.erb`

```erb
<!-- some other erb markup -->
<%= Components::Card.call(title: "hello", body: "world", footer: "foo") %>
<!-- some other erb markup -->
```


#### Use class inheritance

Because it's just a Ruby class, you can use class inheritance in order to further improve the quality of your UI implementation.
Class inheritance can be used to easily create variants of UI components but still reuse parts of the implementation.

`app/matestack/components/blue_card.rb`

```ruby

class Components::BlueCard < Components::Card

  def response
    div class: "card shadow-sm border-0 bg-primary text-white" do
      img path: context.image, class: "w-100" if context.image.present?
      card_content #defined in parent class
      card_footer if context.footer.present? #defined in parent class
    end
  end

end

```

`app/views/your_view.html.erb`

```erb
<!-- some other erb markup -->
<%= Components::BlueCard.call(title: "hello", body: "world") %>
<!-- some other erb markup -->
```

#### Use components within components

Just like you used matestack's core components on your own UI component, you can use your own UI components within other custom UI components.
You decide when using a Ruby method partial should be replaced by another self contained UI component!

`app/matestack/components/card.rb`

```ruby

class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      # calling the CardBody component rather than using Ruby method partials
      Components::CardBody.call(title: context.title, body: context.body)
    end
  end

end

```
`app/matestack/components/card_body.rb`

```ruby

class Components::CardBody < Matestack::Ui::Component

  required :body
  optional :title

  def response
    # Just an example. Would make more sense, if this component had
    # a more complex structure
    div class: "card-body" do
      h5 context.title if context.title.present?
      paragraph context.body, class: "card-body"
    end
  end

end

```


#### Yield components into components

Sometimes it's not enough to just pass simple data into a component. No worries! You can just yield a block into your components!
Using this approach gives you more flexibility when using your UI components. Ofcourse yielding can be used alongside passing in simple params.


`app/matestack/components/card.rb`

```ruby

class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      Components::CardBody.call() do
        # yielding a block into the card_body component
        h5 context.title if context.title.present?
        paragraph context.body, class: "card-body"
      end
    end
  end

end

```

`app/matestack/components/card_body.rb`

```ruby

class Components::CardBody < Matestack::Ui::Component

  def response
    # Just an example. Would make more sense, if this component had
    # a more complex structure
    div class: "card-body" do
      yield if block_given?
    end
  end

end

```

#### Use named slots for advanced content injection

If you need to inject multiple blocks into your UI component, you can use \"slots\"!
Slots help you to build complex UI components with multiple named content placeholders for highest implementation flexibility!

`app/matestack/components/card.rb`

```ruby

class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      Components::CardBody.call(slots: {
        heading: method(:heading_slot),
        body: method(:body_slot)
      })
    end
  end

  def heading_slot
    h5 context.title if context.title.present?      
  end

  def body_slot
    paragraph context.body, class: "card-body"
  end

end

```
`app/matestack/components/card_body.rb`

```ruby

class Components::CardBody < Matestack::Ui::Component

  required :slots

  def response
    # Just an example. Would make more sense, if this component had
    # a more complex structure
    div class: "card-body" do
      div class: "heading-section" do
        slot :heading
      end
      div class: "body-section" do
        slot :body
      end
    end
  end

end

```

## License

`matestack-ui-core` is an Open Source project licensed under the terms of the [MIT license](./LICENSE)


================================================
FILE: Rakefile
================================================
begin
  require 'bundler/setup'
rescue LoadError
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end

require 'rdoc/task'

RDoc::Task.new(:rdoc) do |rdoc|
  rdoc.rdoc_dir = 'rdoc'
  rdoc.title    = 'Matestack::Ui::Core'
  rdoc.options << '--line-numbers'
  rdoc.rdoc_files.include('README.md')
  rdoc.rdoc_files.include('lib/**/*.rb')
end

APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
load 'rails/tasks/engine.rake'

load 'rails/tasks/statistics.rake'

require 'bundler/gem_tasks'

require 'rake/testtask'

# Rake::TestTask.new(:test) do |t|
#   t.libs << 'test'
#   t.pattern = 'test/**/*_test.rb'
#   t.verbose = false
# end
#
# task default: :test

task :webpack => 'webpack:build'

namespace :webpack do
  task :build => ['build:development', 'build:production']

  namespace :build do
    task :development => 'yarn:install' do
      Bundler.with_unbundled_env do
        sh "cd builder && bin/webpack"
      end
    end
    task :production => 'yarn:install' do
      Bundler.with_unbundled_env do
        sh "cd builder && bin/rake webpacker:compile"
      end
    end
  end

  task :watch => 'yarn:install' do
    Bundler.with_unbundled_env do
      sh "cd builder && bin/webpack --watch"
    end
  end

  namespace :yarn do
    task :install do
      sh "yarn install && cd builder && yarn install"
    end
  end
end



================================================
FILE: bin/rails
================================================
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails gems
# installed from the root of your application.

# ENGINE_ROOT = File.expand_path('..', __dir__)
# ENGINE_PATH = File.expand_path('../lib/matestack/ui/core/engine', __dir__)
APP_PATH = File.expand_path('../spec/dummy/config/application', __dir__)

# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])

require 'rails/all'
require 'rails/engine/commands'


================================================
FILE: ci/Dockerfile.test_5_2_ruby_2_6
================================================
FROM ruby:2.6-alpine3.12

RUN gem install bundler:2.1.4

RUN apk update --no-cache && \
    apk add build-base postgresql-dev git nodejs yarn tzdata bash sqlite-dev shared-mime-info npm && \
    mkdir -p /app

WORKDIR /app

COPY ./lib/ /app/lib/
COPY matestack-ui-core.gemspec /app/
COPY ./ci/Gemfile.5.2 /app/Gemfile
RUN bundle install

RUN apk update && apk upgrade \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories \
    && apk add --no-cache \
    chromium=86.0.4240.111-r0 \
    nss@edge \
    && rm -rf /var/lib/apt/lists/* \
    /var/cache/apk/* \
    /usr/share/man \
    /tmp/*

RUN apk add chromium-chromedriver=86.0.4240.111-r0

ENV CHROME_BIN=/usr/bin/chromium-browser \
    CHROME_PATH=/usr/lib/chromium/

RUN mv Gemfile _Gemfile
RUN mv Gemfile.lock _Gemfile.lock
COPY . /app
RUN rm Gemfile
RUN rm Gemfile.lock
RUN mv _Gemfile Gemfile
RUN mv _Gemfile.lock Gemfile.lock

WORKDIR /app/spec/dummy

RUN npm install
RUN ./bin/webpack

RUN rm ./db/schema.rb

RUN rm ./config/application.rb
RUN mv ./config/application.5.2_rb /app/spec/dummy/config/application.rb

WORKDIR /app


================================================
FILE: ci/Dockerfile.test_6_0_ruby_2_6
================================================
FROM ruby:2.6-alpine3.12

RUN gem install bundler:2.1.4

RUN apk update --no-cache && \
    apk add build-base postgresql-dev git nodejs yarn tzdata bash sqlite-dev shared-mime-info npm && \
    mkdir -p /app

WORKDIR /app

COPY ./lib/ /app/lib/
COPY matestack-ui-core.gemspec /app/
COPY ./ci/Gemfile.6.0 /app/Gemfile
RUN bundle install

RUN apk update && apk upgrade \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories \
    && apk add --no-cache \
    chromium=86.0.4240.111-r0 \
    nss@edge \
    && rm -rf /var/lib/apt/lists/* \
    /var/cache/apk/* \
    /usr/share/man \
    /tmp/*

RUN apk add chromium-chromedriver=86.0.4240.111-r0

ENV CHROME_BIN=/usr/bin/chromium-browser \
    CHROME_PATH=/usr/lib/chromium/

RUN mv Gemfile _Gemfile
RUN mv Gemfile.lock _Gemfile.lock
COPY . /app
RUN rm Gemfile
RUN rm Gemfile.lock
RUN mv _Gemfile Gemfile
RUN mv _Gemfile.lock Gemfile.lock

WORKDIR /app/spec/dummy

RUN npm install
RUN ./bin/webpack

RUN rm ./db/schema.rb

RUN rm ./config/application.rb
RUN mv ./config/application.6.0_rb /app/spec/dummy/config/application.rb

WORKDIR /app


================================================
FILE: ci/Dockerfile.test_6_1_ruby_2_7
================================================
FROM ruby:2.7-alpine3.12

RUN gem install bundler:2.1.4

RUN apk update --no-cache && \
    apk add build-base postgresql-dev git nodejs yarn tzdata bash sqlite-dev shared-mime-info npm && \
    mkdir -p /app

WORKDIR /app

COPY ./lib/ /app/lib/
COPY matestack-ui-core.gemspec /app/
COPY ./ci/Gemfile.6.1 /app/Gemfile
RUN bundle install

RUN apk update && apk upgrade \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories \
    && apk add --no-cache \
    chromium=86.0.4240.111-r0 \
    nss@edge \
    && rm -rf /var/lib/apt/lists/* \
    /var/cache/apk/* \
    /usr/share/man \
    /tmp/*

RUN apk add chromium-chromedriver=86.0.4240.111-r0

ENV CHROME_BIN=/usr/bin/chromium-browser \
    CHROME_PATH=/usr/lib/chromium/

RUN mv Gemfile _Gemfile
RUN mv Gemfile.lock _Gemfile.lock
COPY . /app
RUN rm Gemfile
RUN rm Gemfile.lock
RUN mv _Gemfile Gemfile
RUN mv _Gemfile.lock Gemfile.lock

WORKDIR /app/spec/dummy

RUN npm install
RUN ./bin/webpack

RUN rm ./db/schema.rb

RUN rm ./config/application.rb
RUN mv ./config/application.6.1_rb /app/spec/dummy/config/application.rb

WORKDIR /app


================================================
FILE: ci/Dockerfile.test_6_1_ruby_3_0
================================================
FROM ruby:3.0-alpine3.12

RUN gem install bundler:2.1.4

RUN apk update --no-cache && \
    apk add build-base postgresql-dev git nodejs yarn tzdata bash sqlite-dev shared-mime-info npm && \
    mkdir -p /app

WORKDIR /app

COPY ./lib/ /app/lib/
COPY matestack-ui-core.gemspec /app/
COPY ./ci/Gemfile.6.1 /app/Gemfile
RUN bundle install

RUN apk update && apk upgrade \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories \
    && apk add --no-cache \
    chromium=86.0.4240.111-r0 \
    nss@edge \
    && rm -rf /var/lib/apt/lists/* \
    /var/cache/apk/* \
    /usr/share/man \
    /tmp/*

RUN apk add chromium-chromedriver=86.0.4240.111-r0

ENV CHROME_BIN=/usr/bin/chromium-browser \
    CHROME_PATH=/usr/lib/chromium/

RUN mv Gemfile _Gemfile
RUN mv Gemfile.lock _Gemfile.lock
COPY . /app
RUN rm Gemfile
RUN rm Gemfile.lock
RUN mv _Gemfile Gemfile
RUN mv _Gemfile.lock Gemfile.lock

WORKDIR /app/spec/dummy

RUN npm install
RUN ./bin/webpack

RUN rm ./db/schema.rb

RUN rm ./config/application.rb
RUN mv ./config/application.6.1_rb /app/spec/dummy/config/application.rb

WORKDIR /app


================================================
FILE: ci/Dockerfile.test_7_0_ruby_3_0
================================================
FROM ruby:3.0-alpine3.12

RUN gem install bundler:2.1.4

RUN apk update --no-cache && \
    apk add build-base postgresql-dev git nodejs yarn tzdata bash sqlite-dev shared-mime-info npm && \
    mkdir -p /app

WORKDIR /app

COPY ./lib/ /app/lib/
COPY matestack-ui-core.gemspec /app/
COPY ./ci/Gemfile.7.0 /app/Gemfile
RUN bundle install

RUN apk update && apk upgrade \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories \
    && echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories \
    && apk add --no-cache \
    chromium=86.0.4240.111-r0 \
    nss@edge \
    && rm -rf /var/lib/apt/lists/* \
    /var/cache/apk/* \
    /usr/share/man \
    /tmp/*

RUN apk add chromium-chromedriver=86.0.4240.111-r0

ENV CHROME_BIN=/usr/bin/chromium-browser \
    CHROME_PATH=/usr/lib/chromium/

RUN mv Gemfile _Gemfile
RUN mv Gemfile.lock _Gemfile.lock
COPY . /app
RUN rm Gemfile
RUN rm Gemfile.lock
RUN mv _Gemfile Gemfile
RUN mv _Gemfile.lock Gemfile.lock

WORKDIR /app/spec/dummy

RUN npm install
RUN ./bin/webpack

RUN rm ./db/schema.rb

RUN rm ./config/application.rb
RUN mv ./config/application.7.0_rb /app/spec/dummy/config/application.rb

WORKDIR /app


================================================
FILE: ci/Gemfile.5.2
================================================
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

# Declare your gem's dependencies in matestack-ui-core.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec

# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.

gem 'rails', '5.2.4.4'

group :development, :test do
  gem 'rspec-rails', '~> 3.8'
  gem 'capybara'
  gem 'webpacker', '~> 4.0'
  gem 'pg', '>= 0.18', '< 2.0'
  gem 'selenium-webdriver'
  gem 'puma'
  gem 'simplecov', require: false, group: :test
  gem 'byebug'
  gem 'webmock'
  gem 'turbolinks'
end

group :test do
  gem 'pry-rails'
  gem 'pry-byebug'
  gem "generator_spec"
  gem "rspec-retry" # repeating flaky tests
  gem "rspec-wait", "~> 0.0.9"
end


================================================
FILE: ci/Gemfile.6.0
================================================
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

# Declare your gem's dependencies in matestack-ui-core.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec

# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.

gem 'rails', '6.0.3.4'

group :development, :test do
  gem 'rspec-rails', '~> 3.8'
  gem 'capybara'
  gem 'webpacker', '~> 4.0'
  gem 'pg', '>= 0.18', '< 2.0'
  gem 'selenium-webdriver'
  gem 'puma'
  gem 'simplecov', require: false, group: :test
  gem 'byebug'
  gem 'webmock'
  gem 'turbolinks'
end

group :test do
  gem 'pry-rails'
  gem 'pry-byebug'
  gem "generator_spec"
  gem "rspec-retry" # repeating flaky tests
  gem "rspec-wait", "~> 0.0.9"
end


================================================
FILE: ci/Gemfile.6.1
================================================
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

# Declare your gem's dependencies in matestack-ui-core.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec

# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.

gem 'rails', '6.1.1'

group :development, :test do
  gem 'rspec-rails', '~> 4.0.2'
  gem 'capybara'
  gem 'webpacker', '~> 4.0'
  gem 'pg', '>= 0.18', '< 2.0'
  gem 'selenium-webdriver'
  gem 'puma'
  gem 'simplecov', require: false, group: :test
  gem 'byebug'
  gem 'webmock'
  gem 'turbolinks'
end

group :test do
  gem 'pry-rails'
  gem 'pry-byebug'
  gem "generator_spec"
  gem "rspec-retry" # repeating flaky tests
  gem "rspec-wait", "~> 0.0.9"
end


================================================
FILE: ci/Gemfile.7.0
================================================
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

# Declare your gem's dependencies in matestack-ui-core.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec

# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.

gem 'rails', '7.0.1'

group :development, :test do
  gem 'rspec-rails', '~> 4.0.2'
  gem 'capybara'
  gem 'webpacker', '~> 4.0'
  gem 'pg', '>= 0.18', '< 2.0'
  gem 'selenium-webdriver'
  gem 'puma'
  gem 'simplecov', require: false, group: :test
  gem 'byebug'
  gem 'webmock'
  gem 'turbolinks'
end

group :test do
  gem 'pry-rails'
  gem 'pry-byebug'
  gem "generator_spec"
  gem "rspec-retry" # repeating flaky tests
  gem "rspec-wait", "~> 0.0.9"
end


================================================
FILE: ci/artifacts/.keep
================================================


================================================
FILE: ci/docker-compose.ci.yml
================================================
version: '3'
services:

  test_5_2_ruby_2_6:
    build:
      context: ../
      dockerfile: ./ci/Dockerfile.test_5_2_ruby_2_6
    environment:
      RAILS_ENV: test
    volumes:
      - "../ci/artifacts:/app/ci/artifacts"
    links:
      - "postgres_test_5_2_ruby_2_6:postgres_test"
    command: sh -c "bundle exec rake db:drop && bundle exec rake db:create && bundle exec rake db:migrate && bundle exec rspec spec/test/core && cp Gemfile.lock ./ci/artifacts/Gemfile.lock"
    user: ${CURRENT_UID}

  test_6_0_ruby_2_6:
    build:
      context: ../
      dockerfile: ./ci/Dockerfile.test_6_0_ruby_2_6
    environment:
      RAILS_ENV: test
    volumes:
      - "../ci/artifacts:/app/ci/artifacts"
    links:
      - "postgres_test_6_0_ruby_2_6:postgres_test"
    command: sh -c "bundle exec rake db:drop && bundle exec rake db:create && bundle exec rake db:migrate && bundle exec rspec spec/test/core && cp Gemfile.lock ./ci/artifacts/Gemfile.lock"
    user: ${CURRENT_UID}

  test_6_1_ruby_2_7:
    build:
      context: ../
      dockerfile: ./ci/Dockerfile.test_6_1_ruby_2_7
    environment:
      RAILS_ENV: test
    volumes:
      - "../ci/artifacts:/app/ci/artifacts"
    links:
      - "postgres_test_6_1_ruby_2_7:postgres_test"
    command: sh -c "bundle exec rake db:drop && bundle exec rake db:create && bundle exec rake db:migrate && bundle exec rspec spec/test/core && cp Gemfile.lock ./ci/artifacts/Gemfile.lock"
    user: ${CURRENT_UID}

  test_6_1_ruby_3_0:
    build:
      context: ../
      dockerfile: ./ci/Dockerfile.test_6_1_ruby_3_0
    environment:
      RAILS_ENV: test
    volumes:
      - "../ci/artifacts:/app/ci/artifacts"
    links:
      - "postgres_test_6_1_ruby_3_0:postgres_test"
    command: sh -c "bundle exec rake db:drop && bundle exec rake db:create && bundle exec rake db:migrate && bundle exec rspec spec/test/core && cp Gemfile.lock ./ci/artifacts/Gemfile.lock"
    user: ${CURRENT_UID}

  test_7_0_ruby_3_0:
    build:
      context: ../
      dockerfile: ./ci/Dockerfile.test_7_0_ruby_3_0
    environment:
      RAILS_ENV: test
    volumes:
      - "../ci/artifacts:/app/ci/artifacts"
    links:
      - "postgres_test_7_0_ruby_3_0:postgres_test"
    command: sh -c "bundle exec rake db:drop && bundle exec rake db:create && bundle exec rake db:migrate && bundle exec rspec spec/test/core && cp Gemfile.lock ./ci/artifacts/Gemfile.lock"
    user: ${CURRENT_UID}

  postgres_test_base: &postgres_test_base
    image: postgres
    expose:
      - 5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: test

  postgres_test_7_0_ruby_3_0:
    <<: *postgres_test_base

  postgres_test_6_1_ruby_3_0:
    <<: *postgres_test_base

  postgres_test_6_1_ruby_2_7:
    <<: *postgres_test_base

  postgres_test_6_0_ruby_2_6:
    <<: *postgres_test_base

  postgres_test_5_2_ruby_2_6:
    <<: *postgres_test_base


================================================
FILE: docker-compose.yml
================================================
version: '3'
services:

  dummy:
    build:
      context: .
      dockerfile: ./Dockerfile.dev
    ports:
      - "3000:3000"
    environment:
      RAILS_ENV: development
    links:
      - postgres_dummy
    volumes:
      - ./:/app
      - gem-volume:/usr/local/bundle
    command: "bundle exec rails server -b 0.0.0.0"
    user: ${CURRENT_UID}
    stdin_open: true
    tty: true

  webpack-watcher:
    build:
      context: .
      dockerfile: ./Dockerfile.dev
    environment:
      RAILS_ENV: development
    volumes:
      - ./:/app
      - gem-volume:/usr/local/bundle
    command: "sh -c 'cd spec/dummy && ./bin/webpack --watch'"
    user: ${CURRENT_UID}

  test:
    build:
      context: .
      dockerfile: ./Dockerfile.test
    environment:
      RAILS_ENV: test
    links:
      - postgres_test
    ports:
      - "33123:33123"
    volumes:
      - ./:/app
      - gem-volume:/usr/local/bundle
    command: "bundle exec rspec spec/test"
    user: ${CURRENT_UID}



  postgres_dummy:
    image: postgres
    expose:
      - 5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: dummy
    volumes:
      - dummy-data-volume:/var/lib/postgresql/data

  postgres_test_base: &postgres_test_base
    image: postgres
    expose:
      - 5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: test

  postgres_test:
    <<: *postgres_test_base

volumes:
  test-data-volume:
  dummy-data-volume:
  gem-volume:


================================================
FILE: docs/README.md
================================================
---
description: >-
  Matestack Ui Core - Boost your productivity & easily create component based
  web UIs in pure Ruby.
---

# Welcome

{% hint style="info" %}
Version 3.0.0 was released on the xth of February 2022. Click here for more [details](migrate-from-2.x-to-3.0.md)

**Most important changes:**

* Split `matestack-ui-core` into `matestack-ui-core` and `matestack-ui-vuejs`
* Rails 7 support
* Vue 3 support in `matestack-ui-vuejs`

****

**If you want to see the docs for Version 2.1, click** [**here**](https://docs.matestack.io/matestack-ui-core/v/2.1/)**:**
{% endhint %}

## **About**

`matestack-ui-core` enables you to craft maintainable, **component based** web UIs in **pure Ruby**, skipping ERB and HTML. UI code becomes a native and fun part of your Rails app. It can progressively replace the classic Rails-View-Layer. You are able to use it alongside your Rails views.

## Compatibility

`matestack-ui-core` is automatically tested against:

* Rails 7.0.1 + Ruby 3.0.0
* Rails 6.1.1 + Ruby 3.0.0
* Rails 6.1.1 + Ruby 2.7.2
* Rails 6.0.3.4 + Ruby 2.6.6
* Rails 5.2.4.4 + Ruby 2.6.6

{% hint style="danger" %}
Rails versions below 5.2 are not officially supported.
{% endhint %}

## Getting Started

Start right away and install `matestack-ui-core` on top of your Rails app, or read something about the features below.

{% content-ref url="getting-started/installation-update.md" %}
[installation-update.md](getting-started/installation-update.md)
{% endcontent-ref %}

## Feature walk-through

### 1. Create UI components in pure Ruby

Craft your UI based on your components written in pure Ruby. Utilizing Ruby's amazing language features, you're able to create a cleaner and more maintainable UI implementation.

**Implement UI components in pure Ruby**

Create Ruby classes within your Rails project and call Matestack's core components through a Ruby DSL in order to craft your UIs. The Ruby method "div" for example calls one of the static core components, responsible for rendering HTML tags. A component can take Strings, Integers Symbols, Arrays or Hashes (...) as optional properties (e.g. "title") or require them (e.g. "body").

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      div class: "card-body" do
        h5 context.title if context.title.present?
        paragraph context.body, class: "card-text"
      end
    end
  end

end
```

**Use your Ruby UI components on your existing Rails views**

Components can be then called on Rails views (not only! see below), enabling you to create a reusable card components, abstracting UI complexity in your own components.

`app/views/your_view.html.erb`

```erb
<!-- some other erb markup -->
<%= Components::Card.call(title: "hello", body: "world") %>
<!-- some other erb markup -->
```

**Use Ruby methods as partials**

Split your UI implementation into multiple small chunks helping others (and yourself) to better understand your implementation. Using this approach helps you to create a clean, readable and maintainable codebase.

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image
  optional :footer

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      card_content
      card_footer if context.footer.present?
    end
  end

  def card_content
    div class: "card-body" do
      h5 context.title if context.title.present?
      paragraph context.body, class: "card-body"
    end
  end

  def card_footer
    div class: "card-footer text-muted" do
      plain footer
    end
  end

end
```

`app/views/your_view.html.erb`

```erb
<!-- some other erb markup -->
<%= Components::Card.call(title: "hello", body: "world", footer: "foo") %>
<!-- some other erb markup -->
```

**Use class inheritance**

Because it's just a Ruby class, you can use class inheritance in order to further improve the quality of your UI implementation. Class inheritance can be used to easily create variants of UI components but still reuse parts of the implementation.

`app/matestack/components/blue_card.rb`

```ruby
class Components::BlueCard < Components::Card

  def response
    div class: "card shadow-sm border-0 bg-primary text-white" do
      img path: context.image, class: "w-100" if context.image.present?
      card_content #defined in parent class
      card_footer if context.footer.present? #defined in parent class
    end
  end

end
```

`app/views/your_view.html.erb`

```erb
<!-- some other erb markup -->
<%= Components::BlueCard.call(title: "hello", body: "world") %>
<!-- some other erb markup -->
```

**Use components within components**

Just like you used matestack's core components on your own UI component, you can use your own UI components within other custom UI components. You decide when using a Ruby method partial should be replaced by another self contained UI component!

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      # calling the CardBody component rather than using Ruby method partials
      Components::CardBody.call(title: context.title, body: context.body)
    end
  end

end
```

`app/matestack/components/card_body.rb`

```ruby
class Components::CardBody < Matestack::Ui::Component

  required :body
  optional :title

  def response
    # Just an example. Would make more sense, if this component had
    # a more complex structure
    div class: "card-body" do
      h5 context.title if context.title.present?
      paragraph context.body, class: "card-body"
    end
  end

end
```

**Yield components into components**

Sometimes it's not enough to just pass simple data into a component. No worries! You can just yield a block into your components! Using this approach gives you more flexibility when using your UI components. Ofcourse yielding can be used alongside passing in simple params.

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      Components::CardBody.call() do
        # yielding a block into the card_body component
        h5 context.title if context.title.present?
        paragraph context.body, class: "card-body"
      end
    end
  end

end
```

`app/matestack/components/card_body.rb`

```ruby
class Components::CardBody < Matestack::Ui::Component

  def response
    # Just an example. Would make more sense, if this component had
    # a more complex structure
    div class: "card-body" do
      yield if block_given?
    end
  end

end
```

**Use named slots for advanced content injection**

If you need to inject multiple blocks into your UI component, you can use "slots"! Slots help you to build complex UI components with multiple named content placeholders for highest implementation flexibility!

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      Components::CardBody.call(slots: {
        heading: method(:heading_slot),
        body: method(:body_slot)
      })
    end
  end

  def heading_slot
    h5 context.title if context.title.present?      
  end

  def body_slot
    paragraph context.body, class: "card-body"
  end

end
```

`app/matestack/components/card_body.rb`

```ruby
class Components::CardBody < Matestack::Ui::Component

  required :slots

  def response
    # Just an example. Would make more sense, if this component had
    # a more complex structure
    div class: "card-body" do
      div class: "heading-section" do
        slot :heading
      end
      div class: "body-section" do
        slot :body
      end
    end
  end

end
```

### 2. Substitute Rails Views with Matestack Pages

Until here we used Matestack components on Rails views. If desired you can go one step further and use Matestack components on something called a Matestack Page:

A Matestack page can be compared to a Rails view and might be yielded within a layout provided by an associated Matestack layout class (see below). The page itself uses Matestack's HTML rendering mechanism in a `response` method and may additionally call other components in order to define a specific UI.

{% code title="app/matestack/pages/some_page.rb" %}
```ruby
class Pages::SomePage < Matestack::Ui::Page

  def response
    div class: "container" do
      span id: "hello" do
        plain "hello world!"
      end
      Components::Card.call(title: "foo", body: "bar")
    end
  end

end
```
{% endcode %}

Pages are used as Rails view substitutes and therefore called in a Rails controller action:

{% code title="app/controllers/some_controller.rb" %}
```ruby
class SomeController < ApplicationController

  include Matestack::Ui::Core::Helper

  def overview
    render Pages::SomePage
  end

end
```
{% endcode %}

The page response - in this case - will be yielded into the Rails layout if not specified differently.

### 3. Wrap Matestack Pages in Matestack Layouts

Just like a Rails layout would yield a Rails view, a Matestack layout yields a Matestack page. The layout uses Matestack's HTML rendering mechanism in a `response` method and may additionally call other components in order to define a specific UI.

{% code title="app/matestack/some_app/some_layout.rb" %}
```ruby
class SomeApp::SomeLayout < Matestack::Ui::Layout

  def response
    h1 "Some App"
    main do
      yield
    end
  end

end
```
{% endcode %}

In this basic example the layout is using the methods `h1` and `main` in order to create the markup as well as a `yield` in order to yield a page on a specific position.

{% hint style="info" %}
A Matestack layout itself will be yielded into the Rails layout, unless the Rails layout is disabled in the controller via:`layout false`
{% endhint %}

Usually a layout implies a specific context of your application. Multiple pages are then scoped within that context, which could lead to a file structure like:

```bash
app/matestack/
|
└───some_app/
│   │   some_layout.rb
│   └───pages/
│   │   │   page1.rb
│   │   │   page2.rb
│   │   │   page3.rb
```

and then used in a controller like this:

{% code title="app/controllers/some_controller.rb" %}
```ruby
class SomeController < ApplicationController

  include Matestack::Ui::Core::Helper

  matestack_layout SomeApp::SomeLayout

  def page_1
    render SomeApp::Pages::Page1
  end

  def page_2
    render SomeApp::Pages::Page2
  end

  def page_3
    render SomeApp::Pages::Page3, matestack_layout: false # skip app layout on this page
  end

end
```
{% endcode %}


================================================
FILE: docs/SUMMARY.md
================================================
# Table of contents

* [Welcome](README.md)
* [Migrating from 2.x to 3.0](migrate-from-2.x-to-3.0.md)

## Getting started

* [Installation & Update](getting-started/installation-update.md)
* [Hello World](getting-started/hello-world.md)

## HTML Rendering

* [Basic Rendering Mechanism](html-rendering/html-rendering.md)
* [Integrating Action View Helpers](html-rendering/integrating-action-view-helpers.md)
* [Integrating Rails Views or Partials](html-rendering/reusing-views-or-partials.md)

## Components

* [API](components/api.md)
* [Usage on Rails Views](components/usage-on-rails-views.md)
* [Usage on Matestack Pages](components/usage-on-matestack-pages.md)
* [Usage on Matestack Layouts](components/usage-on-matestack-layouts.md)
* [Usage in Isolation](components/usage-in-isolation.md)
* [Registry](components/registry.md)

## Pages

* [API](pages/api.md)
* [Rails Controller Integration](pages/rails-controller-integration.md)

## Layouts

* [API](layouts/api.md)
* [Rails Controller Integration](layouts/rails-controller-integration.md)


================================================
FILE: docs/components/api.md
================================================
# API

## Response

Use the `response` method to define the UI of the component by using Matestack's HTML rendering or calling components.

```ruby
  class SomeComponent < Matestack::Ui::Component

    def response
      div id: "my-component" do
        plain "hello world!"
      end
      SomeOtherComponent.()
    end

  end
```

```ruby
class ExamplePage < Matestack::Ui::Page

  def response
    div id: "div-on-page" do
      SomeComponent.()
    end
  end

end
```

## Partials and helper methods

Use partials to keep the code dry and indentation layers manageable!

### Local partials on component level

In the component definition, see how this time from inside the response, the `my_partial` method below is called:

```ruby
class SomeComponent < Matestack::Ui::Component

  def response
    div id: "my-component" do
      my_partial "foo from component"
    end
  end

  private # optionally mark your partials as private

  def my_partial text
    div class: "nested"
      plain text
    end
  end

end
```

### Partials defined in modules

Extract code snippets to modules for an even better project structure. First, create a module:

```ruby
module MySharedPartials

  def my_partial text
    div class: "nested"
      plain text
    end
  end

end
```

Include the module in the component:

```ruby
class SomeComponent < Matestack::Ui::Component

  include MySharedPartials

  def response
    div id: "my-component" do
      my_partial "foo from component"
    end
  end

end
```

### Helper methods

Not only can instance methods be used as "partials" but as general helpers performing any kind of logic or data resolving:

```ruby
class SomeComponent < Matestack::Ui::Component

  def response
    div id: "my-component" do
      if is_admin?
        latest_users.each do |user|
          div do
            plain user.name # ...
          end
        end
      else
        plain "not authorized"
      end 
    end
  end

  private # optionally mark your helper methods as private

  def is_admin?
    true # some crazy Ruby logic!
  end

  def latest_users
    User.last(10) # calling ActiveRecord models for example
  end

end
```

## Render?

Use the `render?` method to conditionally render the component based on custom rules:

```ruby
class AdminComponent < Matestack::Ui::Component
  required :user

  def render?
    context.user.admin?
  end

  def response
    div id: "admin-component" do
      plain "This component should only get rendered for admins"
    end
  end
end
```

This is particularly useful to avoid plastering your views with conditional statements like `if` and `unless`.

Instead of:

```ruby
  <% if current_user.admin? %>
    <%= Components::AdminComponent.(user: current_user) %>
  <% end %>
```

You can just use:

```ruby
  <%= Components::AdminComponent.(user: current_user) %>
```

## Prepare

Use a prepare method to resolve instance variables before rendering a component if required.

```ruby
  class SomeComponent < Matestack::Ui::Component

    def prepare
      @some_data = "some data"
    end

    def response
      div id: "my-component" do
        plain @some_data
      end
    end

  end
```

```ruby
class ExamplePage < Matestack::Ui::Page

  def response
    div id: "div-on-page" do
      SomeComponent.()
    end
  end

end
```

This is the HTML which gets created:

```markup
<div id="div-on-page">
  <div id="my-component">
    some data
  </div>
</div>
```

## Params access

A component can access request information, e.g. url query params, by calling the `params` method:

```ruby
class SomeComponent < Matestack::Ui::Component

  def response
    div id: "my-component" do
      plain params[:foo]
    end
  end

end
```

On the example page, reference the component as usual.

```ruby
class ExamplePage < Matestack::Ui::Page

  def response
    div id: "div-on-page" do
     SomeComponent.()
    end
  end

end
```

Now, visiting the respective route to the page, e.g. via `/xyz?foo=bar`, the component reads the `[:foo]` from the params and displays it like so:

```markup
<div id="div-on-page">
  <div id="my-component">
    bar
  </div>
</div>
```

## Passing data to components

You often need to pass data into your component to make them reusable. You have multiple possibilities to do that:

### General options access

If you pass in a hash to a component...

```ruby
class ExamplePage < Matestack::Ui::Page

  def response
    div id: "div-on-page" do
      SomeComponent.(foo: "bar")
    end
  end

end
```

...this hash is accessible via options in the component:

```ruby
class Some::Component < Matestack::Ui::Component

  def response
    div id: "my-component" do
      plain options[:foo]
    end
  end

end
```

### Optional and required options

Matestack components give you the possibility to define an explicit API for your component describing required and optional options for a component. Using this approach, it's way easier to understand what data can be processed by your component.

{% hint style="info" %}
`required` and `optional` options will be deleted from the `options` hash and are only available via the `context` object.
{% endhint %}

#### Required options

Required options are required for your component to work, like the name suggests. If at least one required option is missing, an Exception is raised.

Declare your required options by calling `required` as follows:

```ruby
class SomeComponent < Matestack::Ui::Component

  required :some_property, :some_other

end
```

You then can use these options simply by calling the provided OpenStruct object `context`, which includes the injected options with their name:

```ruby
class SomeComponent < Matestack::Ui::Component

  required :some_property, :some_other

  def response
    # display some_property plain inside a div and some_other property inside a paragraph beneath it
    div do
      plain context.some_property
    end
    paragraph text: context.some_other
  end

end
```

#### Optional options

To define optional options you can use the same syntax as `required`. Just use `optional` instead of `required`. Optional options are optional and not validated for presence like required options.

```ruby
class SomeComponent < Matestack::Ui::Component

  optional :optional_property, :other_optional_property # optional properties could be empty

  def response
    div do
      plain context.optional_property
    end
    paragraph context.other_optional_property
  end

end
```

#### Passing more complex data structures to components

You can pass any object you like and use it in the component with the helper.

```ruby
class SomeComponent < Matestack::Ui::Component

  required :some_option,
  optional :some_other

  def response
    div do
      plain context.some_option
    end
    if context.some_other.present?
      paragraph context.some_other[:option]
    end
  end

end
```

Use it in the example page and pass in one option as a hash

```ruby
class ExamplePage < Matestack::Ui::Page

  def prepare
    @hello = "hello!"
  end

  def response
    div id: "div-on-page" do
      SomeComponent.(some_option: @hello, some_other: { option: "world!" })
    end
  end

end
```

#### Alias properties

It's not possible to overwrite core methods of the OpenStruct object `context`

```markup
[:!, :!=, :!~, :<=>, :==, :===, :=~, :[], :[]=, :__id__, :__send__, :acts_like?, :as_json, :blank?, :byebug, :class, :class_eval, :clone, :dclone, :debugger, :deep_dup, :define_singleton_method, :delete_field, :dig, :display, :dup, :duplicable?, :each_pair, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :gem, :hash, :html_safe?, :in?, :inspect, :instance_eval, :instance_exec, :instance_of?, :instance_values, :instance_variable_defined?, :instance_variable_get, :instance_variable_names, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :load_dependency, :marshal_dump, :marshal_load, :method, :method_missing, :methods, :nil?, :object_id, :presence, :presence_in, :present?, :pretty_inspect, :pretty_print, :pretty_print_cycle, :pretty_print_inspect, :pretty_print_instance_variables, :private_methods, :protected_methods, :public_method, :public_methods, :public_send, :remote_byebug, :remove_instance_variable, :require_dependency, :require_or_load, :respond_to?, :send, :singleton_class, :singleton_method, :singleton_methods, :table, :table!, :taint, :tainted?, :tap, :then, :to_enum, :to_h, :to_json, :to_param, :to_query, :to_s, :to_yaml, :trust, :try, :try!, :unloadable, :untaint, :untrust, :untrusted?, :with_options, :yield_self]
```

If you somehow want to inject options with a key matching a core method of the OpenStruct object, simply provide an alias name with the `as:` option. You can then use the alias accordingly. A popular example would be the option called `class`

```ruby
class SomeComponent < Matestack::Ui::Component

  required :foo, :bar, class: { as: :my_class }

  def response
    div class: context.my_class do
      plain "#{context.foo} - #{context.bar}"
    end
  end

end
```

### Text argument

Sometimes you just want to pass in a simple (text) argument rather than a hash with multiple keys:

```ruby
class ExamplePage < Matestack::Ui::Page

  def response
    div id: "div-on-page" do
      # simply pass in a string here
      SomeComponent.("foo from page")
    end
  end

end
```

A component can access this text argument in various ways:

```ruby
class Some::Component < Matestack::Ui::Component

  def response
    div id: "my-component" do
      plain self.text # because such an argument is almost always a string
      # or
      plain context.text # for compatibility with older releases
    end
  end

end
```

This approach can be combined with injecting Hashes to components:

```ruby
class ExamplePage < Matestack::Ui::Page

  def response
    div id: "div-on-page" do
      # simply pass in a string here
      Some::Component.("foo from page", { foo: "bar" })
    end
  end

end
```

```ruby
class Some::Component < Matestack::Ui::Component

  optional :foo

  def response
    div id: "my-component" do
      plain self.text # because such an argument is almost always a string
      # or
      plain context.text # for compatibility with older releases
      plain context.foo
    end
  end

end
```

## Yielding inside components

Components can yield a block with access to scope, where a block is defined.

```ruby
class SomeComponent < Matestack::Ui::Component

  def response
    div id: "my-component" do
      yield
    end
  end

end
```

Pass a block to a component on the page as shown below:

```ruby
class ExamplePage < Matestack::Ui::Page

  def prepare
    @foo = "foo from page"
  end

  def response
    div id: "div-on-page" do
      SomeComponent.() do
        plain @foo
      end
    end
  end

end
```

Not a fancy example, but this is the result:

```markup
<div id="div-on-page">
  <div id="my-component">
    foo from page
  </div>
</div>
```

## Slots

Slots in Matestack allow us to inject whole UI snippets into the component. It's a more specific yielding mechanism as you will yield multiple "named blocks" into the component. Each of these blocks can be referenced and positioned independently in the component,

### Slots on the page instance scope

Define the slots within the component file as shown below. Please make sure to inject slots within a hash `slots: { ... }` into the component.

```ruby
class SomeComponent < Matestack::Ui::Component

  def prepare
    @foo = "foo from component"
  end

  def response
    div id: "my-component" do
      slot :my_first_slot
      br
      slot :my_second_slot
    end
  end

end
```

Slots have access to the scope of the class, where they are defined. In this case `@foo`

```ruby
class ExamplePage < Matestack::Ui::Page

  def prepare
    @foo = "foo from page"
  end

  def response
    div do
      some_component slots: {
        my_first_slot: method(:my_simple_slot),
        my_second_slot: method(:my_second_simple_slot)
      }
    end
  end

  def my_simple_slot
    span id: "my_simple_slot" do
      plain "some content"
    end
  end

  def my_second_simple_slot
    span id: "my_simple_slot" do
      plain @foo
    end
  end

end
```

This gets rendered into HTML as shown below. Notice that the `@foo` from the component configuration got overwritten by the page's local `@foo`!

```markup
<div>
  <div id="my-component">
    <span id="my_simple_slot">
      some content
    </span>
    <br/>
    <span id="my_simple_slot">
      foo from page
    </span>
  </div>
</div>
```

### Using slots of components within components

To use _component instance scope slots_, first define slots within a static component:

```ruby
class Other::Component < Matestack::Ui::Component

  def prepare
    @foo = "foo from other component"
  end

  def response
    div id: "my-other-component" do
      slot :my_slot_from_component
      br
      slot :my_slot_from_page
      br
      plain @foo
    end
  end

end
```

and also in some component:

```ruby
class Some::Component < Matestack::Ui::Component

  def prepare
    @foo = "foo from component"
  end

  def response
    div id: "my-component" do
      other_component slots: {
        my_slot_from_component: method(:my_slot_from_component),
        my_slot_from_page: slots[:my_slot_from_page]
      }
    end
  end

  def my_slot_from_component
    span id: "my-slot-from-component" do
      plain @foo
    end
  end

end
```

Then, put both components (note that some component uses other component so that's how they're both in here) to use on the example page:

```ruby
class ExamplePage < Matestack::Ui::Page

  def prepare
    @foo = "foo from page"
  end

  def response
    div id: "page-div" do
      some_component slots: { my_slot_from_page: method(:my_slot_from_page) }
    end
  end

  def my_slot_from_page
    span id: "my-slot-from-page" do
      plain @foo
    end
  end

end
```

This gets rendered into the HTML below:

```markup
<div id="page-div">
  <div id="my-component">
    <div id="my-other-component">
      <span id="my-slot-from-component">
        foo from component
      </span>
      <br/>
      <span id="my-slot-from-page">
        foo from page
      </span>
      <br/>
      foo from other component
    </div>
  </div>
</div>
```

### Calling slots with params

Sometimes it's necessary to call a slot with params:

```ruby
class SomeComponent < Matestack::Ui::Component

  def response
    div id: "my-component" do
      User.last(10).each do |user|
        slot(:user_card, user)
      end
    end
  end

end
```

```ruby
class ExamplePage < Matestack::Ui::Page

  def response
    div do
      some_component slots: {
        user_card: method(:user_card)
      }
    end
  end

  def user_card user
    div class: "card" do
      plain user.name
    end
  end

end
```


================================================
FILE: docs/components/registry.md
================================================
# Registry

By default, components can be called directly like `Components::Card.call(title: "foo", body: "bar")` which will return the desired HTML string.

If desired, you can create alias methods in order to avoid the class call syntax:

{% code title="app/matestack/components/registry.rb" %}
```ruby
module Components::Registry

  def card(text=nil, options=nil, &block)
    Components::Card.call(text, options, &block)
  end

  #...

end
```
{% endcode %}

which then allows you to call the card component like `card(title: "foo", body: "bar")` if the above shown module is included properly.

As this is just a plain Ruby module, you need to include it in all contexts you want to use the alias method. It might be a good idea to create your own `ApplicationPage`, `ApplicationComponent` and `ApplicationLayout` as base classes for your pages, components ans layouts. In there, you include your component registry module(s) only once and have access to the alias methods in all child classes:

{% code title="app/matestack/application_page.rb" %}
```ruby
class ApplicationPage < Matestack::Ui::Page

  include Components::Registry

end
```
{% endcode %}

{% code title="app/matestack/application_component.rb" %}
```ruby
class ApplicationComponent < Matestack::Ui::Component

  include Components::Registry

end
```
{% endcode %}

{% code title="app/matestack/application_layout.rb" %}
```ruby
class ApplicationLayout < Matestack::Ui::Layout

  include Components::Registry

end
```
{% endcode %}


================================================
FILE: docs/components/usage-in-isolation.md
================================================
# Usage in Isolation



================================================
FILE: docs/components/usage-on-matestack-layouts.md
================================================
# Usage on Matestack Layouts



================================================
FILE: docs/components/usage-on-matestack-pages.md
================================================
# Usage on Matestack Pages



================================================
FILE: docs/components/usage-on-rails-views.md
================================================
# Components on Rails views

If you already have plenty of Rails views \(ERB, Haml or Slim\) and want to start creating small UI components in pure Ruby, you are able to use components on these existing views.

{% code title="app/matestack/components/products/teaser.rb" %}
```ruby
class Components::Products::Teaser < Matestack::Ui::Component

  requires :product

  def response
    a path: product_path(context.product), class: 'product-teaser' do
      div do
        h2 context.product.name
        paragraph conext.product.description
        b context.product.price
      end
    end
  end

end
```
{% endcode %}

The class is then called on your Rails view, in this case an ERB view:

```markup
<%= @products.each do |product| %>
  <%= Components::Products::Teaser.(product: product) %>
<% end %>
```

{% hint style="info" %}
This approach is suitable for existing apps and a good idea to migrate to Matestack step by step. If you start with a blank Rails app, we recommend to go full Matestack right away**!**
{% endhint %}



================================================
FILE: docs/getting-started/hello-world.md
================================================
# Hello World

WIP!


================================================
FILE: docs/getting-started/installation-update.md
================================================
# Installation & Update

## Installation

Add 'matestack-ui-core' to your Gemfile

```ruby
gem 'matestack-ui-core'
```

and run

```
$ bundle install
```

### Matestack folder

Create a folder called `matestack` in your app directory. All your Matestack layouts, pages and components will be defined there.

```
$ mkdir app/matestack
```

### Controller setup

Add the Matestack helper to your controllers. If you want to make the helpers available in all controllers, add it to your `ApplicationController` :

`app/controllers/application_controller.rb`

```ruby
class ApplicationController < ActionController::Base
  include Matestack::Ui::Core::Helper
  #...
end
```

Now, you are able to create UI components in pure Ruby and use them in your Rails views. Additionally you can substitute Rails views and layouts with Matestack pages and layouts.

## Update

### Ruby Gem

Depending on the entry in your Gemfile, you might need to adjust the allowed version ranges in order to update the Gem. After checked and adjusted the version ranges, run:

```bash
bundle update matestack-ui-core
```

and then check the installed version:

```bash
bundle info matestack-ui-core
```


================================================
FILE: docs/html-rendering/html-rendering.md
================================================
# Basic Rendering Mechanism

Matestack’s rendering mechanism takes care of converting Ruby into HTML:

```ruby
div class: "card shadow-sm border-0 bg-light", foo: "bar" do
  img path: "...", class: "w-100"
  div class: "card-body" do
    h5 "foo", class: "card-title"
    paragraph "bar", class: "card-text"
  end
end
```

will be rendered to:

```markup
<div class="card shadow-sm border-0 bg-light" foo="bar">
  <img src="..." class="w-100">
  <div class="card-body">
    <h5 class="card-title">foo</h5>
    <p class="card-text">bar</p>
  </div>
</div>
```

That's working because `matestack-ui-core` defines all kind of Ruby methods targeting Rails ActionView `tag` helper, rendering the desired HTML tag and content as a String. This enables you to build a well known DOM structure while writing and utilizing pure Ruby!

As you can see, you can add CSS classes and ids as well as custom tag attributes. This way `matestack-ui-core` can be combined with various [CSS frameworks](broken-reference), your custom styles and all kinds of reactivity systems.&#x20;

It’s already fun to write pure Ruby instead of HTML or any other templating engine syntax but this approach is really paying of, when you start using Ruby's language features in order to split your UI implementation into various small chunks, organized through included modules, class inheritance or simply multiple Ruby methods within one class!

{% hint style="info" %}
The above shown Ruby code lives in Ruby classes inheriting from `Matestack::Ui::Component`, `Matestack::Ui::Page` or Matestack::Ui::Layout - they are described in the following sections of these docs and might look like this:

```ruby
class Components::HelloWorld < Matestack::Ui::Component

  def response
    div class: "my-class" do
      plain "hello world!"
    end
  end

end
```
{% endhint %}

## Supported HTML Tags

### Void Tags

These tags by definition do not allow an inner HTML and therefore do not take an block but all kinds of tag attributes, e.g.:

```ruby
# ...
hr class: "some-class"
# ...
```

* area
* base
* br
* col
* hr
* img | _you can use `src` or `path` in order to reference the url to the image_
* input
* link
* meta
* param
* command
* keygen
* source

### Tags

The following tags take content via a block OR first (non-hash) argument and all kind of tag attributes, e.g.:

```ruby
# define inner HTML via a block
span class: "some-class" do
  plain "foo"
end
# OR: define inner HTML via a simple first non-hash argument 
span "foo", class: "some-class"
# ...
```

* a | _you can use `href` or `path` in order to reference the url of the link_
* abbr
* acronym
* address
* applet
* article
* aside
* audio
* b
* base
* basefont
* bdi
* bdo
* big
* blockquote
* body
* button
* canvas
* caption
* center
* cite
* code
* col
* colgroup
* data
* datalist
* dd
* del
* details
* dfn
* dialog
* dir
* div
* dl
* dt
* em
* embed
* fieldset
* figcaption
* figure
* font
* footer
* form
* frame
* frameset
* h1 | _also available via `heading size: 1`_
* h2 | _also available via `heading size: 2`_
* h3 | _also available via `heading size: 3`_
* h4 | _also available via `heading size: 4`_
* h5 | _also available via `heading size: 5`_
* h6 | _also available via `heading size: 6`_
* head
* header
* html
* i
* iframe
* ins
* kbd
* label
* legend
* li
* main
* map
* mark
* meter
* nav
* noframes
* noscript
* object
* ol
* optgroup
* option
* output
* paragraph | _p is not working as it's an alias for puts in Ruby core_
* picture
* pre
* progress
* q
* rp
* rt
* ruby
* s
* samp
* script
* section
* select
* small
* span
* strike
* strong
* style
* sub
* summary
* sup
* svg
* table
* tbody
* td
* template
* textarea
* tfoot
* th
* thead
* time
* title
* tr
* track
* tt
* u
* ul
* var
* video
* wbr

## Text Rendering

In order to render plain text, do:

```ruby
#...
plain "hello world!"
# "hello world!" alone would not be rendered!
#...
```

## Tag/Data Attributes

Matestack's rendering mechanism automatically renders all given options as tag attributes. For convenience, data attributes can be passend in within a data hash:

```ruby
div class: "foo", id: "bar", hello: "world", data: { foo: "bar" } do
  #...
end
```

```markup
<div class="foo" id="bar" hello="world" data-foo="bar">
  <!-- ... -->
</div>
```

## Custom HTML Tags

If you want to use HTML tags which are not supported by Matestack's rendering mechanism by default, you can call ActionView's `tag` helper manually:

[https://apidock.com/rails/ActionView/Helpers/TagHelper/tag](https://apidock.com/rails/ActionView/Helpers/TagHelper/tag)

```ruby
plain tag.xyz("foo")
```

will render:

```markup
<xyz>foo</xyz>
```


================================================
FILE: docs/html-rendering/integrating-action-view-helpers.md
================================================
# Integrating Action View Helpers

Using Rails view helpers ([https://api.rubyonrails.org/classes/ActionView/Helpers.html](https://api.rubyonrails.org/classes/ActionView/Helpers.html)) in components, pages and layouts is supported when using the approaches shown below;

## Helpers without a block

Simple Action View helpers working without a block, can easily be integrated in a Matestack class response by calling `plain`:

```ruby
def response
  plain t("my.locale")
  # ...
  plain link_to "Show", post_path(@post)
  # ...
  plain my_own_view_helper_method
  # ...
  plain any_method_returning_a_string
end
```

## Helpers yielding a block

If you want to use a helper like `form_for` you have to follow following approach:

```ruby
def response
  # ...
  plain do # <-- add this
    form_with url: "/some_path" do |f|
      matestack_to_s do # <-- add this, which converst following block to a string
        plain f.text_field :foo # <-- call plain here again
        br
        div class: "some-input-wrapper" do
          plain f.text_field :bar
        end
        br
        plain f.submit
      end
    end
  end
  # ...
  plain do
    link_to root_path do
      matestack_to_s do
        div class: "some-link-wrapper" do
          plain "foo from block"
        end
      end
    end
  end
  # ...
  # Code below will not work!
  plain link_to root_path do
    matestack_to_s do
      div class: "some-link-wrapper" do
        plain "foo from block"
      end
    end
  end
end
```

{% hint style="info" %}
A component needs to be called in context of a controller (with included `Matestack::Ui::Core::Helper`), which is true when you're calling components from Rails views or on Matestack Pages/Layouts (which are themselves called by a controller normally).

When calling a component in isolation (which is possible), the view helpers might not work properly, especially when (implicitly) requiring a request object!
{% endhint %}

{% hint style="info" %}
We're currently working on an improved way to integrate ActionView Helpers which will enable removing the `plain` calls from your code.
{% endhint %}


================================================
FILE: docs/html-rendering/reusing-views-or-partials.md
================================================
# Integrating Rails Views or Partials

Matestack `rails_render` component offers the possibility to render a view or partial by passing its name and required params to it.

## Components reusing partials

Imagine the partial `app/views/products/_teaser.html.erb` containing following content:

```markup
<%= link_to product_path(product), class: 'product-teaser' do %>
  <div>
    <h2><%= product.name %></h2>
    <p><%= product.description %></p>
    <b><%= product.price %></b>
  </div>
<% end %>
```

```ruby
class Components::Products::Trending < Matestack::Ui::Component

  def prepare
    @products = Product.where(trending: true)
  end

  def response
    h1 'Trending products'
    @products.each do |product|
      rails_render partial: '/products/teaser', locals: { product: product }
    end
  end

end
```

As you see, we used the `rails_render` component here to render our products teaser partial. Given the string rails searches for a partial in `app/views/products/_teaser.html.erb`. As our product teaser partial uses a `product` we pass in a product as a `local`.

`rails_render` works with ERB, Haml and Slim Templates, as long as you have installed and configured the desired templating engine correctly in your Rails app.

## Components reusing views

As mentioned above the `rails_render` component can not only render partials but also views. Following Rails view can be reused within a Matestack component:

`app/views/static/index.html.erb`

```markup
<main>
  <%= render partial: 'products/teaser', collection: products, as: :product %>
</main>

<div>
  <%= link_to 'All products', products_path %>
</div>
```

```ruby
class Components::Products::Index < Matestack::Ui::Component

  def prepare
    @products = Product.where(trending: true)
  end

  def response
    rails_render template: '/static/index', locals: { products: @products }
  end

end
```


================================================
FILE: docs/layouts/api.md
================================================
# API

A layout class defines a layout within its `response` method and is suppose to yield the content of a page.

## Response

Use the `response` method to define the UI of the app by using Matestack's HTML rendering and optionally calling components.

```ruby
class SomeApp < Matestack::Ui::App

  def response
    nav do 
      a path: some_rails_path, text: "Navigate!"
    end
    main do
      yield
    end
    footer do
      div id: "div-on-app" do
        SomeComponent.()
      end
    end
  end

end
```

## Partials and helper methods

Use partials to keep the code dry and indentation layers manageable!

### Local partials on page level

In the page definition, see how this time from inside the response, the `my_partial` method below is called:

```ruby
class SomeApp < Matestack::Ui::App

  def response
    nav do 
      a path: some_rails_path, text: "Navigate!"
    end
    main do
      yield
    end
    footer do
      div id: "div-on-app" do
        SomeComponent.()
      end
      my_partial "foo from app"
    end
  end

  private # optionally mark your partials as private

  def my_partial text
    div class: "nested" do
      plain text
    end
  end

end
```

### Partials defined in modules

Extract code snippets to modules for an even better project structure. First, create a module:

```ruby
module MySharedPartials

  def my_partial text
    div class: "nested" do
      plain text
    end
  end

end
```

Include the module in the page:

```ruby
class SomeApp < Matestack::Ui::App

  include MySharedPartials

  def response
    nav do 
      a path: some_rails_path, text: "Navigate!"
    end
    main do
      yield
    end
    footer do
      div id: "div-on-app" do
        SomeComponent.()
      end
      my_partial "foo from app"
    end
  end

end
```

### Helper methods

Not only can instance methods be used as "partials" but as general helpers performing any kind of logic or data resolving:

```ruby
class SomeApp < Matestack::Ui::App

  def response
    nav do 
      a path: some_rails_path, text: "Navigate!"
    end
    main do
      if is_admin?
        yield
      else
        plain "not authorized"
      end 
    end
  end

  private # optionally mark your helper methods as private

  def is_admin?
    true # some crazy Ruby logic!
  end

end
```

## Prepare

Use a prepare method to resolve instance variables before rendering a page if required.

```ruby
class SomeApp < Matestack::Ui::App

  def prepare
    @heading = "Foo"
  end

  def response
    h1 @heading
    nav do 
      a path: some_rails_path, text: "Navigate!"
    end
    main do
      yield
    end
  end

end
```

## Params access

An app can access request information, e.g. url query params, by calling the `params` method:

```ruby
class SomeApp < Matestack::Ui::App

  def response
    nav do 
      a path: some_rails_path, text: "Navigate!"
    end
    main do
      plain params[:foo] # "bar" 
      yield
    end
  end

end
```

Now, visiting the respective route to the page, e.g. via `/xyz?foo=bar`, the page reads the `[:foo]` from the params and displays it.


================================================
FILE: docs/layouts/rails-controller-integration.md
================================================
# Rails Controller Integration

Just like a Rails layout would yield a Rails view, a Matestack layout yields a Matestack page. The layout uses Matestack's HTML rendering mechanism in a `response` method and may additionally call other components in order to define a specific UI.

{% code title="app/matestack/some_app/some_layout.rb" %}
```ruby
class SomeApp::SomeLayout < Matestack::Ui::Layout

  def response
    h1 "Some App"
    main do
      yield
    end
  end

end
```
{% endcode %}

In this basic example the layout is using the methods `h1` and `main` in order to create the markup as well as a `yield` in order to yield a page on a specific position.

{% hint style="info" %}
A Matestack layout itself will be yielded into the Rails layout, unless the Rails layout is disabled in the controller via:`layout false`
{% endhint %}

Usually a layout implies a specific context of your application. Multiple pages are then scoped within that context, which could lead to a file structure like:

```bash
app/matestack/
|
└───some_app/
│   │   some_layout.rb
│   └───pages/
│   │   │   page1.rb
│   │   │   page2.rb
│   │   │   page3.rb
```

and then used in a controller like this:



### Feature walk-through

#### 1. Create UI components in pure Ruby

Craft your UI based on your components written in pure Ruby. Utilizing Ruby's amazing language features, you're able to create a cleaner and more maintainable UI implementation.

**Implement UI components in pure Ruby**

Create Ruby classes within your Rails project and call Matestack's core components through a Ruby DSL in order to craft your UIs. The Ruby method "div" for example calls one of the static core components, responsible for rendering HTML tags. A component can take Strings, Integers Symbols, Arrays or Hashes (...) as optional properties (e.g. "title") or require them (e.g. "body").

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      div class: "card-body" do
        h5 context.title if context.title.present?
        paragraph context.body, class: "card-text"
      end
    end
  end

end
```

**Use your Ruby UI components on your existing Rails views**

Components can be then called on Rails views (not only! see below), enabling you to create a reusable card components, abstracting UI complexity in your own components.

`app/views/your_view.html.erb`

```erb
<!-- some other erb markup -->
<%= Components::Card.call(title: "hello", body: "world") %>
<!-- some other erb markup -->
```

**Use Ruby methods as partials**

Split your UI implementation into multiple small chunks helping others (and yourself) to better understand your implementation. Using this approach helps you to create a clean, readable and maintainable codebase.

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image
  optional :footer

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      card_content
      card_footer if context.footer.present?
    end
  end

  def card_content
    div class: "card-body" do
      h5 context.title if context.title.present?
      paragraph context.body, class: "card-body"
    end
  end

  def card_footer
    div class: "card-footer text-muted" do
      plain footer
    end
  end

end
```

`app/views/your_view.html.erb`

```erb
<!-- some other erb markup -->
<%= Components::Card.call(title: "hello", body: "world", footer: "foo") %>
<!-- some other erb markup -->
```

**Use class inheritance**

Because it's just a Ruby class, you can use class inheritance in order to further improve the quality of your UI implementation. Class inheritance can be used to easily create variants of UI components but still reuse parts of the implementation.

`app/matestack/components/blue_card.rb`

```ruby
class Components::BlueCard < Components::Card

  def response
    div class: "card shadow-sm border-0 bg-primary text-white" do
      img path: context.image, class: "w-100" if context.image.present?
      card_content #defined in parent class
      card_footer if context.footer.present? #defined in parent class
    end
  end

end
```

`app/views/your_view.html.erb`

```erb
<!-- some other erb markup -->
<%= Components::BlueCard.call(title: "hello", body: "world") %>
<!-- some other erb markup -->
```

**Use components within components**

Just like you used matestack's core components on your own UI component, you can use your own UI components within other custom UI components. You decide when using a Ruby method partial should be replaced by another self contained UI component!

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      # calling the CardBody component rather than using Ruby method partials
      Components::CardBody.call(title: context.title, body: context.body)
    end
  end

end
```

`app/matestack/components/card_body.rb`

```ruby
class Components::CardBody < Matestack::Ui::Component

  required :body
  optional :title

  def response
    # Just an example. Would make more sense, if this component had
    # a more complex structure
    div class: "card-body" do
      h5 context.title if context.title.present?
      paragraph context.body, class: "card-body"
    end
  end

end
```

**Yield components into components**

Sometimes it's not enough to just pass simple data into a component. No worries! You can just yield a block into your components! Using this approach gives you more flexibility when using your UI components. Ofcourse yielding can be used alongside passing in simple params.

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      Components::CardBody.call() do
        # yielding a block into the card_body component
        h5 context.title if context.title.present?
        paragraph context.body, class: "card-body"
      end
    end
  end

end
```

`app/matestack/components/card_body.rb`

```ruby
class Components::CardBody < Matestack::Ui::Component

  def response
    # Just an example. Would make more sense, if this component had
    # a more complex structure
    div class: "card-body" do
      yield if block_given?
    end
  end

end
```

**Use named slots for advanced content injection**

If you need to inject multiple blocks into your UI component, you can use "slots"! Slots help you to build complex UI components with multiple named content placeholders for highest implementation flexibility!

`app/matestack/components/card.rb`

```ruby
class Components::Card < Matestack::Ui::Component

  required :body
  optional :title
  optional :image

  def response
    div class: "card shadow-sm border-0 bg-light" do
      img path: context.image, class: "w-100" if context.image.present?
      Components::CardBody.call(slots: {
        heading: method(:heading_slot),
        body: method(:body_slot)
      })
    end
  end

  def heading_slot
    h5 context.title if context.title.present?      
  end

  def body_slot
    paragraph context.body, class: "card-body"
  end

end
```

`app/matestack/components/card_body.rb`

```ruby
class Components::CardBody < Matestack::Ui::Component

  required :slots

  def response
    # Just an example. Would make more sense, if this component had
    # a more complex structure
    div class: "card-body" do
      div class: "heading-section" do
        slot :heading
      end
      div class: "body-section" do
        slot :body
      end
    end
  end

end
```

#### 2. Substitute Rails Views with Matestack Pages

Until here we used Matestack components on Rails views. If desired you can go one step further and use Matestack components on something called a Matestack Page:

A Matestack page can be compared to a Rails view and might be yielded within a layout provided by an associated Matestack layout class (see below). The page itself uses Matestack's HTML rendering mechanism in a `response` method and may additionally call other components in order to define a specific UI.

{% code title="app/matestack/pages/some_page.rb" %}
```ruby
class Pages::SomePage < Matestack::Ui::Page

  def response
    div class: "container" do
      span id: "hello" do
        plain "hello world!"
      end
      Components::Card.call(title: "foo", body: "bar")
    end
  end

end
```
{% endcode %}

Pages are used as Rails view substitutes and therefore called in a Rails controller action:

{% code title="app/controllers/some_controller.rb" %}
```ruby
class SomeController < ApplicationController

  include Matestack::Ui::Core::Helper

  def overview
    render Pages::SomePage
  end

end
```
{% endcode %}

The page response - in this case - will be yielded into the Rails layout if not specified differently.

#### 3. Wrap Matestack Pages in Matestack Layouts

Just like a Rails layout would yield a Rails view, a Matestack layout yields a Matestack page. The layout uses Matestack's HTML rendering mechanism in a `response` method and may additionally call other components in order to define a specific UI.

{% code title="app/matestack/some_app/some_layout.rb" %}
```ruby
class SomeApp::SomeLayout < Matestack::Ui::Layout

  def response
    h1 "Some App"
    main do
      yield
    end
  end

end
```
{% endcode %}

In this basic example the layout is using the methods `h1` and `main` in order to create the markup as well as a `yield` in order to yield a page on a specific position.

{% hint style="info" %}
A Matestack layout itself will be yielded into the Rails layout, unless the Rails layout is disabled in the controler via:`layout false`
{% endhint %}

Usually a layout implies a specific context of your application. Multiple pages are then scoped within that context, which could lead to a file structure like:

```bash
app/matestack/
|
└───some_app/
│   │   some_layout.rb
│   └───pages/
│   │   │   page1.rb
│   │   │   page2.rb
│   │   │   page3.rb
```

and then used in a controller like this:

{% code title="app/controllers/some_controller.rb" %}
```ruby
class SomeController < ApplicationController

  include Matestack::Ui::Core::Helper

  matestack_layout SomeApp::SomeLayout

  def page_1
    render SomeApp::Pages::Page1
  end

  def page_2
    render SomeApp::Pages::Page2
  end

  def page_3
    render SomeApp::Pages::Page3, matestack_layout: false # skip app layout on this page
  end

end
```
{% endcode %}


================================================
FILE: docs/migrate-from-2.x-to-3.0.md
================================================
# Migrating from 2.x to 3.0

## Core/VueJs repo and gem split

* `matestack-ui-core` previously contained logic for
  * Ruby -> HTML conversion
  * Reactivity via prebuilt and custom Vue.js components
* in order to have better seperation of concerns, we've moved the reactivity related things to its own repository/gem -> `matestack-ui-vue_js`
* `matestack-ui-core` is now meant to be combined with any reactivity framework or none at all

{% hint style="warning" %}
**Please follow the migration guide within the docs of `matestack-ui-vuejs` when using reactivity features of `matestack-ui-core` 2.x**
{% endhint %}

## Remove `matestack-ui-core` JavaScript package

- `matestack-ui-core` does not ship a JavaScript package anymore
- please remove the package from your application and switch to `matestack-ui-vuejs` for the VueJs driven reactivity if required

```
yarn remove matestack-ui-core
```

## `Matestack::Ui::App` is now called `Matestack::Ui::Layout`

* `Matestack::Ui::App` was always meant to be a layout wrapping pages, but was supercharged with some vuejs logic before splitting the `core` and `vuejs` repos
* now `Matestack::Ui::App` is only a layout, that's why it should be named like that: `Matestack::Ui::Layout`

\-> Search\&Replace

## `matestack_app` method is renamed to `matestack_layout`

* following the above mentioned naming adjustment, the `matestack_app` method used on controller level is renamed to `matestack_layout`

`app/controllers/demo_controller.rb`

```ruby
class DemoController < ActionController::Base
  include Matestack::Ui::Core::Helper

  layout "application" # root rails layout file

  matestack_layout DemoApp::Layout # <-- renamed from matestack_app

  def foo
    render DemoApp::Pages::Foo
  end

end
```

\-> Search\&Replace

## `Matestack::Ui::Layout` `Matestack::Ui::Page` wrapping DOM structures

* previously, `Matestack::Ui::App` added some wrapping DOM structure around the whole layout and around it's `yield`
* this enabled dynamic page transition and loading state animations
* `Matestack::Ui::Layout` now purely renders the layout and yields a page without anything in between
* the wrapping DOM structres required for dynamic page transitions and loading state animations needs to be added via two new components if you want to use these features via `matestack-ui-vue_js` (see section below!)

`matestack/some/app/layout.rb`

```ruby
class Some::App::Layout < Matestack::Ui::Layout
  def response
    h1 "Demo App"
    main do
      yield
    end
  end
end
```

`matestack/some/app/pages/some_page.rb`

```ruby
class Some::App::Pages::SomePage < Matestack::Ui::Page
  def response
    h2 "Some Page"
  end
end
```

will just render:

```html
<body> <!-- coming from rails layout if specified -->
  <!-- no wrapping DON structure around the layout -->
  <h1>Demo App</<h1>
  <main>
    <!-- page markup without any wrapping DOM structure -->
    <h2>Some Page</h2>
  <main>
</body>
```

\-> Adjust CSS if you have created any rules targeting the wrapping DOM structure which now only is applied when using components from `matestack-ui-vuejs` explicitly


================================================
FILE: docs/pages/api.md
================================================
# Page API

## Response

Use the `response` method to define the UI of the page by using Matestack's HTML rendering or calling components.

```ruby
class SomePage < Matestack::Ui::Page

  def response
    div id: "div-on-page" do
      SomeComponent.()
    end
  end

end
```

```ruby
  class SomeComponent < Matestack::Ui::Component

    def response
      div id: "my-component" do
        plain "hello world!"
      end
    end

  end
```

## Partials and helper methods

Use partials to keep the code dry and indentation layers manageable!

### Local partials on page level

In the page definition, see how this time from inside the response, the `my_partial` method below is called:

```ruby
class SomePage < Matestack::Ui::Page

  def response
    div id: "my-page" do
      my_partial "foo from page"
    end
  end

  private # optionally mark your partials as private

  def my_partial text
    div class: "nested"
      plain text
    end
  end

end
```

### Partials defined in modules

Extract code snippets to modules for an even better project structure. First, create a module:

```ruby
module MySharedPartials

  def my_partial text
    div class: "nested"
      plain text
    end
  end

end
```

Include the module in the page:

```ruby
class SomePage < Matestack::Ui::Page

  include MySharedPartials

  def response
    div id: "my-page" do
      my_partial "foo from component"
    end
  end

end
```

### Helper methods

Not only can instance methods be used as "partials" but as general helpers performing any kind of logic or data resolving:

```ruby
class SomePage < Matestack::Ui::Page

  def response
    div id: "my-page" do
      if is_admin?
        latest_users.each do |user|
          div do
            plain user.name # ...
          end
        end
      else
        plain "not authorized"
      end 
    end
  end

  private # optionally mark your helper methods as private

  def is_admin?
    true # some crazy Ruby logic!
  end

  def latest_users
    User.last(10) # calling ActiveRecord models for example
  end

end
```

## Prepare

Use a prepare method to resolve instance variables before rendering a page if required.

```ruby
class SomePage < Matestack::Ui::Page

  def prepare
    @some_data = "some data"
  end

  def response
    div id: "my-page" do
      plain @some_data
    end
  end

end
```

## Params access

A page can access request information, e.g. url query params, by calling the `params` method:

```ruby
class SomePage < Matestack::Ui::Page

  def response
    div id: "my-page" do
      plain params[:foo]
    end
  end

end
```

Now, visiting the respective route to the page, e.g. via `/xyz?foo=bar`, the page reads the `[:foo]` from the params and displays it.

## Passing data to pages

Sometimes you want to pass in data from the calling controller action into the page. This works the same way as seen at components:

```ruby
class SoomeController < ActionController::Base

  include Matestack::Ui::Core::Helper

  def some_page
    render SomePage, foo: 'bar', bar: 'baz'
  end

end
```

```ruby
class SomePage < Matestack::Ui::Page

  required :foo
  optional :bar

  def response
    div id: "my-page" do
      plain context.foo # "bar"
      plain context.bar # "baz"
    end
  end

end
```



================================================
FILE: docs/pages/rails-controller-integration.md
================================================
# Rails Controller Integration

Pages are used as Rails view substitutes and therefore called in a Rails controller action:

{% code title="app/controllers/some_controller.rb" %}
```ruby
class SomeController < ApplicationController

  include Matestack::Ui::Core::Helper

  def overview
    render Pages::SomePage
  end

end
```
{% endcode %}

{% hint style="info" %}
A Matestack page will in this case be yielded into the Rails layout, unless the Rails layout is disabled in the controller via:`layout false`
{% endhint %}

## Passing data to pages

Sometimes you want to pass in data from the calling controller action into the page. This works the same way as seen at components:

```ruby
class SomeController < ActionController::Base

  include Matestack::Ui::Core::Helper

  def some_page
    render SomePage, foo: 'bar', bar: 'baz'
  end

end
```

```ruby
class SomePage < Matestack::Ui::Page

  required :foo
  optional :bar

  def response
    div id: "my-page" do
      plain context.foo # "bar"
      plain context.bar # "baz"
    end
  end

end
```


================================================
FILE: entrypoint.sh
================================================
#!/bin/bash
set -e

if [[ ! -e /app/Gemfile.lock ]]; then
    bundle install
fi

# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"


================================================
FILE: lib/matestack/ui/component.rb
================================================
Matestack::Ui::Component = Matestack::Ui::Core::Component

================================================
FILE: lib/matestack/ui/core/base.rb
================================================
require_relative 'tag_helper'

module Matestack
  module Ui
    module Core
      class Base
        include ActionView::Helpers::TagHelper

        include Matestack::Ui::Core::Properties
        include Matestack::Ui::Core::TagHelper

        attr_accessor :html_tag, :text, :options, :parent, :escape, :bind_to_parent

        def initialize(html_tag = nil, text = nil, options = {}, &block)
          return unless render?

          if options && options[:detach_from_parent] == true
            self.bind_to_parent = false
          else
            self.bind_to_parent = ([:without_parent].include?(html_tag) ? false : true)
          end
          self.slots = self.options.delete(:slots) if self.options
          # extract_options(text, options) is called in properties
          self.html_tag = html_tag if self.bind_to_parent
          self.escape = self.options.delete(:escape) || true
          self.parent = Matestack::Ui::Core::Context.parent
          self.parent.children << self if self.parent if self.bind_to_parent
          self.prepare
          Matestack::Ui::Core::Context.parent = self
          create_children(&block)
          Matestack::Ui::Core::Context.parent = self.parent
          self
        end

        # can be optionally overwritten in subclass
        # in order to conditionally render the component
        def render?
          true
        end

        # check if text is given and set text and options accordingly
        def extract_options(text, options)
          if text.is_a? Hash
            # we need to dup the text object because we're deleting keys from this object which manipulates the object passed in here
            # if this object is reused after beeing injected into this component, the keys would be missing
            self.options = text.dup
          else
            self.text = text
            # we need to dup the options object because we're deleting keys from this object which manipulates the object passed in here
            # if this object is reused after beeing injected into this component, the keys would be missing
            self.options = options.dup || {}
          end
          self.options.symbolize_keys!
        end

        def prepare
          # can be optionally overwritten in subclass in order to set
          # instance vars for example, might get deprecated in the future
        end

        # create child items by either running the response method if exists or executing the block
        # overwrite if needed (like in pages or apps)
        def create_children(&block)
          if respond_to?(:response)
            self.response &block
          else
            block.call if block_given?
          end
        end

        def self.call(text = nil, options = {}, &block)
          self.new(nil, text, options, &block).render_content
        end

        def children
          @children ||= []
        end

        def render_content
          if children.empty?
            child_content = self.escape ? ERB::Util.html_escape(text) : text if text
          else
            # using "\n" in order to preserve the 1.x rendering behavior which impacts appearance in browser
            child_content = (children.map { |child| " \n " + child.render_content }.join + " \n ").html_safe
          end
          result = ''
          if self.html_tag
            result = tag.public_send(self.html_tag, child_content, **self.options || {})
          elsif child_content
            result = child_content
          end
          result
        end

        def params
          Matestack::Ui::Core::Context.params || ActionController::Parameters.new({})
        end

        def view_context
          if Matestack::Ui::Core::Context.controller.nil?
            Matestack::Ui::Core::Context.controller = ActionController::Base.new
          else
            Matestack::Ui::Core::Context.controller&.view_context
          end
        end

        def method_missing(name, *args, **kwargs, &block)
          if view_context && view_context.respond_to?(name, true)
            view_context_response = view_context.send(name, *args, **kwargs, &block)
            return view_context_response
          end
          if Rails.application.routes.url_helpers.respond_to?(name, true)
            return Rails.application.routes.url_helpers.send(name, *args, &block)
          end
          return raise NameError, "#{name} is not defined for #{self.class}", caller
        end

        def to_str
          render_content
        end
        alias to_s to_str

      end
    end
  end
end


================================================
FILE: lib/matestack/ui/core/component.rb
================================================
module Matestack
  module Ui
    module Core
      class Component < Base
      end
    end
  end
end

================================================
FILE: lib/matestack/ui/core/context.rb
================================================
module Matestack
  module Ui
    module Core
      class Context < ActiveSupport::CurrentAttributes

        attribute :layout
        attribute :parent
        attribute :isolated_parent
        attribute :params
        attribute :controller
        attribute :component_block
        attribute :async_components

      end
    end
  end
end


================================================
FILE: lib/matestack/ui/core/helper.rb
================================================
module Matestack
  module Ui
    module Core
      module Helper

        def self.included(base)
          base.extend ClassMethods
        end

        module ClassMethods
          def inherited(subclass)
            subclass.matestack_layout(@matestack_layout)
            super
          end

          def matestack_layout(layout = nil)
            @matestack_layout = layout ? layout : @matestack_layout
          end
        end

        def render(*args)
          setup_context
          if args.first.is_a?(Class) && args.first.ancestors.include?(Base)
            raise 'expected a hash as second argument' unless args.second.is_a?(Hash) || args.second.nil?

            begin
              controller_layout = self.class.send(:_layout)
            rescue
              controller_layout = nil
            end

            options = args.second || {}
            layout = options.delete(:matestack_layout) || self.class.matestack_layout
            page = args.first

            if controller_layout == false
              root_layout = layout ? layout.layout : false
            else
              # when using the turbo-rails gem, controller_layout is a Proc
              # https://github.com/hotwired/turbo-rails/blob/v1.0.1/app/controllers/turbo/frames/frame_request.rb#L16
              # and not nil or a string indicating which layout to be used like before
              if controller_layout.nil? || controller_layout.is_a?(Proc)
                root_layout = "application"
              else
                root_layout = controller_layout
              end
            end

            if layout && params[:only_page].nil? && params[:component_key].nil? && params[:component_class].nil?
              render_layout layout, page, options, root_layout
            else
              if params[:component_key] && params[:component_class].nil?
                render_component layout, page, params[:component_key], options
              elsif params[:component_class]
                if params[:component_key]
                  render_component nil, params[:component_class].constantize, params[:component_key], JSON.parse(params[:public_options] || '{}')
                else
                  render html: params[:component_class].constantize.(public_options: JSON.parse(params[:public_options] || '{}'))
                end
              else
                if params[:only_page]
                  render_page page, options, false
                else
                  render_page page, options, root_layout
                end
              end
            end
          else
            super
          end
        end

        def render_layout(layout, page, options, root_layout)
          render html: layout.new(options) { page.new(options) }.render_content.html_safe, layout: root_layout
        end

        def render_page(page, options, root_layout)
          render html: page.new(options).render_content.html_safe, layout: root_layout
        end

        def render_component(layout, page, component_key, options)
          layout ? layout.new(options) { page.new(options) } : page.new(options) # create page structure in order to later access registered async components
          render html: Matestack::Ui::Core::Context.async_components[component_key].render_content.html_safe, layout: false
        end

        def setup_context
          Matestack::Ui::Core::Context.params = self.params
          Matestack::Ui::Core::Context.controller = (self.class <= ActionController::Base) ? self : @_controller
        end

      end
    end
  end
end


================================================
FILE: lib/matestack/ui/core/layout.rb
================================================
module Matestack
  module Ui
    module Core
      class Layout < Base

        def initialize(options = {})
          @controller = Context.controller
          Context.layout = self
          super(nil, nil, options)
        end

        # layout class method to specify if a rails layout should be used
        def self.inherited(subclass)
          subclass.layout(@layout)
          super
        end

        def self.layout(layout = nil)
          @layout = layout ? layout : @layout
        end

      end
    end
  end
end


================================================
FILE: lib/matestack/ui/core/page.rb
================================================
module Matestack
  module Ui
    module Core
      class Page < Base

        def initialize(options = {})
          super(nil, nil, options)
        end

      end
    end
  end
end


================================================
FILE: lib/matestack/ui/core/properties.rb
================================================
module Matestack
  module Ui
    module Core
      module Properties

        def self.included(base)
          base.extend ClassMethods
          base.send :prepend, Initializer
        end

        module Initializer
          def initialize(html_tag = nil, text = nil, options = {}, &block)
            extract_options(text, options)
            create_context
            set_text
            super
          end
        end

        module ClassMethods
          extend Gem::Deprecate

          def required(*args)
            @required = (@required || []).concat(args)
          end
          alias requires required

          def optional(*args)
            @optional = (@optional || []).concat(args)
          end

          def required_property_keys
            @required
          end

          def optional_property_keys
            @optional
          end

          def inherited(subclass)
            subclass.required(*required_property_keys)
            subclass.optional(*optional_property_keys)
            super
          end
        end

        def context
          @context ||= OpenStruct.new
        end
        alias :ctx :context

        def required_property_keys
          self.class.required_property_keys || []
        end

        def optional_property_keys
          self.class.optional_property_keys || []
        end

        def create_context
          create_context_for_properties(self.required_property_keys, required: true)
          create_context_for_properties(self.optional_property_keys)
        end

        def create_context_for_properties(properties, required: false)
          properties.uniq.each do |property|
            if property.is_a? Hash
              property.each do |key, value|
                method_name = value[:as] || key
                raise "required property '#{key}' is missing for '#{self.class}'" if required && self.options[key].nil?
                context.send(:"#{method_name}=", self.options.delete(key))
              end
            else
              raise "required property '#{property}' is missing for '#{self.class}'" if required && self.options[property].nil?
              context.send(:"#{property}=", self.options.delete(property))
            end
          end if properties
        end

        def set_text
          # the text property is treated specially since 2.0.0 enables text injection for all components like:
          #
          # some_component "foo", class: "whatever" -> self.text -> "foo"
          #
          # prior to 2.0.0, text injection happened like that:
          #
          # some_component text: "foo", class: "whatever" -> self.options[:text] -> "foo"
          #
          # in both cases "foo" should be available via self.context.text AND self.text
          #
          # in 2.0.0 text is available via context.text if text is marked as required or optional
          # in order to have a consistent access, we make this text accessable via self.text as well in this case
          # in all cases, text is accessable via self.text AND self.context.text
          # we make the passed in text option available via context.text by default, even if not marked as required or optional
          #
          # additionally we need to delete text from the options, as they might be used to be rendered as
          # tag attributes without any whitelisting as happened prior to 2.0.0
          self.text = self.options.delete(:text) if self.options.has_key?(:text)
          self.context.text = self.text
        end
        
      end
    end
  end
end


================================================
FILE: lib/matestack/ui/core/slots.rb
================================================
module Matestack
  module Ui
    module Core
      module Slots

        attr_accessor :slots

        def slot(key, *args)
          slots[key].call(*args)
        end

      end
    end
  end
end

================================================
FILE: lib/matestack/ui/core/tag_helper.rb
================================================
require_relative 'slots'
module Matestack
  module Ui
    module Core
      module TagHelper
        extend Gem::Deprecate
        include Slots

        # can't take content or a block
        VOID_TAGS = %i[area base br col hr img input link meta param command keygen source]

        TAGS = [:a, :abbr, :acronym, :address, :applet, :area, :article, :aside, :audio, :b, :base, :basefont, :bdi, :bdo, :big, :blockquote, :body, :br, :button, :canvas, :caption, :center, :cite, :code, :col, :colgroup, :data, :datalist, :dd, :del, :details, :dfn, :dialog, :dir, :div, :dl, :dt, :em, :embed, :fieldset, :figcaption, :figure, :font, :footer, :form, :frame, :frameset, :h1, :h2, :h3, :h4, :h5, :h6, :head, :header, :hr, :html, :i, :iframe, :img, :input, :ins, :kbd, :label, :legend, :li, :link, :main, :map, :mark, :meta, :meter, :nav, :noframes, :noscript, :object, :ol, :optgroup, :option, :output, :paragraph, :param, :picture, :pre, :progress, :q, :rp, :rt, :ruby, :s, :samp, :script, :section, :select, :small, :source, :span, :strike, :strong, :style, :sub, :summary, :sup, :svg, :table, :tbody, :td, :template, :textarea, :tfoot, :th, :thead, :time, :title, :tr, :track, :tt, :u, :ul, :var, :video, :wbr]

        VOID_TAGS.each do |tag|
          define_method tag do |options = {}|
            Matestack::Ui::Core::Base.new(tag, nil, options)
          end
        end

        TAGS.each do |tag|
          define_method tag do |text = nil, options = {}, &block|
            tag = :p if tag == :paragraph
            Matestack::Ui::Core::Base.new(tag, text, options, &block)
          end
        end

        def plain(text=nil, options=nil, &block)
          if block_given?
            Matestack::Ui::Core::Base.new(nil, yield, options)
          else
            Matestack::Ui::Core::Base.new(nil, text, options)
          end
        end

        def unescape(text)
          Matestack::Ui::Core::Base.new(nil, text&.html_safe, escape: false)
        end
        alias unescaped unescape

        # override image in order to implement automatically using rails assets path
        def img(text = nil, options = {}, &block)
          # if :src attribut given try to replace automatically
          if src = text.delete(:path)
            text[:src] = ActionController::Base.helpers.asset_path(src)
          end
          Matestack::Ui::Core::Base.new(:img, text, options, &block)
        end

        def a(text = nil, options = {}, &block)
          # if :path attribut given rename to href
          if text.is_a?(Hash)
            text[:href] = text.delete(:path) if text[:href].nil?
          else
            options[:href] = options.delete(:path) if options[:href].nil?
          end
          Matestack::Ui::Core::Base.new(:a, text, options, &block)
        end

        # support old heading component
        def heading(text = nil, options=nil, &block)
          if text.is_a?(Hash)
            options = text
          end

          case options[:size]
          when 1
            h1(text, options, &block)
          when 2
            h2(text, options, &block)
          when 3
            h3(text, options, &block)
          when 4
            h4(text, options, &block)
          when 5
            h5(text, options, &block)
          when 6
            h6(text, options, &block)
          else
            h1(text, options, &block)
          end
        end

        def rails_render(options = {})
          plain render options
        end

        def detached(text=nil, options=nil, &block)
          options = {} if options.nil?
          options[:detach_from_parent] = true
          Matestack::Ui::Core::Base.new(nil, text, options, &block)
        end

        def detached_to_s(text=nil, options=nil, &block)
          detached(text, options, &block).to_str
        end
        alias matestack_to_s detached_to_s

      end
    end
  end
end


================================================
FILE: lib/matestack/ui/core/version.rb
================================================
module Matestack
  module Ui
    module Core
      VERSION = '3.0.1'
    end
  end
end


================================================
FILE: lib/matestack/ui/core.rb
================================================
base_path = 'matestack/ui/core'
require "#{base_path}/version"

module Matestack
  module Ui
    module Core

    end
  end
end

require "#{base_path}/context"
require "#{base_path}/properties"
require "#{base_path}/base"
require "#{base_path}/component"
require "#{base_path}/page"
require "#{base_path}/layout"
require "#{base_path}/helper"

# require abbreveations for apps, pages and components
require "matestack/ui/layout"
require "matestack/ui/page"
require "matestack/ui/component"


================================================
FILE: lib/matestack/ui/layout.rb
================================================
Matestack::Ui::Layout = Matestack::Ui::Core::Layout


================================================
FILE: lib/matestack/ui/page.rb
================================================
Matestack::Ui::Page = Matestack::Ui::Core::Page


================================================
FILE: matestack-ui-core.gemspec
================================================
$:.push File.expand_path("lib", __dir__)

# Maintain your gem's version:
require "matestack/ui/core/version"

# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
  s.name        = "matestack-ui-core"
  s.version     = Matestack::Ui::Core::VERSION
  s.authors     = ["Jonas Jabari"]
  s.email       = ["jonas@matestack.io"]
  s.homepage    = "https://matestack.io"
  s.summary     = "Escape the frontend hustle & easily create interactive web apps in pure Ruby."
  s.description = "Matestack provides a collection of open source gems made for Ruby on Rails developers. Matestack enables you to craft interactive web UIs without JavaScript in pure Ruby with minimum effort. UI code becomes a native and fun part of your Rails app."
  s.license     = "MIT"
  s.metadata    = { "source_code_uri" => "https://github.com/matestack/matestack-ui-core" }

  s.files = Dir["{app,config,db,lib,vendor}/**/*", "LICENSE", "Rakefile", "README.md"]

  s.add_dependency "rails", '>= 5.2'
end


================================================
FILE: results.txt
================================================
Capybara starting Puma...
* Version 4.3.5 , codename: Mysterious Traveller
* Min threads: 0, max threads: 4
* Listening on tcp://0.0.0.0:33123
.............................................................................................................................

Finished in 12.69 seconds (files took 2.38 seconds to load)
125 examples, 0 failures

Coverage report generated for Unit Tests to /app/coverage. 209 / 2187 LOC (9.56%) covered.


================================================
FILE: spec/core_spec_helper.rb
================================================
# This file was generated by the `rails generate rspec:install` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause
# this file to always be loaded, without a need to explicitly require it in any
# files.
#
# Given that it is always loaded, you are encouraged to keep this file as
# light-weight as possible. Requiring heavyweight dependencies from this file
# will add to the boot time of your test suite on EVERY test run, even for an
# individual file that may not need all of that loaded. Instead, consider making
# a separate helper file that requires the additional dependencies and performs
# the additional setup, and require it from the spec files that actually need
# it.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
require 'simplecov'
SimpleCov.start do
  enable_coverage :branch

  add_filter "/spec"
  add_filter %r{^/config/}


  add_group "Concepts", "/app/concepts"
  add_group "Helpers", "/app/helpers"
  add_group "App Lib", "/app/lib"
  add_group "Lib", %r{^/lib/}

  track_files "{app,lib}/**/*.rb"
end

require 'webmock/rspec'
WebMock.allow_net_connect!

require File.join File.dirname(__FILE__), 'dummy', 'config', 'environment.rb'

Dir[File.join File.dirname(__FILE__), 'test', 'core', 'support', '**', '*.rb'].each { |f| require f }

require 'pry'

# require 'rspec/retry'
# require "rspec/wait"

RSpec.configure do |config|

  # run retry only on features
  # config.around :each, :js do |ex|
  #   ex.run_with_retry retry: 3
  # end

  # config.include Capybara::DSL
  # rspec-expectations config goes here. You can use an alternate
  # assertion/expectation library such as wrong or the stdlib/minitest
  # assertions if you prefer.
  config.expect_with :rspec do |expectations|
    # This option will default to `true` in RSpec 4. It makes the `description`
    # and `failure_message` of custom matchers include text for helper methods
    # defined using `chain`, e.g.:
    #     be_bigger_than(2).and_smaller_than(4).description
    #     # => "be bigger than 2 and smaller than 4"
    # ...rather than:
    #     # => "be bigger than 2"
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  # rspec-mocks config goes here. You can use an alternate test double
  # library (such as bogus or mocha) by changing the `mock_with` option here.
  config.mock_with :rspec do |mocks|
    # Prevents you from mocking or stubbing a method that does not exist on
    # a real object. This is generally recommended, and will default to
    # `true` in RSpec 4.
    mocks.verify_partial_doubles = true
  end

  # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
  # have no way to turn it off -- the option exists only for backwards
  # compatibility in RSpec 3). It causes shared context metadata to be
  # inherited by the metadata hash of host groups and examples, rather than
  # triggering implicit auto-inclusion in groups with matching metadata.
  config.shared_context_metadata_behavior = :apply_to_host_groups

# The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content.
=begin
  # This allows you to limit a spec run to individual examples or groups
  # you care about by tagging them with `:focus` metadata. When nothing
  # is tagged with `:focus`, all examples get run. RSpec also provides
  # aliases for `it`, `describe`, and `context` that include `:focus`
  # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
  config.filter_run_when_matching :focus

  # Allows RSpec to persist some state between runs in order to support
  # the `--only-failures` and `--next-failure` CLI options. We recommend
  # you configure your source control system to ignore this file.
  config.example_status_persistence_file_path = "spec/examples.txt"

  # Limits the available syntax to the non-monkey patched syntax that is
  # recommended. For more details, see:
  #   - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
  #   - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
  #   - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
  config.disable_monkey_patching!

  # Many RSpec users commonly either run the entire suite or an individual
  # file, and it's useful to allow more verbose output when running an
  # individual spec file.
  if config.files_to_run.one?
    # Use the documentation formatter for detailed output,
    # unless a formatter has already been configured
    # (e.g. via a command-line flag).
    config.default_formatter = "doc"
  end

  # Print the 10 slowest examples and example groups at the
  # end of the spec run, to help surface which specs are running
  # particularly slow.
  config.profile_examples = 10

  # Run specs in random order to surface order dependencies. If you find an
  # order dependency and want to debug it, you can fix the order by providing
  # the seed, which is printed after each run.
  #     --seed 1234
  config.order = :random

  # Seed global randomization in this process using the `--seed` CLI option.
  # Setting this allows you to use `--seed` to deterministically reproduce
  # test failures related to randomization by passing the same `--seed` value
  # as the one that triggered the failure.
  Kernel.srand config.seed
=end

  config.before :all, type: :feature do
    unless Rails.application.routes.url_helpers.method_defined?(:matestack_components_test_path)
      Rails.application.routes.append do
        get '/matestack_components_test', to: 'matestack_components#matestack_components_test', as: :matestack_components_test
        get '/matestack_transition_test', to: 'matestack_components#matestack_transition_test', as: :matestack_transition_test
        get '/example', to: 'example#page'
        get '/base_example', to: 'example#base'
      end
      Rails.application.reload_routes!
    end
  end

end


================================================
FILE: spec/dummy/Rakefile
================================================
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require_relative 'config/application'

Rails.application.load_tasks


================================================
FILE: spec/dummy/app/assets/config/manifest.js
================================================
//= link_tree ../images
//= link_tree ../videos


================================================
FILE: spec/dummy/app/assets/images/.keep
================================================


================================================
FILE: spec/dummy/app/channels/application_cable/channel.rb
================================================
module ApplicationCable
  class Channel < ActionCable::Channel::Base
  end
end


================================================
FILE: spec/dummy/app/channels/application_cable/connection.rb
================================================
module ApplicationCable
  class Connection < ActionCable::Connection::Base
  end
end


================================================
FILE: spec/dummy/app/controllers/application_controller.rb
================================================
class ApplicationController < ActionController::Base
end


================================================
FILE: spec/dummy/app/controllers/concerns/.keep
================================================


================================================
FILE: spec/dummy/app/controllers/demo_core_controller.rb
================================================
class DemoCoreController < ActionController::Base
  include Matestack::Ui::Core::Helper

  layout "application_core"

  matestack_layout Demo::Core::Layout

  def first
    render Demo::Core::Pages::FirstPage
  end

  def second
    render Demo::Core::Pages::SecondPage
  end

end


================================================
FILE: spec/dummy/app/controllers/legacy_views/0_USED_IN_SPECS_DONT_TOUCH
================================================


================================================
FILE: spec/dummy/app/controllers/legacy_views/pages_controller.rb
================================================
# used in specs

class LegacyViews::PagesController < ApplicationController
  include Matestack::Ui::Core::Helper

  layout 'legacy_views'

  def viewcontext_custom_component
  end

end


================================================
FILE: spec/dummy/app/helpers/application_helper.rb
================================================
module ApplicationHelper
  include Matestack::Ui::Core::Helper
  include Matestack::Ui::Core::TagHelper
end


================================================
FILE: spec/dummy/app/javascript/channels/consumer.js
================================================
// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the `rails generate channel` command.

import { createConsumer } from "@rails/actioncable"

export default createConsumer()


================================================
FILE: spec/dummy/app/javascript/channels/index.js
================================================
// Load all the channels within this directory and all subdirectories.
// Channel files must be named *_channel.js.

const channels = require.context('.', true, /_channel\.js$/)
channels.keys().forEach(channels)


================================================
FILE: spec/dummy/app/javascript/packs/application.js
================================================
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb

require("@rails/ujs").start()
require("channels")


================================================
FILE: spec/dummy/app/javascript/packs/application_core.js
================================================
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb

// require("@rails/ujs").start()
// require("channels")


================================================
FILE: spec/dummy/app/jobs/application_job.rb
================================================
class ApplicationJob < ActiveJob::Base
end


================================================
FILE: spec/dummy/app/mailers/application_mailer.rb
================================================
class ApplicationMailer < ActionMailer::Base
  default from: 'from@example.com'
  layout 'mailer'
end


================================================
FILE: spec/dummy/app/matestack/components/legacy_views/pages/0_USED_IN_SPECS_DONT_TOUCH
================================================


================================================
FILE: spec/dummy/app/matestack/components/legacy_views/pages/viewcontext.rb
================================================
# used in specs

class Components::LegacyViews::Pages::Viewcontext < Matestack::Ui::Component

  def response
    div id: "my-component" do
      if view_context.view_renderer.instance_of?(ActionView::Renderer)
        plain "has access to ActionView Context"
      end
      plain link_to "Test Link", "/some/page" # calling an ActionView Url Helper here
      plain time_ago_in_words(3.minutes.from_now) # calling an ActionView Date Helper here
      plain "root_path: #{root_path}" # calling a Path Helper here
    end
  end

end


================================================
FILE: spec/dummy/app/matestack/demo/core/components/static_component.rb
================================================
class Demo::Core::Components::StaticComponent < Matestack::Ui::Component

  required :foo

  def response
    plain "A simple Static Component with given input foo: #{context.foo}"
  end

end


================================================
FILE: spec/dummy/app/matestack/demo/core/layout.rb
================================================
class Demo::Core::Layout < Matestack::Ui::Layout

  def response
    h1 "Demo Core App"

    paragraph do
      plain "play around! --> spec/dummy/app/matestack/demo/core/app.rb"
    end

    nav do
      a path: demo_core_first_page_path do
        button "First Page"
      end
      a path: demo_core_second_page_path do
        button "Second Page"
      end
    end

    main do
      yield
    end
  end

end


================================================
FILE: spec/dummy/app/matestack/demo/core/pages/first_page.rb
================================================
class Demo::Core::Pages::FirstPage < Matestack::Ui::Page

  def response
    h2 "First page"

    paragraph do
      plain "play around! --> spec/dummy/app/matestack/demo/core/pages/first_page.rb"
    end

    # you can call components on pages:
    Demo::Core::Components::StaticComponent.call(foo: "bar")
  end

end


================================================
FILE: spec/dummy/app/matestack/demo/core/pages/second_page.rb
================================================
class Demo::Core::Pages::SecondPage < Matestack::Ui::Page

  def response
    h2 "Second Page"

    paragraph do
      plain "play around! --> spec/dummy/app/matestack/demo/core/pages/second_page.rb"
    end

    # you can call components on pages:
    Demo::Core::Components::StaticComponent.call(foo: "baz")
  end

end


================================================
FILE: spec/dummy/app/models/0_USED_IN_SPECS_DONT_TOUCH
================================================


================================================
FILE: spec/dummy/app/models/application_record.rb
================================================
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end


================================================
FILE: spec/dummy/app/models/concerns/.keep
================================================


================================================
FILE: spec/dummy/app/models/dummy_child_model.rb
================================================
# used in specs

class DummyChildModel < ApplicationRecord

  validates :title, presence: true, uniqueness: true

  has_one_attached :file
  has_many_attached :files

end


================================================
FILE: spec/dummy/app/models/dummy_model.rb
================================================
# used in specs

class DummyModel < ApplicationRecord

  validates :title, presence: true, uniqueness: true

  has_one_attached :file
  has_many_attached :files

  has_many :dummy_child_models, index_errors: true #https://bigbinary.com/blog/errors-can-be-indexed-with-nested-attrbutes-in-rails-5
  accepts_nested_attributes_for :dummy_child_models, allow_destroy: true
end


================================================
FILE: spec/dummy/app/models/test_model.rb
================================================
# used in specs

class TestModel < ApplicationRecord

  has_one_attached :file

end


================================================
FILE: spec/dummy/app/views/_some_partial.html.erb
================================================
<h1>This is some partial</h1>
<p><%= foo %></p>

================================================
FILE: spec/dummy/app/views/demo/0_USED_IN_SPECS_DONT_TOUCH
================================================


================================================
FILE: spec/dummy/app/views/demo/_header.html.erb
================================================
<header>
  <h1>Rails Partial</h1>
  <p><%= @title %></p>
</header>

================================================
FILE: spec/dummy/app/views/demo/header.html.erb
================================================
<header>
  <h1>Rails View</h1>
  <p><%= @title %></p>
</header>

================================================
FILE: spec/dummy/app/views/layouts/0_USED_IN_SPECS_DONT_TOUCH
================================================


================================================
FILE: spec/dummy/app/views/layouts/application.html.erb
================================================
<!DOCTYPE html>
<html>
  <head>
    <title>Dummy</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= javascript_pack_tag 'application' %>
  </head>

  <body>
    <%= yield %>
    <div id='from-rails-layout'></div>
  </body>
</html>


================================================
FILE: spec/dummy/app/views/layouts/application_core.html.erb
================================================
<!DOCTYPE html>
<html>
  <head>
    <title>Core Demo</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= javascript_pack_tag 'application_core' %>
  </head>

  <body>
    <%= yield %>
  </body>
  <div id='from-rails-core-layout'></div> 
</html>


================================================
FILE: spec/dummy/app/views/layouts/legacy_views.erb
================================================
<!DOCTYPE html>
<html>
  <head>
    <title>Dummy</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= javascript_pack_tag 'application_vue_js' %>
  </head>

  <body>
    <div id='matestack-ui'>
      <nav>
        <ul>Page 1</ul>
        <ul>Page 2</ul>
      </nav>
      <div>
        <%= yield %>
      </div>
    </div>
  </body>
</html>


================================================
FILE: spec/dummy/app/views/legacy_views/pages/0_USED_IN_SPECS_DONT_TOUCH
================================================


================================================
FILE: spec/dummy/app/views/legacy_views/pages/viewcontext_custom_component.html.erb
================================================
<h1>Viewcontext Custom Component</h1>
<%= Components::LegacyViews::Pages::Viewcontext.() %>


================================================
FILE: spec/dummy/app/views/rails/0_USED_IN_SPECS_DONT_TOUCH
================================================


================================================
FILE: spec/dummy/app/views/rails/_some_partial.html.erb
================================================
<h2><%= name %></h2>
<% 5.times do |i| %>
  <p><%= i %><p>
<% end %>

================================================
FILE: spec/dummy/app/views/rails/index.html.erb
================================================
<h1>Test</h1>
<% 100.times do %>
  <div>
    <div>
      <div>
        <div>
          <div>
            <div>
              <b>Nested Content</b>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
<% end %>
<%= render partial: 'rails/some_partial', collection: (1..100).to_a, as: :name %>

================================================
FILE: spec/dummy/app/views/some_view.html.erb
================================================
<h1>A view :D</h1>
<p><%= foo %></p>

================================================
FILE: spec/dummy/bin/bundle
================================================
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __dir__)
load Gem.bin_path('bundler', 'bundle')


================================================
FILE: spec/dummy/bin/rails
================================================
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'


================================================
FILE: spec/dummy/bin/rake
================================================
#!/usr/bin/env ruby
require_relative '../config/boot'
require 'rake'
Rake.application.run


================================================
FILE: spec/dummy/bin/setup
================================================
#!/usr/bin/env ruby
require 'fileutils'
include FileUtils

# path to your application root.
APP_ROOT = File.expand_path('..', __dir__)

def system!(*args)
  system(*args) || abort("\n== Command #{args} failed ==")
end

chdir APP_ROOT do
  # This script is a starting point to setup your application.
  # Add necessary setup steps to this file.

  puts '== Installing dependencies =='
  system! 'gem install bundler --conservative'
  system('bundle check') || system!('bundle install')

  # Install JavaScript dependencies if using Yarn
  # system('bin/yarn')

  # puts "\n== Copying sample files =="
  # unless File.exist?('config/database.yml')
  #   cp 'config/database.yml.sample', 'config/database.yml'
  # end

  puts "\n== Preparing database =="
  system! 'bin/rails db:setup'

  puts "\n== Removing old logs and tempfiles =="
  system! 'bin/rails log:clear tmp:clear'

  puts "\n== Restarting application server =="
  system! 'bin/rails restart'
end


================================================
FILE: spec/dummy/bin/update
================================================
#!/usr/bin/env ruby
require 'fileutils'
include FileUtils

# path to your application root.
APP_ROOT = File.expand_path('..', __dir__)

def system!(*args)
  system(*args) || abort("\n== Command #{args} failed ==")
end

chdir APP_ROOT do
  # This script is a way to update your development environment automatically.
  # Add necessary update steps to this file.

  puts '== Installing dependencies =='
  system! 'gem install bundler --conservative'
  system('bundle check') || system!('bundle install')

  # Install JavaScript dependencies if using Yarn
  # system('bin/yarn')

  puts "\n== Updating database =="
  system! 'bin/rails db:migrate'

  puts "\n== Removing old logs and tempfiles =="
  system! 'bin/rails log:clear tmp:clear'

  puts "\n== Restarting application server =="
  system! 'bin/rails restart'
end


================================================
FILE: spec/dummy/bin/webpack
================================================
#!/usr/bin/env ruby

ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"]  ||= "development"

require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile",
  Pathname.new(__FILE__).realpath)

require "bundler/setup"

require "webpacker"
require "webpacker/webpack_runner"

APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
  Webpacker::WebpackRunner.run(ARGV)
end


================================================
FILE: spec/dummy/bin/webpack-dev-server
================================================
#!/usr/bin/env ruby

ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"]  ||= "development"

require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../../Gemfile",
  Pathname.new(__FILE__).realpath)

require "bundler/setup"

require "webpacker"
require "webpacker/dev_server_runner"

APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
  Webpacker::DevServerRunner.run(ARGV)
end


================================================
FILE: spec/dummy/bin/yarn
================================================
#!/usr/bin/env ruby
APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do
  begin
    exec "yarnpkg", *ARGV
  rescue Errno::ENOENT
    $stderr.puts "Yarn executable was not detected in the system."
    $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
    exit 1
  end
end


================================================
FILE: spec/dummy/config/application.5.2_rb
================================================
require_relative 'boot'

require 'rails/all'

Bundler.require(*Rails.groups)
require "matestack/ui/core"

module Dummy
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    # config.eager_load_paths += %W( #{config.root}/app/matestack/registry )
  end
end


================================================
FILE: spec/dummy/config/application.6.0_rb
================================================
require_relative 'boot'

require 'rails/all'

Bundler.require(*Rails.groups)
require "matestack/ui/core"

module Dummy
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    # config.eager_load_paths += %W( #{config.root}/app/matestack/registry )
  end
end


================================================
FILE: spec/dummy/config/application.6.1_rb
================================================
require_relative 'boot'

require 'rails/all'

Bundler.require(*Rails.groups)
require "matestack/ui/core"

module Dummy
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.1

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    # config.eager_load_paths += %W( #{config.root}/app/matestack/registry )
  end
end


================================================
FILE: spec/dummy/config/application.7.0_rb
================================================
require_relative 'boot'

require 'rails/all'

Bundler.require(*Rails.groups)
require "matestack/ui/core"

module Dummy
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 7.0

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    # config.eager_load_paths += %W( #{config.root}/app/matestack/registry )
  end
end


================================================
FILE: spec/dummy/config/application.rb
================================================
require_relative 'boot'

require 'rails/all'

Bundler.require(*Rails.groups)
require "matestack/ui/core"

module Dummy
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 7.0

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    # config.eager_load_paths += %W( #{config.root}/app/matestack/reg
Download .txt
gitextract_mexlutwf/

├── .dockerignore
├── .gitattributes
├── .gitbook.yaml
├── .github/
│   ├── FUNDING.yml
│   ├── issue_template.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── dockerpush.yml
├── .gitignore
├── .rspec
├── .ruby-version
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── Dockerfile.dev
├── Dockerfile.test
├── Gemfile
├── LICENSE
├── README.md
├── Rakefile
├── bin/
│   └── rails
├── ci/
│   ├── Dockerfile.test_5_2_ruby_2_6
│   ├── Dockerfile.test_6_0_ruby_2_6
│   ├── Dockerfile.test_6_1_ruby_2_7
│   ├── Dockerfile.test_6_1_ruby_3_0
│   ├── Dockerfile.test_7_0_ruby_3_0
│   ├── Gemfile.5.2
│   ├── Gemfile.6.0
│   ├── Gemfile.6.1
│   ├── Gemfile.7.0
│   ├── artifacts/
│   │   └── .keep
│   └── docker-compose.ci.yml
├── docker-compose.yml
├── docs/
│   ├── README.md
│   ├── SUMMARY.md
│   ├── components/
│   │   ├── api.md
│   │   ├── registry.md
│   │   ├── usage-in-isolation.md
│   │   ├── usage-on-matestack-layouts.md
│   │   ├── usage-on-matestack-pages.md
│   │   └── usage-on-rails-views.md
│   ├── getting-started/
│   │   ├── hello-world.md
│   │   └── installation-update.md
│   ├── html-rendering/
│   │   ├── html-rendering.md
│   │   ├── integrating-action-view-helpers.md
│   │   └── reusing-views-or-partials.md
│   ├── layouts/
│   │   ├── api.md
│   │   └── rails-controller-integration.md
│   ├── migrate-from-2.x-to-3.0.md
│   └── pages/
│       ├── api.md
│       └── rails-controller-integration.md
├── entrypoint.sh
├── lib/
│   └── matestack/
│       └── ui/
│           ├── component.rb
│           ├── core/
│           │   ├── base.rb
│           │   ├── component.rb
│           │   ├── context.rb
│           │   ├── helper.rb
│           │   ├── layout.rb
│           │   ├── page.rb
│           │   ├── properties.rb
│           │   ├── slots.rb
│           │   ├── tag_helper.rb
│           │   └── version.rb
│           ├── core.rb
│           ├── layout.rb
│           └── page.rb
├── matestack-ui-core.gemspec
├── results.txt
└── spec/
    ├── core_spec_helper.rb
    ├── dummy/
    │   ├── Rakefile
    │   ├── app/
    │   │   ├── assets/
    │   │   │   ├── config/
    │   │   │   │   └── manifest.js
    │   │   │   └── images/
    │   │   │       └── .keep
    │   │   ├── channels/
    │   │   │   └── application_cable/
    │   │   │       ├── channel.rb
    │   │   │       └── connection.rb
    │   │   ├── controllers/
    │   │   │   ├── application_controller.rb
    │   │   │   ├── concerns/
    │   │   │   │   └── .keep
    │   │   │   ├── demo_core_controller.rb
    │   │   │   └── legacy_views/
    │   │   │       ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │   │       └── pages_controller.rb
    │   │   ├── helpers/
    │   │   │   └── application_helper.rb
    │   │   ├── javascript/
    │   │   │   ├── channels/
    │   │   │   │   ├── consumer.js
    │   │   │   │   └── index.js
    │   │   │   └── packs/
    │   │   │       ├── application.js
    │   │   │       └── application_core.js
    │   │   ├── jobs/
    │   │   │   └── application_job.rb
    │   │   ├── mailers/
    │   │   │   └── application_mailer.rb
    │   │   ├── matestack/
    │   │   │   ├── components/
    │   │   │   │   └── legacy_views/
    │   │   │   │       └── pages/
    │   │   │   │           ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │   │   │           └── viewcontext.rb
    │   │   │   └── demo/
    │   │   │       └── core/
    │   │   │           ├── components/
    │   │   │           │   └── static_component.rb
    │   │   │           ├── layout.rb
    │   │   │           └── pages/
    │   │   │               ├── first_page.rb
    │   │   │               └── second_page.rb
    │   │   ├── models/
    │   │   │   ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │   │   ├── application_record.rb
    │   │   │   ├── concerns/
    │   │   │   │   └── .keep
    │   │   │   ├── dummy_child_model.rb
    │   │   │   ├── dummy_model.rb
    │   │   │   └── test_model.rb
    │   │   └── views/
    │   │       ├── _some_partial.html.erb
    │   │       ├── demo/
    │   │       │   ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │       │   ├── _header.html.erb
    │   │       │   └── header.html.erb
    │   │       ├── layouts/
    │   │       │   ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │       │   ├── application.html.erb
    │   │       │   ├── application_core.html.erb
    │   │       │   └── legacy_views.erb
    │   │       ├── legacy_views/
    │   │       │   └── pages/
    │   │       │       ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │       │       └── viewcontext_custom_component.html.erb
    │   │       ├── rails/
    │   │       │   ├── 0_USED_IN_SPECS_DONT_TOUCH
    │   │       │   ├── _some_partial.html.erb
    │   │       │   └── index.html.erb
    │   │       └── some_view.html.erb
    │   ├── bin/
    │   │   ├── bundle
    │   │   ├── rails
    │   │   ├── rake
    │   │   ├── setup
    │   │   ├── update
    │   │   ├── webpack
    │   │   ├── webpack-dev-server
    │   │   └── yarn
    │   ├── config/
    │   │   ├── application.5.2_rb
    │   │   ├── application.6.0_rb
    │   │   ├── application.6.1_rb
    │   │   ├── application.7.0_rb
    │   │   ├── application.rb
    │   │   ├── boot.rb
    │   │   ├── cable.yml
    │   │   ├── database.yml
    │   │   ├── environment.rb
    │   │   ├── environments/
    │   │   │   ├── development.rb
    │   │   │   ├── production.rb
    │   │   │   └── test.rb
    │   │   ├── initializers/
    │   │   │   ├── application_controller_renderer.rb
    │   │   │   ├── assets.rb
    │   │   │   ├── backtrace_silencers.rb
    │   │   │   ├── content_security_policy.rb
    │   │   │   ├── cookies_serializer.rb
    │   │   │   ├── filter_parameter_logging.rb
    │   │   │   ├── inflections.rb
    │   │   │   ├── matestack.rb
    │   │   │   ├── mime_types.rb
    │   │   │   ├── nested_attrs_error_index_patch.rb
    │   │   │   └── wrap_parameters.rb
    │   │   ├── locales/
    │   │   │   └── en.yml
    │   │   ├── puma.rb
    │   │   ├── routes.rb
    │   │   ├── spring.rb
    │   │   ├── storage.yml
    │   │   ├── webpack/
    │   │   │   ├── development.js
    │   │   │   ├── environment.js
    │   │   │   ├── production.js
    │   │   │   └── test.js
    │   │   └── webpacker.yml
    │   ├── config.ru
    │   ├── db/
    │   │   ├── migrate/
    │   │   │   ├── 20190419174203_create_test_models.rb
    │   │   │   ├── 20190427134012_create_dummy_models.rb
    │   │   │   ├── 20190908153924_create_dummy_child_models.rb
    │   │   │   ├── 20200427170812_create_active_storage_tables.active_storage.rb
    │   │   │   ├── 20201222161321_add_boolean_value_to_test_models.rb
    │   │   │   ├── 20210204135043_add_service_name_to_active_storage_blobs.active_storage.rb
    │   │   │   └── 20210204135044_create_active_storage_variant_records.active_storage.rb
    │   │   └── schema.rb
    │   ├── lib/
    │   │   └── assets/
    │   │       └── .keep
    │   ├── log/
    │   │   └── .keep
    │   ├── package.json
    │   ├── postcss.config.js
    │   └── public/
    │       ├── 404.html
    │       ├── 422.html
    │       └── 500.html
    ├── rails_core_spec_helper.rb
    ├── spec_helper.rb
    └── test/
        └── core/
            ├── base/
            │   ├── component/
            │   │   ├── argument_spec.rb
            │   │   ├── conditional_rendering_spec.rb
            │   │   ├── core_namespaces_spec.rb
            │   │   ├── custom_namespaces_spec.rb
            │   │   ├── options_spec.rb
            │   │   ├── partials_spec.rb
            │   │   ├── prepare_spec.rb
            │   │   ├── properties_spec.rb
            │   │   ├── slots_spec.rb
            │   │   ├── static_rendering_spec.rb
            │   │   ├── url_params_access_spec.rb
            │   │   ├── view_context_access_spec.rb
            │   │   └── yield_spec.rb
            │   ├── layout/
            │   │   ├── layout_resolving_spec.rb
            │   │   └── layout_spec.rb
            │   └── page/
            │       ├── controller_instance_access_spec.rb
            │       ├── orchestrates_components_spec.rb
            │       ├── partials_spec.rb
            │       ├── prepare_spec.rb
            │       ├── slots_spec.rb
            │       ├── url_params_access_spec.rb
            │       └── view_context_access_spec.rb
            ├── custom_component_spec.rb
            ├── html_rendering/
            │   ├── action_view_integration.rb
            │   ├── default_tags_spec.rb
            │   └── link_spec.rb
            ├── rails_render_spec.rb
            ├── support/
            │   ├── capybara.rb
            │   ├── core_spec_utils.rb
            │   ├── example_controller.rb
            │   ├── layout.rb
            │   ├── matestack_components_controller.rb
            │   ├── matestack_wrapper_layout.rb
            │   ├── matestack_wrapper_page.rb
            │   ├── test_controller.rb
            │   └── xss.rb
            └── xss_spec.rb
Download .txt
SYMBOL INDEX (527 symbols across 72 files)

FILE: lib/matestack/ui/core.rb
  type Matestack (line 4) | module Matestack
    type Ui (line 5) | module Ui
      type Core (line 6) | module Core

FILE: lib/matestack/ui/core/base.rb
  type Matestack (line 3) | module Matestack
    type Ui (line 4) | module Ui
      type Core (line 5) | module Core
        class Base (line 6) | class Base
          method initialize (line 14) | def initialize(html_tag = nil, text = nil, options = {}, &block)
          method render? (line 37) | def render?
          method extract_options (line 42) | def extract_options(text, options)
          method prepare (line 56) | def prepare
          method create_children (line 63) | def create_children(&block)
          method call (line 71) | def self.call(text = nil, options = {}, &block)
          method children (line 75) | def children
          method render_content (line 79) | def render_content
          method params (line 95) | def params
          method view_context (line 99) | def view_context
          method method_missing (line 107) | def method_missing(name, *args, **kwargs, &block)
          method to_str (line 118) | def to_str

FILE: lib/matestack/ui/core/component.rb
  type Matestack (line 1) | module Matestack
    type Ui (line 2) | module Ui
      type Core (line 3) | module Core
        class Component (line 4) | class Component < Base

FILE: lib/matestack/ui/core/context.rb
  type Matestack (line 1) | module Matestack
    type Ui (line 2) | module Ui
      type Core (line 3) | module Core
        class Context (line 4) | class Context < ActiveSupport::CurrentAttributes

FILE: lib/matestack/ui/core/helper.rb
  type Matestack (line 1) | module Matestack
    type Ui (line 2) | module Ui
      type Core (line 3) | module Core
        type Helper (line 4) | module Helper
          function included (line 6) | def self.included(base)
          type ClassMethods (line 10) | module ClassMethods
            function inherited (line 11) | def inherited(subclass)
            function matestack_layout (line 16) | def matestack_layout(layout = nil)
          function render (line 21) | def render(*args)
          function render_layout (line 73) | def render_layout(layout, page, options, root_layout)
          function render_page (line 77) | def render_page(page, options, root_layout)
          function render_component (line 81) | def render_component(layout, page, component_key, options)
          function setup_context (line 86) | def setup_context

FILE: lib/matestack/ui/core/layout.rb
  type Matestack (line 1) | module Matestack
    type Ui (line 2) | module Ui
      type Core (line 3) | module Core
        class Layout (line 4) | class Layout < Base
          method initialize (line 6) | def initialize(options = {})
          method inherited (line 13) | def self.inherited(subclass)
          method layout (line 18) | def self.layout(layout = nil)

FILE: lib/matestack/ui/core/page.rb
  type Matestack (line 1) | module Matestack
    type Ui (line 2) | module Ui
      type Core (line 3) | module Core
        class Page (line 4) | class Page < Base
          method initialize (line 6) | def initialize(options = {})

FILE: lib/matestack/ui/core/properties.rb
  type Matestack (line 1) | module Matestack
    type Ui (line 2) | module Ui
      type Core (line 3) | module Core
        type Properties (line 4) | module Properties
          function included (line 6) | def self.included(base)
          type Initializer (line 11) | module Initializer
            function initialize (line 12) | def initialize(html_tag = nil, text = nil, options = {}, &block)
          type ClassMethods (line 20) | module ClassMethods
            function required (line 23) | def required(*args)
            function optional (line 28) | def optional(*args)
            function required_property_keys (line 32) | def required_property_keys
            function optional_property_keys (line 36) | def optional_property_keys
            function inherited (line 40) | def inherited(subclass)
          function context (line 47) | def context
          function required_property_keys (line 52) | def required_property_keys
          function optional_property_keys (line 56) | def optional_property_keys
          function create_context (line 60) | def create_context
          function create_context_for_properties (line 65) | def create_context_for_properties(properties, required: false)
          function set_text (line 80) | def set_text

FILE: lib/matestack/ui/core/slots.rb
  type Matestack (line 1) | module Matestack
    type Ui (line 2) | module Ui
      type Core (line 3) | module Core
        type Slots (line 4) | module Slots
          function slot (line 8) | def slot(key, *args)

FILE: lib/matestack/ui/core/tag_helper.rb
  type Matestack (line 2) | module Matestack
    type Ui (line 3) | module Ui
      type Core (line 4) | module Core
        type TagHelper (line 5) | module TagHelper
          function plain (line 27) | def plain(text=nil, options=nil, &block)
          function unescape (line 35) | def unescape(text)
          function img (line 41) | def img(text = nil, options = {}, &block)
          function a (line 49) | def a(text = nil, options = {}, &block)
          function heading (line 60) | def heading(text = nil, options=nil, &block)
          function rails_render (line 83) | def rails_render(options = {})
          function detached (line 87) | def detached(text=nil, options=nil, &block)
          function detached_to_s (line 93) | def detached_to_s(text=nil, options=nil, &block)

FILE: lib/matestack/ui/core/version.rb
  type Matestack (line 1) | module Matestack
    type Ui (line 2) | module Ui
      type Core (line 3) | module Core

FILE: spec/dummy/app/channels/application_cable/channel.rb
  type ApplicationCable (line 1) | module ApplicationCable
    class Channel (line 2) | class Channel < ActionCable::Channel::Base

FILE: spec/dummy/app/channels/application_cable/connection.rb
  type ApplicationCable (line 1) | module ApplicationCable
    class Connection (line 2) | class Connection < ActionCable::Connection::Base

FILE: spec/dummy/app/controllers/application_controller.rb
  class ApplicationController (line 1) | class ApplicationController < ActionController::Base

FILE: spec/dummy/app/controllers/demo_core_controller.rb
  class DemoCoreController (line 1) | class DemoCoreController < ActionController::Base
    method first (line 8) | def first
    method second (line 12) | def second

FILE: spec/dummy/app/controllers/legacy_views/pages_controller.rb
  class LegacyViews::PagesController (line 3) | class LegacyViews::PagesController < ApplicationController
    method viewcontext_custom_component (line 8) | def viewcontext_custom_component

FILE: spec/dummy/app/helpers/application_helper.rb
  type ApplicationHelper (line 1) | module ApplicationHelper

FILE: spec/dummy/app/jobs/application_job.rb
  class ApplicationJob (line 1) | class ApplicationJob < ActiveJob::Base

FILE: spec/dummy/app/mailers/application_mailer.rb
  class ApplicationMailer (line 1) | class ApplicationMailer < ActionMailer::Base

FILE: spec/dummy/app/matestack/components/legacy_views/pages/viewcontext.rb
  class Components::LegacyViews::Pages::Viewcontext (line 3) | class Components::LegacyViews::Pages::Viewcontext < Matestack::Ui::Compo...
    method response (line 5) | def response

FILE: spec/dummy/app/matestack/demo/core/components/static_component.rb
  class Demo::Core::Components::StaticComponent (line 1) | class Demo::Core::Components::StaticComponent < Matestack::Ui::Component
    method response (line 5) | def response

FILE: spec/dummy/app/matestack/demo/core/layout.rb
  class Demo::Core::Layout (line 1) | class Demo::Core::Layout < Matestack::Ui::Layout
    method response (line 3) | def response

FILE: spec/dummy/app/matestack/demo/core/pages/first_page.rb
  class Demo::Core::Pages::FirstPage (line 1) | class Demo::Core::Pages::FirstPage < Matestack::Ui::Page
    method response (line 3) | def response

FILE: spec/dummy/app/matestack/demo/core/pages/second_page.rb
  class Demo::Core::Pages::SecondPage (line 1) | class Demo::Core::Pages::SecondPage < Matestack::Ui::Page
    method response (line 3) | def response

FILE: spec/dummy/app/models/application_record.rb
  class ApplicationRecord (line 1) | class ApplicationRecord < ActiveRecord::Base

FILE: spec/dummy/app/models/dummy_child_model.rb
  class DummyChildModel (line 3) | class DummyChildModel < ApplicationRecord

FILE: spec/dummy/app/models/dummy_model.rb
  class DummyModel (line 3) | class DummyModel < ApplicationRecord

FILE: spec/dummy/app/models/test_model.rb
  class TestModel (line 3) | class TestModel < ApplicationRecord

FILE: spec/dummy/config/application.rb
  type Dummy (line 8) | module Dummy
    class Application (line 9) | class Application < Rails::Application

FILE: spec/dummy/config/initializers/nested_attrs_error_index_patch.rb
  type ActiveRecord (line 4) | module ActiveRecord
    type AutosaveAssociation (line 5) | module AutosaveAssociation
      function validate_collection_association (line 6) | def validate_collection_association(reflection)

FILE: spec/dummy/db/migrate/20190419174203_create_test_models.rb
  class CreateTestModels (line 1) | class CreateTestModels < ActiveRecord::Migration[5.2]
    method change (line 2) | def change

FILE: spec/dummy/db/migrate/20190427134012_create_dummy_models.rb
  class CreateDummyModels (line 1) | class CreateDummyModels < ActiveRecord::Migration[5.2]
    method change (line 2) | def change

FILE: spec/dummy/db/migrate/20190908153924_create_dummy_child_models.rb
  class CreateDummyChildModels (line 1) | class CreateDummyChildModels < ActiveRecord::Migration[5.2]
    method change (line 2) | def change

FILE: spec/dummy/db/migrate/20200427170812_create_active_storage_tables.active_storage.rb
  class CreateActiveStorageTables (line 2) | class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
    method change (line 3) | def change

FILE: spec/dummy/db/migrate/20201222161321_add_boolean_value_to_test_models.rb
  class AddBooleanValueToTestModels (line 1) | class AddBooleanValueToTestModels < ActiveRecord::Migration[5.2]
    method change (line 2) | def change

FILE: spec/dummy/db/migrate/20210204135043_add_service_name_to_active_storage_blobs.active_storage.rb
  class AddServiceNameToActiveStorageBlobs (line 3) | class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0]
    method up (line 4) | def up
    method down (line 16) | def down
    method up (line 22) | def up
    method down (line 26) | def down
  class AddServiceNameToActiveStorageBlobs (line 21) | class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[5.2]
    method up (line 4) | def up
    method down (line 16) | def down
    method up (line 22) | def up
    method down (line 26) | def down

FILE: spec/dummy/db/migrate/20210204135044_create_active_storage_variant_records.active_storage.rb
  class CreateActiveStorageVariantRecords (line 3) | class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0]
    method change (line 4) | def change
    method change (line 16) | def change
  class CreateActiveStorageVariantRecords (line 15) | class CreateActiveStorageVariantRecords < ActiveRecord::Migration[5.2]
    method change (line 4) | def change
    method change (line 16) | def change

FILE: spec/test/core/base/component/argument_spec.rb
  class ComponentTestController (line 8) | class ComponentTestController < ActionController::Base
    method my_action (line 13) | def my_action
  class SomeStaticComponent (line 32) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 34) | def response
  class ExamplePage (line 43) | class ExamplePage < Matestack::Ui::Page
    method response (line 45) | def response

FILE: spec/test/core/base/component/conditional_rendering_spec.rb
  class ComponentTestController (line 7) | class ComponentTestController < ActionController::Base
    method my_action (line 11) | def my_action
  class DefaultRenderingComponent (line 27) | class DefaultRenderingComponent < Matestack::Ui::Component
    method response (line 28) | def response
  class ExamplePage (line 37) | class ExamplePage < Matestack::Ui::Page
    method response (line 38) | def response
    method response (line 65) | def response
    method response (line 92) | def response
  class ConditionalRenderingComponent (line 50) | class ConditionalRenderingComponent < Matestack::Ui::Component
    method response (line 51) | def response
    method render? (line 57) | def render?
    method response (line 78) | def response
    method render? (line 84) | def render?
  class ExamplePage (line 64) | class ExamplePage < Matestack::Ui::Page
    method response (line 38) | def response
    method response (line 65) | def response
    method response (line 92) | def response
  class ConditionalRenderingComponent (line 77) | class ConditionalRenderingComponent < Matestack::Ui::Component
    method response (line 51) | def response
    method render? (line 57) | def render?
    method response (line 78) | def response
    method render? (line 84) | def render?
  class ExamplePage (line 91) | class ExamplePage < Matestack::Ui::Page
    method response (line 38) | def response
    method response (line 65) | def response
    method response (line 92) | def response

FILE: spec/test/core/base/component/core_namespaces_spec.rb
  type Components (line 8) | module Components end
  type Pages (line 10) | module Pages end
  type Matestack::Ui::Core (line 12) | module Matestack::Ui::Core end
  class ComponentTestController (line 14) | class ComponentTestController < ActionController::Base
    method my_action (line 19) | def my_action
  type Matestack::Ui::Core::Component1 (line 39) | module Matestack::Ui::Core::Component1
  class Matestack::Ui::Core::Component1::Component1 (line 43) | class Matestack::Ui::Core::Component1::Component1 < Matestack::Ui::Compo...
    method response (line 44) | def response
  class Matestack::Ui::Core::Component1::Component2 (line 54) | class Matestack::Ui::Core::Component1::Component2 < Matestack::Ui::Compo...
    method response (line 55) | def response
  class Matestack::Ui::Core::Component1::ThirdComponent (line 65) | class Matestack::Ui::Core::Component1::ThirdComponent < Matestack::Ui::C...
    method response (line 66) | def response
  class Pages::ExamplePage (line 75) | class Pages::ExamplePage < Matestack::Ui::Page
    method response (line 76) | def response

FILE: spec/test/core/base/component/custom_namespaces_spec.rb
  type Components (line 8) | module Components end
  type Pages (line 10) | module Pages end
  type Matestack::Ui::Core (line 12) | module Matestack::Ui::Core end
  class ComponentTestController (line 14) | class ComponentTestController < ActionController::Base
    method my_action (line 19) | def my_action
  type Components (line 40) | module Components end
  class Components::Component1 (line 43) | class Components::Component1 < Matestack::Ui::Component
    method response (line 45) | def response
  type Components::Namespace1 (line 55) | module Components::Namespace1 end
  class Components::Namespace1::Component1 (line 58) | class Components::Namespace1::Component1 < Matestack::Ui::Component
    method response (line 60) | def response
  class Components::MyCamelcasedClassNameComponent (line 71) | class Components::MyCamelcasedClassNameComponent < Matestack::Ui::Component
    method response (line 73) | def response
  class Pages::ExamplePage (line 82) | class Pages::ExamplePage < Matestack::Ui::Page
    method response (line 84) | def response

FILE: spec/test/core/base/component/options_spec.rb
  class ComponentTestController (line 8) | class ComponentTestController < ActionController::Base
    method my_action (line 13) | def my_action
  class SomeStaticComponent (line 32) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 34) | def response
  class ExamplePage (line 43) | class ExamplePage < Matestack::Ui::Page
    method response (line 45) | def response
    method response (line 77) | def response
  class SpecialComponent (line 61) | class SpecialComponent < Matestack::Ui::Component
    method response (line 66) | def response
  class ExamplePage (line 75) | class ExamplePage < Matestack::Ui::Page
    method response (line 45) | def response
    method response (line 77) | def response

FILE: spec/test/core/base/component/partials_spec.rb
  class ComponentTestController (line 7) | class ComponentTestController < ActionController::Base
    method my_action (line 11) | def my_action
  class SomeStaticComponent (line 27) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 28) | def response
    method my_partial (line 34) | def my_partial text
    method response (line 65) | def response
  class ExamplePage (line 41) | class ExamplePage < Matestack::Ui::Page
    method response (line 43) | def response
    method response (line 75) | def response
  type MySharedPartials (line 56) | module MySharedPartials
    function my_partial (line 57) | def my_partial text
  class SomeStaticComponent (line 62) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 28) | def response
    method my_partial (line 34) | def my_partial text
    method response (line 65) | def response
  class ExamplePage (line 74) | class ExamplePage < Matestack::Ui::Page
    method response (line 43) | def response
    method response (line 75) | def response

FILE: spec/test/core/base/component/prepare_spec.rb
  class ComponentTestController (line 8) | class ComponentTestController < ActionController::Base
    method my_action (line 13) | def my_action
  class SomeStaticComponent (line 32) | class SomeStaticComponent < Matestack::Ui::Component
    method prepare (line 34) | def prepare
    method response (line 38) | def response
  class ExamplePage (line 47) | class ExamplePage < Matestack::Ui::Page
    method response (line 49) | def response

FILE: spec/test/core/base/component/properties_spec.rb
  class PropertyComponent (line 7) | class PropertyComponent < Matestack::Ui::Component
    method response (line 13) | def response
  class ExamplePage (line 27) | class ExamplePage < Matestack::Ui::Page
    method response (line 28) | def response
    method response (line 39) | def response
    method response (line 52) | def response
    method response (line 66) | def response
    method response (line 94) | def response
    method response (line 120) | def response
    method some_slot (line 124) | def some_slot
    method other_slot (line 128) | def other_slot
  class ExamplePage (line 38) | class ExamplePage < Matestack::Ui::Page
    method response (line 28) | def response
    method response (line 39) | def response
    method response (line 52) | def response
    method response (line 66) | def response
    method response (line 94) | def response
    method response (line 120) | def response
    method some_slot (line 124) | def some_slot
    method other_slot (line 128) | def other_slot
  class ExamplePage (line 51) | class ExamplePage < Matestack::Ui::Page
    method response (line 28) | def response
    method response (line 39) | def response
    method response (line 52) | def response
    method response (line 66) | def response
    method response (line 94) | def response
    method response (line 120) | def response
    method some_slot (line 124) | def some_slot
    method other_slot (line 128) | def other_slot
  class ExamplePage (line 65) | class ExamplePage < Matestack::Ui::Page
    method response (line 28) | def response
    method response (line 39) | def response
    method response (line 52) | def response
    method response (line 66) | def response
    method response (line 94) | def response
    method response (line 120) | def response
    method some_slot (line 124) | def some_slot
    method other_slot (line 128) | def other_slot
  class SetupComponent (line 80) | class SetupComponent < Matestack::Ui::Component
    method prepare (line 82) | def prepare
    method response (line 86) | def response
  class ExamplePage (line 93) | class ExamplePage < Matestack::Ui::Page
    method response (line 28) | def response
    method response (line 39) | def response
    method response (line 52) | def response
    method response (line 66) | def response
    method response (line 94) | def response
    method response (line 120) | def response
    method some_slot (line 124) | def some_slot
    method other_slot (line 128) | def other_slot
  class SlotComponent (line 109) | class SlotComponent < Matestack::Ui::Component
    method response (line 110) | def response
  class ExamplePage (line 119) | class ExamplePage < Matestack::Ui::Page
    method response (line 28) | def response
    method response (line 39) | def response
    method response (line 52) | def response
    method response (line 66) | def response
    method response (line 94) | def response
    method response (line 120) | def response
    method some_slot (line 124) | def some_slot
    method other_slot (line 128) | def other_slot
  class Component (line 145) | class Component < Matestack::Ui::Component
    method response (line 147) | def response
    method response (line 168) | def response
  class AnotherComponent (line 150) | class AnotherComponent < Component
  class Component (line 166) | class Component < Matestack::Ui::Component
    method response (line 147) | def response
    method response (line 168) | def response
  class AnotherComponent (line 171) | class AnotherComponent < Component
  class Component2 (line 187) | class Component2 < Matestack::Ui::Component
  class AnotherComponent2 (line 190) | class AnotherComponent2 < Component2
  class AliasPropertyComponent (line 202) | class AliasPropertyComponent < Matestack::Ui::Component
    method response (line 204) | def response
  class AnotherAliasPropertyComponent (line 207) | class AnotherAliasPropertyComponent < Matestack::Ui::Component
    method response (line 209) | def response
  class OptionalAliasPropertyComponent (line 224) | class OptionalAliasPropertyComponent < Matestack::Ui::Component
    method response (line 226) | def response
  class AnotherOptionalAliasPropertyComponent (line 229) | class AnotherOptionalAliasPropertyComponent < Matestack::Ui::Component
    method response (line 231) | def response

FILE: spec/test/core/base/component/slots_spec.rb
  class ComponentTestController (line 8) | class ComponentTestController < ActionController::Base
    method my_action (line 11) | def my_action
  class SomeStaticComponent (line 30) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 32) | def response
    method response (line 93) | def response
    method my_slot_from_component (line 103) | def my_slot_from_component
  class ExamplePage (line 43) | class ExamplePage < Matestack::Ui::Page
    method response (line 45) | def response
    method my_simple_slot (line 52) | def my_simple_slot
    method my_second_simple_slot (line 58) | def my_second_simple_slot
    method response (line 128) | def response
    method my_slot_from_page (line 135) | def my_slot_from_page
  class SomeStaticComponent (line 91) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 32) | def response
    method response (line 93) | def response
    method my_slot_from_component (line 103) | def my_slot_from_component
  class OtherComponent (line 112) | class OtherComponent < Matestack::Ui::Component
    method response (line 114) | def response
  class ExamplePage (line 126) | class ExamplePage < Matestack::Ui::Page
    method response (line 45) | def response
    method my_simple_slot (line 52) | def my_simple_slot
    method my_second_simple_slot (line 58) | def my_second_simple_slot
    method response (line 128) | def response
    method my_slot_from_page (line 135) | def my_slot_from_page

FILE: spec/test/core/base/component/static_rendering_spec.rb
  class ComponentTestController (line 7) | class ComponentTestController < ActionController::Base
    method my_action (line 11) | def my_action
  class SomeStaticComponent (line 27) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 28) | def response
  class ExamplePage (line 37) | class ExamplePage < Matestack::Ui::Page
    method response (line 38) | def response

FILE: spec/test/core/base/component/url_params_access_spec.rb
  class ComponentTestController (line 8) | class ComponentTestController < ActionController::Base
    method my_action (line 13) | def my_action
  class SomeStaticComponent (line 32) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 34) | def response
  class ExamplePage (line 45) | class ExamplePage < Matestack::Ui::Page
    method response (line 47) | def response

FILE: spec/test/core/base/component/view_context_access_spec.rb
  class SomeLayout (line 8) | class SomeLayout < Matestack::Ui::Layout
    method response (line 9) | def response
  class ComponentTestController (line 14) | class ComponentTestController < ActionController::Base
    method my_action (line 18) | def my_action
  class SomeStaticComponent (line 34) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 35) | def response
  class ExamplePage (line 49) | class ExamplePage < Matestack::Ui::Page
    method response (line 50) | def response

FILE: spec/test/core/base/component/yield_spec.rb
  class ComponentTestController (line 8) | class ComponentTestController < ActionController::Base
    method my_action (line 11) | def my_action
  class SomeStaticComponent (line 28) | class SomeStaticComponent < Matestack::Ui::Component
    method response (line 29) | def response
  class ExamplePage (line 38) | class ExamplePage < Matestack::Ui::Page
    method response (line 40) | def response

FILE: spec/test/core/base/layout/layout_resolving_spec.rb
  class ExamplePage (line 26) | class ExamplePage < Matestack::Ui::Page
    method response (line 28) | def response
    method response (line 74) | def response
    method response (line 124) | def response
  class RenderTestAController (line 36) | class RenderTestAController < ActionController::Base
    method example (line 41) | def example
  type ExampleApp (line 54) | module ExampleApp
  class ExampleApp::Layout (line 57) | class ExampleApp::Layout < Matestack::Ui::Layout
    method response (line 58) | def response
    method response (line 108) | def response
  class ExampleApp::SomeOtherExampleLayout (line 65) | class ExampleApp::SomeOtherExampleLayout < Matestack::Ui::Layout
    method response (line 66) | def response
    method response (line 116) | def response
  class ExamplePage (line 73) | class ExamplePage < Matestack::Ui::Page
    method response (line 28) | def response
    method response (line 74) | def response
    method response (line 124) | def response
  class RenderTestBController (line 82) | class RenderTestBController < ActionController::Base
    method example (line 86) | def example
    method second_example (line 90) | def second_example
  type ExampleApp (line 104) | module ExampleApp
  class ExampleApp::Layout (line 107) | class ExampleApp::Layout < Matestack::Ui::Layout
    method response (line 58) | def response
    method response (line 108) | def response
  class ExampleApp::SomeOtherExampleLayout (line 115) | class ExampleApp::SomeOtherExampleLayout < Matestack::Ui::Layout
    method response (line 66) | def response
    method response (line 116) | def response
  class ExamplePage (line 123) | class ExamplePage < Matestack::Ui::Page
    method response (line 28) | def response
    method response (line 74) | def response
    method response (line 124) | def response
  class RenderTestCController (line 132) | class RenderTestCController < ActionController::Base
    method example (line 137) | def example
    method second_example (line 141) | def second_example
  type Layouts (line 158) | module Layouts end
  class Layouts::ExampleLayout (line 159) | class Layouts::ExampleLayout < Matestack::Ui::Layout
    method response (line 160) | def response
  class Layouts::SomeOtherExampleLayout (line 167) | class Layouts::SomeOtherExampleLayout < Matestack::Ui::Layout
    method response (line 168) | def response
  type Pages (line 175) | module Pages end
  type Pages::ExampleLayout (line 176) | module Pages::ExampleLayout end
  type Pages::SomeOtherExampleLayout (line 177) | module Pages::SomeOtherExampleLayout end
  class Pages::ExampleLayout::ExamplePage (line 179) | class Pages::ExampleLayout::ExamplePage < Matestack::Ui::Page
    method response (line 180) | def response
  class Pages::SomeOtherExampleLayout::ExamplePage (line 187) | class Pages::SomeOtherExampleLayout::ExamplePage < Matestack::Ui::Page
    method response (line 188) | def response
  class RenderTestEController (line 197) | class RenderTestEController < ActionController::Base
    method example (line 201) | def example
    method second_example (line 205) | def second_example

FILE: spec/test/core/base/layout/layout_spec.rb
  type ExampleApp (line 17) | module ExampleApp
  class ExampleApp::App (line 20) | class ExampleApp::App < Matestack::Ui::Layout
    method response (line 21) | def response
    method response (line 78) | def response
  type ExampleApp::Pages (line 31) | module ExampleApp::Pages
  class ExampleApp::Pages::ExamplePage (line 34) | class ExampleApp::Pages::ExamplePage < Matestack::Ui::Page
    method response (line 35) | def response
    method response (line 92) | def response
  class ExampleApp::Pages::SecondExamplePage (line 42) | class ExampleApp::Pages::SecondExamplePage < Matestack::Ui::Page
    method response (line 43) | def response
  class ExampleAppPagesController (line 50) | class ExampleAppPagesController < ExampleController
    method page1 (line 54) | def page1
    method page2 (line 58) | def page2
    method page1 (line 104) | def page1
  type ExampleApp (line 72) | module ExampleApp
  class ExampleApp::App (line 75) | class ExampleApp::App < Matestack::Ui::Layout
    method response (line 21) | def response
    method response (line 78) | def response
  type ExampleApp::Pages (line 88) | module ExampleApp::Pages
  class ExampleApp::Pages::ExamplePage (line 91) | class ExampleApp::Pages::ExamplePage < Matestack::Ui::Page
    method response (line 35) | def response
    method response (line 92) | def response
  class ExampleAppPagesController (line 99) | class ExampleAppPagesController < ExampleController
    method page1 (line 54) | def page1
    method page2 (line 58) | def page2
    method page1 (line 104) | def page1

FILE: spec/test/core/base/page/controller_instance_access_spec.rb
  class ExamplePage (line 16) | class ExamplePage < Matestack::Ui::Page
    method response (line 18) | def response
  class PageTestController (line 26) | class PageTestController < ActionController::Base
    method my_action (line 29) | def my_action

FILE: spec/test/core/base/page/orchestrates_components_spec.rb
  class PageTestController (line 7) | class PageTestController < ActionController::Base
    method my_action (line 12) | def my_action
  class ExamplePage (line 28) | class ExamplePage < Matestack::Ui::Page
    method response (line 30) | def response

FILE: spec/test/core/base/page/partials_spec.rb
  class PageTestController (line 7) | class PageTestController < ActionController::Base
    method my_action (line 12) | def my_action
  class ExamplePage (line 28) | class ExamplePage < Matestack::Ui::Page
    method response (line 30) | def response
    method my_simple_partial (line 38) | def my_simple_partial
    method my_partial_with_param (line 44) | def my_partial_with_param some_param
    method my_partial_with_partial (line 50) | def my_partial_with_partial
    method response (line 103) | def response
    method my_simple_partial (line 111) | def my_simple_partial
    method my_partial_with_partial (line 117) | def my_partial_with_partial
  type MySharedPartials (line 89) | module MySharedPartials
    function my_partial_with_param (line 91) | def my_partial_with_param some_param
  class ExamplePage (line 99) | class ExamplePage < Matestack::Ui::Page
    method response (line 30) | def response
    method my_simple_partial (line 38) | def my_simple_partial
    method my_partial_with_param (line 44) | def my_partial_with_param some_param
    method my_partial_with_partial (line 50) | def my_partial_with_partial
    method response (line 103) | def response
    method my_simple_partial (line 111) | def my_simple_partial
    method my_partial_with_partial (line 117) | def my_partial_with_partial

FILE: spec/test/core/base/page/slots_spec.rb
  class PageTestController (line 7) | class PageTestController < ActionController::Base
    method my_action (line 12) | def my_action
  class SlotTestComponent (line 29) | class SlotTestComponent < Matestack::Ui::Component
    method prepare (line 31) | def prepare
    method response (line 35) | def response
  class ExamplePage (line 45) | class ExamplePage < Matestack::Ui::Page
    method response (line 47) | def response
    method my_simple_slot (line 54) | def my_simple_slot
    method my_second_simple_slot (line 60) | def my_second_simple_slot

FILE: spec/test/core/base/page/url_params_access_spec.rb
  class PageTestController (line 7) | class PageTestController < ActionController::Base
    method my_action (line 12) | def my_action
  class ExamplePage (line 28) | class ExamplePage < Matestack::Ui::Page
    method response (line 30) | def response

FILE: spec/test/core/base/page/view_context_access_spec.rb
  class PageTestController (line 7) | class PageTestController < ActionController::Base
    method my_action (line 12) | def my_action
  class ExamplePage (line 29) | class ExamplePage < Matestack::Ui::Page
    method response (line 31) | def response

FILE: spec/test/core/custom_component_spec.rb
  type Components (line 7) | module Components end
  type Pages (line 9) | module Pages end
  type Matestack::Ui::Core (line 11) | module Matestack::Ui::Core end
  class SomeLayout (line 13) | class SomeLayout < Matestack::Ui::Layout
    method response (line 14) | def response
  class ComponentTestController (line 19) | class ComponentTestController < ActionController::Base
    method my_action (line 23) | def my_action
  type Components (line 35) | module Components end
  class Components::CrazyComponent (line 37) | class Components::CrazyComponent < Matestack::Ui::Component
    method response (line 38) | def response
  class ExamplePage (line 47) | class ExamplePage < Matestack::Ui::Page
    method response (line 48) | def response

FILE: spec/test/core/html_rendering/action_view_integration.rb
  class ExamplePage (line 7) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 32) | def response
    method response (line 69) | def response
    method some_partial (line 89) | def some_partial
    method some_partial_rendering_view_helpers (line 95) | def some_partial_rendering_view_helpers f
  class ExamplePage (line 31) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 32) | def response
    method response (line 69) | def response
    method some_partial (line 89) | def some_partial
    method some_partial_rendering_view_helpers (line 95) | def some_partial_rendering_view_helpers f
  class ExamplePage (line 68) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 32) | def response
    method response (line 69) | def response
    method some_partial (line 89) | def some_partial
    method some_partial_rendering_view_helpers (line 95) | def some_partial_rendering_view_helpers f

FILE: spec/test/core/html_rendering/default_tags_spec.rb
  class ExamplePage (line 9) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 19) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 29) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 47) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 70) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 97) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 107) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 117) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 127) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 141) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 155) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 171) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 191) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 219) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 231) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 253) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 317) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 330) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 344) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 360) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 372) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 384) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 400) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 412) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 427) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response
  class ExamplePage (line 458) | class ExamplePage < Matestack::Ui::Page
    method response (line 10) | def response
    method response (line 20) | def response
    method response (line 30) | def response
    method response (line 48) | def response
    method response (line 71) | def response
    method response (line 98) | def response
    method response (line 108) | def response
    method response (line 118) | def response
    method response (line 128) | def response
    method response (line 142) | def response
    method response (line 156) | def response
    method response (line 172) | def response
    method response (line 192) | def response
    method response (line 220) | def response
    method response (line 232) | def response
    method response (line 254) | def response
    method response (line 318) | def response
    method response (line 331) | def response
    method response (line 345) | def response
    method response (line 361) | def response
    method response (line 373) | def response
    method response (line 385) | def response
    method response (line 401) | def response
    method response (line 413) | def response
    method response (line 428) | def response
    method response (line 459) | def response

FILE: spec/test/core/html_rendering/link_spec.rb
  class ExamplePage (line 7) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 27) | def response
    method response (line 48) | def response
    method response (line 74) | def response
    method response (line 100) | def response
    method response (line 119) | def response
    method set_app_class (line 150) | def set_app_class
    method response (line 164) | def response
    method set_app_class (line 176) | def set_app_class
    method response (line 201) | def response
    method set_app_class (line 210) | def set_app_class
  class ExamplePage (line 26) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 27) | def response
    method response (line 48) | def response
    method response (line 74) | def response
    method response (line 100) | def response
    method response (line 119) | def response
    method set_app_class (line 150) | def set_app_class
    method response (line 164) | def response
    method set_app_class (line 176) | def set_app_class
    method response (line 201) | def response
    method set_app_class (line 210) | def set_app_class
  class ExamplePage (line 47) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 27) | def response
    method response (line 48) | def response
    method response (line 74) | def response
    method response (line 100) | def response
    method response (line 119) | def response
    method set_app_class (line 150) | def set_app_class
    method response (line 164) | def response
    method set_app_class (line 176) | def set_app_class
    method response (line 201) | def response
    method set_app_class (line 210) | def set_app_class
  class ExamplePage (line 73) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 27) | def response
    method response (line 48) | def response
    method response (line 74) | def response
    method response (line 100) | def response
    method response (line 119) | def response
    method set_app_class (line 150) | def set_app_class
    method response (line 164) | def response
    method set_app_class (line 176) | def set_app_class
    method response (line 201) | def response
    method set_app_class (line 210) | def set_app_class
  class ExamplePage (line 99) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 27) | def response
    method response (line 48) | def response
    method response (line 74) | def response
    method response (line 100) | def response
    method response (line 119) | def response
    method set_app_class (line 150) | def set_app_class
    method response (line 164) | def response
    method set_app_class (line 176) | def set_app_class
    method response (line 201) | def response
    method set_app_class (line 210) | def set_app_class
  class ExamplePage (line 118) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 27) | def response
    method response (line 48) | def response
    method response (line 74) | def response
    method response (line 100) | def response
    method response (line 119) | def response
    method set_app_class (line 150) | def set_app_class
    method response (line 164) | def response
    method set_app_class (line 176) | def set_app_class
    method response (line 201) | def response
    method set_app_class (line 210) | def set_app_class
  class ExamplePage (line 146) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 27) | def response
    method response (line 48) | def response
    method response (line 74) | def response
    method response (line 100) | def response
    method response (line 119) | def response
    method set_app_class (line 150) | def set_app_class
    method response (line 164) | def response
    method set_app_class (line 176) | def set_app_class
    method response (line 201) | def response
    method set_app_class (line 210) | def set_app_class
  class MyTestApp (line 157) | class MyTestApp < Matestack::Ui::Layout
    method response (line 158) | def response
    method response (line 195) | def response
  class ExamplePage (line 163) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 27) | def response
    method response (line 48) | def response
    method response (line 74) | def response
    method response (line 100) | def response
    method response (line 119) | def response
    method set_app_class (line 150) | def set_app_class
    method response (line 164) | def response
    method set_app_class (line 176) | def set_app_class
    method response (line 201) | def response
    method set_app_class (line 210) | def set_app_class
  class MyTestApp (line 194) | class MyTestApp < Matestack::Ui::Layout
    method response (line 158) | def response
    method response (line 195) | def response
  class ExamplePage (line 200) | class ExamplePage < Matestack::Ui::Page
    method response (line 8) | def response
    method response (line 27) | def response
    method response (line 48) | def response
    method response (line 74) | def response
    method response (line 100) | def response
    method response (line 119) | def response
    method set_app_class (line 150) | def set_app_class
    method response (line 164) | def response
    method set_app_class (line 176) | def set_app_class
    method response (line 201) | def response
    method set_app_class (line 210) | def set_app_class

FILE: spec/test/core/rails_render_spec.rb
  class ExampleController (line 7) | class ExampleController < ApplicationController
    method page (line 8) | def page
    method page (line 16) | def page
  class ExampleController (line 15) | class ExampleController < ApplicationController
    method page (line 8) | def page
    method page (line 16) | def page
  class ExamplePage (line 22) | class ExamplePage < Matestack::Ui::Page
    method response (line 23) | def response

FILE: spec/test/core/support/core_spec_utils.rb
  type CoreSpecUtils (line 1) | module CoreSpecUtils
    function stripped (line 3) | def stripped(html_string)
    function path_exists? (line 11) | def path_exists?(path_as_symbol)
    function register_component (line 18) | def register_component(dsl_method, component_class)
    function register_self_as (line 26) | def register_self_as(dsl_method)
    function matestack_render (line 30) | def matestack_render(reset_app: true, page: MatestackWrapperPage, &block)
    function matestack_layout (line 36) | def matestack_layout(&block)
    function reset_matestack_layout (line 40) | def reset_matestack_layout

FILE: spec/test/core/support/example_controller.rb
  class ExampleController (line 3) | class ExampleController < ApplicationController
    method page (line 9) | def page
    method base (line 13) | def base

FILE: spec/test/core/support/layout.rb
  class Layout (line 3) | class Layout < Matestack::Ui::Layout
    method response (line 5) | def response

FILE: spec/test/core/support/matestack_components_controller.rb
  class MatestackComponentsController (line 4) | class MatestackComponentsController < ApplicationController
    method matestack_components_test (line 9) | def matestack_components_test
    method matestack_transition_test (line 13) | def matestack_transition_test

FILE: spec/test/core/support/matestack_wrapper_layout.rb
  class MatestackWrapperLayout (line 1) | class MatestackWrapperLayout < Matestack::Ui::Layout
    method response (line 2) | def response
    method app_body (line 7) | def app_body

FILE: spec/test/core/support/matestack_wrapper_page.rb
  class MatestackWrapperPage (line 1) | class MatestackWrapperPage < Matestack::Ui::Page
    method response (line 2) | def response

FILE: spec/test/core/support/test_controller.rb
  class TestController (line 1) | class TestController < ActionController::Base
    method check_params (line 4) | def check_params
    method expect_params (line 8) | def expect_params(params)

FILE: spec/test/core/support/xss.rb
  type XSS (line 1) | module XSS

FILE: spec/test/core/xss_spec.rb
  function expect_alert (line 52) | def expect_alert(alert)
Condensed preview — 206 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (338K chars).
[
  {
    "path": ".dockerignore",
    "chars": 439,
    "preview": "node_modules/\nspec/dummy/db/*.sqlite3\nspec/dummy/db/*.sqlite3-journal\nspec/dummy/log/*.log\nspec/dummy/node_modules/\nspec"
  },
  {
    "path": ".gitattributes",
    "chars": 30,
    "preview": "docs/* linguist-documentation\n"
  },
  {
    "path": ".gitbook.yaml",
    "chars": 68,
    "preview": "root: ./docs/\n\nstructure:\n  readme: README.md\n  summary: SUMMARY.md\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 67,
    "preview": "# These are supported funding model platforms\n\ngithub: [matestack]\n"
  },
  {
    "path": ".github/issue_template.md",
    "chars": 935,
    "preview": "<!-- This is a template only, remove/add sections below as appropriate (e.g. for a new feature, there might be no 'curre"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 333,
    "preview": "**Note:** If you submit a feature or bugfix PR, pick **develop** as target branch (and delete this line afterwards).\n\n##"
  },
  {
    "path": ".github/workflows/dockerpush.yml",
    "chars": 2126,
    "preview": "name: specs\n\non:\n  push:\n    paths-ignore:\n      - 'docs/**'\n      - 'README.md'\n      - 'CHANGELOG.md'\n\njobs:\n  test_7_"
  },
  {
    "path": ".gitignore",
    "chars": 293,
    "preview": ".bundle/\nlog/*.log\nnode_modules/\ncoverage/\nspec/dummy/db/*.sqlite3\nspec/dummy/db/*.sqlite3-journal\nspec/dummy/log/*.log\n"
  },
  {
    "path": ".rspec",
    "chars": 22,
    "preview": "--require spec_helper\n"
  },
  {
    "path": ".ruby-version",
    "chars": 6,
    "preview": "2.6.5\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 45832,
    "preview": "# Changelog\n\n## v3.0.1 Release - 2022-04-29\n\n### Bugfixes\n\n- fixing layout resolving issue when using the `turbo-rails` "
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3351,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "Dockerfile.dev",
    "chars": 313,
    "preview": "FROM ruby:3.0-alpine3.12\n\nRUN gem install bundler:2.1.4\n\nRUN apk update --no-cache && \\\n    apk add build-base postgresq"
  },
  {
    "path": "Dockerfile.test",
    "chars": 825,
    "preview": "FROM ruby:3.0-alpine3.12\n\nRUN gem install bundler:2.1.4\n\nRUN apk update --no-cache && \\\n    apk add build-base postgresq"
  },
  {
    "path": "Gemfile",
    "chars": 1034,
    "preview": "source 'https://rubygems.org'\ngit_source(:github) { |repo| \"https://github.com/#{repo}.git\" }\n\n# Declare your gem's depe"
  },
  {
    "path": "LICENSE",
    "chars": 1051,
    "preview": "Copyright (c) MateLab GmbH\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this softwar"
  },
  {
    "path": "README.md",
    "chars": 9309,
    "preview": "[![Specs](https://github.com/matestack/matestack-ui-core/workflows/specs/badge.svg)](https://github.com/matestack/matest"
  },
  {
    "path": "Rakefile",
    "chars": 1377,
    "preview": "begin\n  require 'bundler/setup'\nrescue LoadError\n  puts 'You must `gem install bundler` and `bundle install` to run rake"
  },
  {
    "path": "bin/rails",
    "chars": 563,
    "preview": "#!/usr/bin/env ruby\n# This command will automatically be run when you run \"rails\" with Rails gems\n# installed from the r"
  },
  {
    "path": "ci/Dockerfile.test_5_2_ruby_2_6",
    "chars": 1215,
    "preview": "FROM ruby:2.6-alpine3.12\n\nRUN gem install bundler:2.1.4\n\nRUN apk update --no-cache && \\\n    apk add build-base postgresq"
  },
  {
    "path": "ci/Dockerfile.test_6_0_ruby_2_6",
    "chars": 1215,
    "preview": "FROM ruby:2.6-alpine3.12\n\nRUN gem install bundler:2.1.4\n\nRUN apk update --no-cache && \\\n    apk add build-base postgresq"
  },
  {
    "path": "ci/Dockerfile.test_6_1_ruby_2_7",
    "chars": 1215,
    "preview": "FROM ruby:2.7-alpine3.12\n\nRUN gem install bundler:2.1.4\n\nRUN apk update --no-cache && \\\n    apk add build-base postgresq"
  },
  {
    "path": "ci/Dockerfile.test_6_1_ruby_3_0",
    "chars": 1215,
    "preview": "FROM ruby:3.0-alpine3.12\n\nRUN gem install bundler:2.1.4\n\nRUN apk update --no-cache && \\\n    apk add build-base postgresq"
  },
  {
    "path": "ci/Dockerfile.test_7_0_ruby_3_0",
    "chars": 1215,
    "preview": "FROM ruby:3.0-alpine3.12\n\nRUN gem install bundler:2.1.4\n\nRUN apk update --no-cache && \\\n    apk add build-base postgresq"
  },
  {
    "path": "ci/Gemfile.5.2",
    "chars": 1027,
    "preview": "source 'https://rubygems.org'\ngit_source(:github) { |repo| \"https://github.com/#{repo}.git\" }\n\n# Declare your gem's depe"
  },
  {
    "path": "ci/Gemfile.6.0",
    "chars": 1027,
    "preview": "source 'https://rubygems.org'\ngit_source(:github) { |repo| \"https://github.com/#{repo}.git\" }\n\n# Declare your gem's depe"
  },
  {
    "path": "ci/Gemfile.6.1",
    "chars": 1027,
    "preview": "source 'https://rubygems.org'\ngit_source(:github) { |repo| \"https://github.com/#{repo}.git\" }\n\n# Declare your gem's depe"
  },
  {
    "path": "ci/Gemfile.7.0",
    "chars": 1027,
    "preview": "source 'https://rubygems.org'\ngit_source(:github) { |repo| \"https://github.com/#{repo}.git\" }\n\n# Declare your gem's depe"
  },
  {
    "path": "ci/artifacts/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ci/docker-compose.ci.yml",
    "chars": 2896,
    "preview": "version: '3'\nservices:\n\n  test_5_2_ruby_2_6:\n    build:\n      context: ../\n      dockerfile: ./ci/Dockerfile.test_5_2_ru"
  },
  {
    "path": "docker-compose.yml",
    "chars": 1518,
    "preview": "version: '3'\nservices:\n\n  dummy:\n    build:\n      context: .\n      dockerfile: ./Dockerfile.dev\n    ports:\n      - \"3000"
  },
  {
    "path": "docs/README.md",
    "chars": 11367,
    "preview": "---\ndescription: >-\n  Matestack Ui Core - Boost your productivity & easily create component based\n  web UIs in pure Ruby"
  },
  {
    "path": "docs/SUMMARY.md",
    "chars": 1049,
    "preview": "# Table of contents\n\n* [Welcome](README.md)\n* [Migrating from 2.x to 3.0](migrate-from-2.x-to-3.0.md)\n\n## Getting starte"
  },
  {
    "path": "docs/components/api.md",
    "chars": 14847,
    "preview": "# API\n\n## Response\n\nUse the `response` method to define the UI of the component by using Matestack's HTML rendering or c"
  },
  {
    "path": "docs/components/registry.md",
    "chars": 1504,
    "preview": "# Registry\n\nBy default, components can be called directly like `Components::Card.call(title: \"foo\", body: \"bar\")` which "
  },
  {
    "path": "docs/components/usage-in-isolation.md",
    "chars": 22,
    "preview": "# Usage in Isolation\n\n"
  },
  {
    "path": "docs/components/usage-on-matestack-layouts.md",
    "chars": 30,
    "preview": "# Usage on Matestack Layouts\n\n"
  },
  {
    "path": "docs/components/usage-on-matestack-pages.md",
    "chars": 28,
    "preview": "# Usage on Matestack Pages\n\n"
  },
  {
    "path": "docs/components/usage-on-rails-views.md",
    "chars": 1034,
    "preview": "# Components on Rails views\n\nIf you already have plenty of Rails views \\(ERB, Haml or Slim\\) and want to start creating "
  },
  {
    "path": "docs/getting-started/hello-world.md",
    "chars": 20,
    "preview": "# Hello World\n\nWIP!\n"
  },
  {
    "path": "docs/getting-started/installation-update.md",
    "chars": 1175,
    "preview": "# Installation & Update\n\n## Installation\n\nAdd 'matestack-ui-core' to your Gemfile\n\n```ruby\ngem 'matestack-ui-core'\n```\n\n"
  },
  {
    "path": "docs/html-rendering/html-rendering.md",
    "chars": 4656,
    "preview": "# Basic Rendering Mechanism\n\nMatestack’s rendering mechanism takes care of converting Ruby into HTML:\n\n```ruby\ndiv class"
  },
  {
    "path": "docs/html-rendering/integrating-action-view-helpers.md",
    "chars": 2122,
    "preview": "# Integrating Action View Helpers\n\nUsing Rails view helpers ([https://api.rubyonrails.org/classes/ActionView/Helpers.htm"
  },
  {
    "path": "docs/html-rendering/reusing-views-or-partials.md",
    "chars": 1880,
    "preview": "# Integrating Rails Views or Partials\n\nMatestack `rails_render` component offers the possibility to render a view or par"
  },
  {
    "path": "docs/layouts/api.md",
    "chars": 3105,
    "preview": "# API\n\nA layout class defines a layout within its `response` method and is suppose to yield the content of a page.\n\n## R"
  },
  {
    "path": "docs/layouts/rails-controller-integration.md",
    "chars": 11069,
    "preview": "# Rails Controller Integration\n\nJust like a Rails layout would yield a Rails view, a Matestack layout yields a Matestack"
  },
  {
    "path": "docs/migrate-from-2.x-to-3.0.md",
    "chars": 3120,
    "preview": "# Migrating from 2.x to 3.0\n\n## Core/VueJs repo and gem split\n\n* `matestack-ui-core` previously contained logic for\n  * "
  },
  {
    "path": "docs/pages/api.md",
    "chars": 3268,
    "preview": "# Page API\n\n## Response\n\nUse the `response` method to define the UI of the page by using Matestack's HTML rendering or c"
  },
  {
    "path": "docs/pages/rails-controller-integration.md",
    "chars": 1060,
    "preview": "# Rails Controller Integration\n\nPages are used as Rails view substitutes and therefore called in a Rails controller acti"
  },
  {
    "path": "entrypoint.sh",
    "chars": 261,
    "preview": "#!/bin/bash\nset -e\n\nif [[ ! -e /app/Gemfile.lock ]]; then\n    bundle install\nfi\n\n# Remove a potentially pre-existing ser"
  },
  {
    "path": "lib/matestack/ui/component.rb",
    "chars": 57,
    "preview": "Matestack::Ui::Component = Matestack::Ui::Core::Component"
  },
  {
    "path": "lib/matestack/ui/core/base.rb",
    "chars": 4588,
    "preview": "require_relative 'tag_helper'\n\nmodule Matestack\n  module Ui\n    module Core\n      class Base\n        include ActionView:"
  },
  {
    "path": "lib/matestack/ui/core/component.rb",
    "chars": 101,
    "preview": "module Matestack\n  module Ui\n    module Core\n      class Component < Base\n      end\n    end\n  end\nend"
  },
  {
    "path": "lib/matestack/ui/core/context.rb",
    "chars": 344,
    "preview": "module Matestack\n  module Ui\n    module Core\n      class Context < ActiveSupport::CurrentAttributes\n\n        attribute :"
  },
  {
    "path": "lib/matestack/ui/core/helper.rb",
    "chars": 3587,
    "preview": "module Matestack\n  module Ui\n    module Core\n      module Helper\n\n        def self.included(base)\n          base.extend "
  },
  {
    "path": "lib/matestack/ui/core/layout.rb",
    "chars": 532,
    "preview": "module Matestack\n  module Ui\n    module Core\n      class Layout < Base\n\n        def initialize(options = {})\n          @"
  },
  {
    "path": "lib/matestack/ui/core/page.rb",
    "chars": 183,
    "preview": "module Matestack\n  module Ui\n    module Core\n      class Page < Base\n\n        def initialize(options = {})\n          sup"
  },
  {
    "path": "lib/matestack/ui/core/properties.rb",
    "chars": 3579,
    "preview": "module Matestack\n  module Ui\n    module Core\n      module Properties\n\n        def self.included(base)\n          base.ext"
  },
  {
    "path": "lib/matestack/ui/core/slots.rb",
    "chars": 197,
    "preview": "module Matestack\n  module Ui\n    module Core\n      module Slots\n\n        attr_accessor :slots\n\n        def slot(key, *ar"
  },
  {
    "path": "lib/matestack/ui/core/tag_helper.rb",
    "chars": 3877,
    "preview": "require_relative 'slots'\nmodule Matestack\n  module Ui\n    module Core\n      module TagHelper\n        extend Gem::Depreca"
  },
  {
    "path": "lib/matestack/ui/core/version.rb",
    "chars": 87,
    "preview": "module Matestack\n  module Ui\n    module Core\n      VERSION = '3.0.1'\n    end\n  end\nend\n"
  },
  {
    "path": "lib/matestack/ui/core.rb",
    "chars": 490,
    "preview": "base_path = 'matestack/ui/core'\nrequire \"#{base_path}/version\"\n\nmodule Matestack\n  module Ui\n    module Core\n\n    end\n  "
  },
  {
    "path": "lib/matestack/ui/layout.rb",
    "chars": 52,
    "preview": "Matestack::Ui::Layout = Matestack::Ui::Core::Layout\n"
  },
  {
    "path": "lib/matestack/ui/page.rb",
    "chars": 48,
    "preview": "Matestack::Ui::Page = Matestack::Ui::Core::Page\n"
  },
  {
    "path": "matestack-ui-core.gemspec",
    "chars": 1004,
    "preview": "$:.push File.expand_path(\"lib\", __dir__)\n\n# Maintain your gem's version:\nrequire \"matestack/ui/core/version\"\n\n# Describe"
  },
  {
    "path": "results.txt",
    "chars": 447,
    "preview": "Capybara starting Puma...\n* Version 4.3.5 , codename: Mysterious Traveller\n* Min threads: 0, max threads: 4\n* Listening "
  },
  {
    "path": "spec/core_spec_helper.rb",
    "chars": 6088,
    "preview": "# This file was generated by the `rails generate rspec:install` command. Conventionally, all\n# specs live under a `spec`"
  },
  {
    "path": "spec/dummy/Rakefile",
    "chars": 227,
    "preview": "# Add your own tasks in files placed in lib/tasks ending in .rake,\n# for example lib/tasks/capistrano.rake, and they wil"
  },
  {
    "path": "spec/dummy/app/assets/config/manifest.js",
    "chars": 48,
    "preview": "//= link_tree ../images\n//= link_tree ../videos\n"
  },
  {
    "path": "spec/dummy/app/assets/images/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/channels/application_cable/channel.rb",
    "chars": 79,
    "preview": "module ApplicationCable\n  class Channel < ActionCable::Channel::Base\n  end\nend\n"
  },
  {
    "path": "spec/dummy/app/channels/application_cable/connection.rb",
    "chars": 85,
    "preview": "module ApplicationCable\n  class Connection < ActionCable::Connection::Base\n  end\nend\n"
  },
  {
    "path": "spec/dummy/app/controllers/application_controller.rb",
    "chars": 57,
    "preview": "class ApplicationController < ActionController::Base\nend\n"
  },
  {
    "path": "spec/dummy/app/controllers/concerns/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/controllers/demo_core_controller.rb",
    "chars": 281,
    "preview": "class DemoCoreController < ActionController::Base\n  include Matestack::Ui::Core::Helper\n\n  layout \"application_core\"\n\n  "
  },
  {
    "path": "spec/dummy/app/controllers/legacy_views/0_USED_IN_SPECS_DONT_TOUCH",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/controllers/legacy_views/pages_controller.rb",
    "chars": 186,
    "preview": "# used in specs\n\nclass LegacyViews::PagesController < ApplicationController\n  include Matestack::Ui::Core::Helper\n\n  lay"
  },
  {
    "path": "spec/dummy/app/helpers/application_helper.rb",
    "chars": 108,
    "preview": "module ApplicationHelper\n  include Matestack::Ui::Core::Helper\n  include Matestack::Ui::Core::TagHelper\nend\n"
  },
  {
    "path": "spec/dummy/app/javascript/channels/consumer.js",
    "chars": 266,
    "preview": "// Action Cable provides the framework to deal with WebSockets in Rails.\n// You can generate new channels where WebSocke"
  },
  {
    "path": "spec/dummy/app/javascript/channels/index.js",
    "chars": 212,
    "preview": "// Load all the channels within this directory and all subdirectories.\n// Channel files must be named *_channel.js.\n\ncon"
  },
  {
    "path": "spec/dummy/app/javascript/packs/application.js",
    "chars": 523,
    "preview": "/* eslint no-console:0 */\n// This file is automatically compiled by Webpack, along with any other files\n// present in th"
  },
  {
    "path": "spec/dummy/app/javascript/packs/application_core.js",
    "chars": 529,
    "preview": "/* eslint no-console:0 */\n// This file is automatically compiled by Webpack, along with any other files\n// present in th"
  },
  {
    "path": "spec/dummy/app/jobs/application_job.rb",
    "chars": 43,
    "preview": "class ApplicationJob < ActiveJob::Base\nend\n"
  },
  {
    "path": "spec/dummy/app/mailers/application_mailer.rb",
    "chars": 102,
    "preview": "class ApplicationMailer < ActionMailer::Base\n  default from: 'from@example.com'\n  layout 'mailer'\nend\n"
  },
  {
    "path": "spec/dummy/app/matestack/components/legacy_views/pages/0_USED_IN_SPECS_DONT_TOUCH",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/matestack/components/legacy_views/pages/viewcontext.rb",
    "chars": 533,
    "preview": "# used in specs\n\nclass Components::LegacyViews::Pages::Viewcontext < Matestack::Ui::Component\n\n  def response\n    div id"
  },
  {
    "path": "spec/dummy/app/matestack/demo/core/components/static_component.rb",
    "chars": 192,
    "preview": "class Demo::Core::Components::StaticComponent < Matestack::Ui::Component\n\n  required :foo\n\n  def response\n    plain \"A s"
  },
  {
    "path": "spec/dummy/app/matestack/demo/core/layout.rb",
    "chars": 415,
    "preview": "class Demo::Core::Layout < Matestack::Ui::Layout\n\n  def response\n    h1 \"Demo Core App\"\n\n    paragraph do\n      plain \"p"
  },
  {
    "path": "spec/dummy/app/matestack/demo/core/pages/first_page.rb",
    "chars": 318,
    "preview": "class Demo::Core::Pages::FirstPage < Matestack::Ui::Page\n\n  def response\n    h2 \"First page\"\n\n    paragraph do\n      pla"
  },
  {
    "path": "spec/dummy/app/matestack/demo/core/pages/second_page.rb",
    "chars": 321,
    "preview": "class Demo::Core::Pages::SecondPage < Matestack::Ui::Page\n\n  def response\n    h2 \"Second Page\"\n\n    paragraph do\n      p"
  },
  {
    "path": "spec/dummy/app/models/0_USED_IN_SPECS_DONT_TOUCH",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/models/application_record.rb",
    "chars": 78,
    "preview": "class ApplicationRecord < ActiveRecord::Base\n  self.abstract_class = true\nend\n"
  },
  {
    "path": "spec/dummy/app/models/concerns/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/models/dummy_child_model.rb",
    "chars": 171,
    "preview": "# used in specs\n\nclass DummyChildModel < ApplicationRecord\n\n  validates :title, presence: true, uniqueness: true\n\n  has_"
  },
  {
    "path": "spec/dummy/app/models/dummy_model.rb",
    "chars": 373,
    "preview": "# used in specs\n\nclass DummyModel < ApplicationRecord\n\n  validates :title, presence: true, uniqueness: true\n\n  has_one_a"
  },
  {
    "path": "spec/dummy/app/models/test_model.rb",
    "chars": 84,
    "preview": "# used in specs\n\nclass TestModel < ApplicationRecord\n\n  has_one_attached :file\n\nend\n"
  },
  {
    "path": "spec/dummy/app/views/_some_partial.html.erb",
    "chars": 47,
    "preview": "<h1>This is some partial</h1>\n<p><%= foo %></p>"
  },
  {
    "path": "spec/dummy/app/views/demo/0_USED_IN_SPECS_DONT_TOUCH",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/views/demo/_header.html.erb",
    "chars": 66,
    "preview": "<header>\n  <h1>Rails Partial</h1>\n  <p><%= @title %></p>\n</header>"
  },
  {
    "path": "spec/dummy/app/views/demo/header.html.erb",
    "chars": 63,
    "preview": "<header>\n  <h1>Rails View</h1>\n  <p><%= @title %></p>\n</header>"
  },
  {
    "path": "spec/dummy/app/views/layouts/0_USED_IN_SPECS_DONT_TOUCH",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/views/layouts/application.html.erb",
    "chars": 247,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Dummy</title>\n    <%= csrf_meta_tags %>\n    <%= csp_meta_tag %>\n\n    <%= java"
  },
  {
    "path": "spec/dummy/app/views/layouts/application_core.html.erb",
    "chars": 260,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Core Demo</title>\n    <%= csrf_meta_tags %>\n    <%= csp_meta_tag %>\n\n    <%= "
  },
  {
    "path": "spec/dummy/app/views/layouts/legacy_views.erb",
    "chars": 356,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Dummy</title>\n    <%= csrf_meta_tags %>\n    <%= csp_meta_tag %>\n\n    <%= java"
  },
  {
    "path": "spec/dummy/app/views/legacy_views/pages/0_USED_IN_SPECS_DONT_TOUCH",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/views/legacy_views/pages/viewcontext_custom_component.html.erb",
    "chars": 92,
    "preview": "<h1>Viewcontext Custom Component</h1>\n<%= Components::LegacyViews::Pages::Viewcontext.() %>\n"
  },
  {
    "path": "spec/dummy/app/views/rails/0_USED_IN_SPECS_DONT_TOUCH",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/app/views/rails/_some_partial.html.erb",
    "chars": 68,
    "preview": "<h2><%= name %></h2>\n<% 5.times do |i| %>\n  <p><%= i %><p>\n<% end %>"
  },
  {
    "path": "spec/dummy/app/views/rails/index.html.erb",
    "chars": 322,
    "preview": "<h1>Test</h1>\n<% 100.times do %>\n  <div>\n    <div>\n      <div>\n        <div>\n          <div>\n            <div>\n         "
  },
  {
    "path": "spec/dummy/app/views/some_view.html.erb",
    "chars": 36,
    "preview": "<h1>A view :D</h1>\n<p><%= foo %></p>"
  },
  {
    "path": "spec/dummy/bin/bundle",
    "chars": 134,
    "preview": "#!/usr/bin/env ruby\nENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __dir__)\nload Gem.bin_path('bundle"
  },
  {
    "path": "spec/dummy/bin/rails",
    "chars": 141,
    "preview": "#!/usr/bin/env ruby\nAPP_PATH = File.expand_path('../config/application', __dir__)\nrequire_relative '../config/boot'\nrequ"
  },
  {
    "path": "spec/dummy/bin/rake",
    "chars": 90,
    "preview": "#!/usr/bin/env ruby\nrequire_relative '../config/boot'\nrequire 'rake'\nRake.application.run\n"
  },
  {
    "path": "spec/dummy/bin/setup",
    "chars": 957,
    "preview": "#!/usr/bin/env ruby\nrequire 'fileutils'\ninclude FileUtils\n\n# path to your application root.\nAPP_ROOT = File.expand_path("
  },
  {
    "path": "spec/dummy/bin/update",
    "chars": 819,
    "preview": "#!/usr/bin/env ruby\nrequire 'fileutils'\ninclude FileUtils\n\n# path to your application root.\nAPP_ROOT = File.expand_path("
  },
  {
    "path": "spec/dummy/bin/webpack",
    "chars": 420,
    "preview": "#!/usr/bin/env ruby\n\nENV[\"RAILS_ENV\"] ||= ENV[\"RACK_ENV\"] || \"development\"\nENV[\"NODE_ENV\"]  ||= \"development\"\n\nrequire \""
  },
  {
    "path": "spec/dummy/bin/webpack-dev-server",
    "chars": 425,
    "preview": "#!/usr/bin/env ruby\n\nENV[\"RAILS_ENV\"] ||= ENV[\"RACK_ENV\"] || \"development\"\nENV[\"NODE_ENV\"]  ||= \"development\"\n\nrequire \""
  },
  {
    "path": "spec/dummy/bin/yarn",
    "chars": 303,
    "preview": "#!/usr/bin/env ruby\nAPP_ROOT = File.expand_path('..', __dir__)\nDir.chdir(APP_ROOT) do\n  begin\n    exec \"yarnpkg\", *ARGV\n"
  },
  {
    "path": "spec/dummy/config/application.5.2_rb",
    "chars": 647,
    "preview": "require_relative 'boot'\n\nrequire 'rails/all'\n\nBundler.require(*Rails.groups)\nrequire \"matestack/ui/core\"\n\nmodule Dummy\n "
  },
  {
    "path": "spec/dummy/config/application.6.0_rb",
    "chars": 647,
    "preview": "require_relative 'boot'\n\nrequire 'rails/all'\n\nBundler.require(*Rails.groups)\nrequire \"matestack/ui/core\"\n\nmodule Dummy\n "
  },
  {
    "path": "spec/dummy/config/application.6.1_rb",
    "chars": 647,
    "preview": "require_relative 'boot'\n\nrequire 'rails/all'\n\nBundler.require(*Rails.groups)\nrequire \"matestack/ui/core\"\n\nmodule Dummy\n "
  },
  {
    "path": "spec/dummy/config/application.7.0_rb",
    "chars": 647,
    "preview": "require_relative 'boot'\n\nrequire 'rails/all'\n\nBundler.require(*Rails.groups)\nrequire \"matestack/ui/core\"\n\nmodule Dummy\n "
  },
  {
    "path": "spec/dummy/config/application.rb",
    "chars": 647,
    "preview": "require_relative 'boot'\n\nrequire 'rails/all'\n\nBundler.require(*Rails.groups)\nrequire \"matestack/ui/core\"\n\nmodule Dummy\n "
  },
  {
    "path": "spec/dummy/config/boot.rb",
    "chars": 233,
    "preview": "# Set up gems listed in the Gemfile.\nENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __dir__)\n\nrequire 'b"
  },
  {
    "path": "spec/dummy/config/cable.yml",
    "chars": 187,
    "preview": "development:\n  adapter: async\n\ntest:\n  adapter: async\n\nproduction:\n  adapter: redis\n  url: <%= ENV.fetch(\"REDIS_URL\") { "
  },
  {
    "path": "spec/dummy/config/database.yml",
    "chars": 482,
    "preview": "default: &default\n  adapter: postgresql\n  encoding: unicode\n  host: postgres\n  username: <%= ENV.fetch(\"POSTGRES_USER\") "
  },
  {
    "path": "spec/dummy/config/environment.rb",
    "chars": 128,
    "preview": "# Load the Rails application.\nrequire_relative 'application'\n\n# Initialize the Rails application.\nRails.application.init"
  },
  {
    "path": "spec/dummy/config/environments/development.rb",
    "chars": 2326,
    "preview": "Rails.application.configure do\n  # Verifies that versions and hashed value of the package contents in the project's pack"
  },
  {
    "path": "spec/dummy/config/environments/production.rb",
    "chars": 4083,
    "preview": "Rails.application.configure do\n  # Verifies that versions and hashed value of the package contents in the project's pack"
  },
  {
    "path": "spec/dummy/config/environments/test.rb",
    "chars": 1873,
    "preview": "Rails.application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  "
  },
  {
    "path": "spec/dummy/config/initializers/application_controller_renderer.rb",
    "chars": 216,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# ActiveSupport::Reloader.to_prepare do\n#   ApplicationCont"
  },
  {
    "path": "spec/dummy/config/initializers/assets.rb",
    "chars": 762,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Version of your assets, change this if you want to expire"
  },
  {
    "path": "spec/dummy/config/initializers/backtrace_silencers.rb",
    "chars": 404,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# You can add backtrace silencers for libraries that you're"
  },
  {
    "path": "spec/dummy/config/initializers/content_security_policy.rb",
    "chars": 1092,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Define an application-wide content security policy\n# For "
  },
  {
    "path": "spec/dummy/config/initializers/cookies_serializer.rb",
    "chars": 244,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Specify a serializer for the signed and encrypted cookie "
  },
  {
    "path": "spec/dummy/config/initializers/filter_parameter_logging.rb",
    "chars": 194,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Configure sensitive parameters which will be filtered fro"
  },
  {
    "path": "spec/dummy/config/initializers/inflections.rb",
    "chars": 647,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Add new inflection rules using the following format. Infl"
  },
  {
    "path": "spec/dummy/config/initializers/matestack.rb",
    "chars": 90,
    "preview": "# Matestack::Ui::Core::Component::Registry.register_component(:my_card, Components::Card)\n"
  },
  {
    "path": "spec/dummy/config/initializers/mime_types.rb",
    "chars": 156,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# Add new mime types for use in respond_to blocks:\n# Mime::"
  },
  {
    "path": "spec/dummy/config/initializers/nested_attrs_error_index_patch.rb",
    "chars": 681,
    "preview": "# Support propper mapping of errors on existing nested models in nested forms\n# https://github.com/rails/rails/issues/24"
  },
  {
    "path": "spec/dummy/config/initializers/wrap_parameters.rb",
    "chars": 485,
    "preview": "# Be sure to restart your server when you modify this file.\n\n# This file contains settings for ActionController::ParamsW"
  },
  {
    "path": "spec/dummy/config/locales/en.yml",
    "chars": 848,
    "preview": "# Files in the config/locales directory are used for internationalization\n# and are automatically loaded by Rails. If yo"
  },
  {
    "path": "spec/dummy/config/puma.rb",
    "chars": 1397,
    "preview": "# Puma can serve each request in a thread from an internal thread pool.\n# The `threads` method setting takes two numbers"
  },
  {
    "path": "spec/dummy/config/routes.rb",
    "chars": 256,
    "preview": "Rails.application.routes.draw do\n\n  root to: 'demo_core#first'\n\n  scope :demo do\n    scope :core do\n      get :first, to"
  },
  {
    "path": "spec/dummy/config/spring.rb",
    "chars": 111,
    "preview": "%w[\n  .ruby-version\n  .rbenv-vars\n  tmp/restart.txt\n  tmp/caching-dev.txt\n].each { |path| Spring.watch(path) }\n"
  },
  {
    "path": "spec/dummy/config/storage.yml",
    "chars": 1093,
    "preview": "test:\n  service: Disk\n  root: <%= Rails.root.join(\"tmp/storage\") %>\n\nlocal:\n  service: Disk\n  root: <%= Rails.root.join("
  },
  {
    "path": "spec/dummy/config/webpack/development.js",
    "chars": 155,
    "preview": "process.env.NODE_ENV = process.env.NODE_ENV || 'development'\n\nconst environment = require('./environment')\n\nmodule.expor"
  },
  {
    "path": "spec/dummy/config/webpack/environment.js",
    "chars": 82,
    "preview": "const { environment } = require('@rails/webpacker')\n\nmodule.exports = environment\n"
  },
  {
    "path": "spec/dummy/config/webpack/production.js",
    "chars": 154,
    "preview": "process.env.NODE_ENV = process.env.NODE_ENV || 'production'\n\nconst environment = require('./environment')\n\nmodule.export"
  },
  {
    "path": "spec/dummy/config/webpack/test.js",
    "chars": 155,
    "preview": "process.env.NODE_ENV = process.env.NODE_ENV || 'development'\n\nconst environment = require('./environment')\n\nmodule.expor"
  },
  {
    "path": "spec/dummy/config/webpacker.yml",
    "chars": 1426,
    "preview": "# Note: You must restart bin/webpack-dev-server for changes to take effect\n\ndefault: &default\n  source_path: app/javascr"
  },
  {
    "path": "spec/dummy/config.ru",
    "chars": 130,
    "preview": "# This file is used by Rack-based servers to start the application.\n\nrequire_relative 'config/environment'\n\nrun Rails.ap"
  },
  {
    "path": "spec/dummy/db/migrate/20190419174203_create_test_models.rb",
    "chars": 262,
    "preview": "class CreateTestModels < ActiveRecord::Migration[5.2]\n  def change\n    create_table :test_models do |t|\n      t.string :"
  },
  {
    "path": "spec/dummy/db/migrate/20190427134012_create_dummy_models.rb",
    "chars": 264,
    "preview": "class CreateDummyModels < ActiveRecord::Migration[5.2]\n  def change\n    create_table :dummy_models do |t|\n      t.string"
  },
  {
    "path": "spec/dummy/db/migrate/20190908153924_create_dummy_child_models.rb",
    "chars": 346,
    "preview": "class CreateDummyChildModels < ActiveRecord::Migration[5.2]\n  def change\n    create_table :dummy_child_models do |t|\n   "
  },
  {
    "path": "spec/dummy/db/migrate/20200427170812_create_active_storage_tables.active_storage.rb",
    "chars": 968,
    "preview": "# This migration comes from active_storage (originally 20170806125915)\nclass CreateActiveStorageTables < ActiveRecord::M"
  },
  {
    "path": "spec/dummy/db/migrate/20201222161321_add_boolean_value_to_test_models.rb",
    "chars": 147,
    "preview": "class AddBooleanValueToTestModels < ActiveRecord::Migration[5.2]\n  def change\n    add_column :test_models, :some_boolean"
  },
  {
    "path": "spec/dummy/db/migrate/20210204135043_add_service_name_to_active_storage_blobs.active_storage.rb",
    "chars": 826,
    "preview": "# This migration comes from active_storage (originally 20190112182829)\nif Rails::VERSION::MAJOR >= 6 && Rails::VERSION::"
  },
  {
    "path": "spec/dummy/db/migrate/20210204135044_create_active_storage_variant_records.active_storage.rb",
    "chars": 702,
    "preview": "# This migration comes from active_storage (originally 20191206030411)\nif Rails::VERSION::MAJOR >= 6 && Rails::VERSION::"
  },
  {
    "path": "spec/dummy/db/schema.rb",
    "chars": 3214,
    "preview": "# This file is auto-generated from the current state of the database. Instead\n# of editing this file, please use the mig"
  },
  {
    "path": "spec/dummy/lib/assets/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/log/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "spec/dummy/package.json",
    "chars": 359,
    "preview": "{\n  \"name\": \"dummy\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@babel/preset-env\": \"^7.16.7\",\n    \"@hotwired/turbo-rai"
  },
  {
    "path": "spec/dummy/postcss.config.js",
    "chars": 224,
    "preview": "module.exports = {\n  plugins: [\n    require('postcss-import'),\n    require('postcss-flexbugs-fixes'),\n    require('postc"
  },
  {
    "path": "spec/dummy/public/404.html",
    "chars": 1722,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>The page you were looking for doesn't exist (404)</title>\n  <meta name=\"viewport\""
  },
  {
    "path": "spec/dummy/public/422.html",
    "chars": 1705,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>The change you wanted was rejected (422)</title>\n  <meta name=\"viewport\" content="
  },
  {
    "path": "spec/dummy/public/500.html",
    "chars": 1635,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <title>We're sorry, but something went wrong (500)</title>\n  <meta name=\"viewport\" conte"
  },
  {
    "path": "spec/rails_core_spec_helper.rb",
    "chars": 2962,
    "preview": "# This file is copied to spec/ when you run 'rails generate rspec:install'\nrequire 'core_spec_helper'\nENV['RAILS_ENV'] |"
  },
  {
    "path": "spec/spec_helper.rb",
    "chars": 49,
    "preview": "# file need to exist, otherwise specs will fail!\n"
  },
  {
    "path": "spec/test/core/base/component/argument_spec.rb",
    "chars": 1279,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/conditional_rendering_spec.rb",
    "chars": 2931,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/core_namespaces_spec.rb",
    "chars": 3673,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/custom_namespaces_spec.rb",
    "chars": 3946,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/options_spec.rb",
    "chars": 2370,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/partials_spec.rb",
    "chars": 2177,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/prepare_spec.rb",
    "chars": 1352,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/properties_spec.rb",
    "chars": 8574,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe 'Properties Mechanism', type: :feature, js: true do\n\n  "
  },
  {
    "path": "spec/test/core/base/component/slots_spec.rb",
    "chars": 4105,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/static_rendering_spec.rb",
    "chars": 1333,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/url_params_access_spec.rb",
    "chars": 1477,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :al"
  },
  {
    "path": "spec/test/core/base/component/view_context_access_spec.rb",
    "chars": 1854,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :all"
  },
  {
    "path": "spec/test/core/base/component/yield_spec.rb",
    "chars": 1298,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe \"Component\", type: :feature, js: true do\n\n  before :all"
  },
  {
    "path": "spec/test/core/base/layout/layout_resolving_spec.rb",
    "chars": 6107,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe \"Layout Resolving\", type: :feature, js: true do\n\n  befo"
  },
  {
    "path": "spec/test/core/base/layout/layout_spec.rb",
    "chars": 3210,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe \"App\", type: :feature, js: true do\n\n  before :all do\n  "
  },
  {
    "path": "spec/test/core/base/page/controller_instance_access_spec.rb",
    "chars": 949,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Page\", type: :feature, js: true do\n\n  before :all do\n"
  },
  {
    "path": "spec/test/core/base/page/orchestrates_components_spec.rb",
    "chars": 940,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Page\", type: :feature, js: true do\n\n  before :all do\n"
  },
  {
    "path": "spec/test/core/base/page/partials_spec.rb",
    "chars": 3046,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Page\", type: :feature, js: true do\n\n  before :all do\n"
  },
  {
    "path": "spec/test/core/base/page/prepare_spec.rb",
    "chars": 1076,
    "preview": "# require 'rails_core_spec_helper' \n# include CoreSpecUtils\n\n# describe \"Page\", type: :feature, js: true do\n\n#   before "
  },
  {
    "path": "spec/test/core/base/page/slots_spec.rb",
    "chars": 1679,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe \"Page\", type: :feature, js: true do\n\n  before :all do\n "
  },
  {
    "path": "spec/test/core/base/page/url_params_access_spec.rb",
    "chars": 850,
    "preview": "require 'rails_core_spec_helper' \ninclude CoreSpecUtils\n\ndescribe \"Page\", type: :feature, js: true do\n\n  before :all do\n"
  },
  {
    "path": "spec/test/core/base/page/view_context_access_spec.rb",
    "chars": 1379,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe \"Page\", type: :feature, js: true do\n\n  before :all do\n "
  },
  {
    "path": "spec/test/core/custom_component_spec.rb",
    "chars": 1331,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe 'Creating custom components', type: :feature, js: true "
  },
  {
    "path": "spec/test/core/html_rendering/action_view_integration.rb",
    "chars": 3896,
    "preview": "require 'rails_core_spec_helper'\n\ndescribe 'Action View Integration', type: :feature do\n  include CoreSpecUtils\n\n  it \"u"
  },
  {
    "path": "spec/test/core/html_rendering/default_tags_spec.rb",
    "chars": 18523,
    "preview": "require 'rails_core_spec_helper'\n\ndescribe 'Default Tags Rendering', type: :feature do\n  include CoreSpecUtils\n\n  descri"
  },
  {
    "path": "spec/test/core/html_rendering/link_spec.rb",
    "chars": 6465,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe 'a Component', type: :feature, js: true do\n\n  it 'Examp"
  },
  {
    "path": "spec/test/core/rails_render_spec.rb",
    "chars": 1061,
    "preview": "require 'rails_core_spec_helper'\ninclude CoreSpecUtils\n\ndescribe 'Rails View Component', type: :feature, js: true do\n\n  "
  },
  {
    "path": "spec/test/core/support/capybara.rb",
    "chars": 672,
    "preview": "require 'capybara/rspec'\nrequire 'capybara/rails'\nrequire \"selenium/webdriver\"\n\nrequire \"matestack/ui/core\"\n\nCapybara.se"
  },
  {
    "path": "spec/test/core/support/core_spec_utils.rb",
    "chars": 1460,
    "preview": "module CoreSpecUtils\n\n  def stripped(html_string)\n    html_string\n      .gsub(/>\\s+</, \"><\")\n      .gsub(\"\\n\", \"\")\n     "
  },
  {
    "path": "spec/test/core/support/example_controller.rb",
    "chars": 259,
    "preview": "require_relative 'layout'\n\nclass ExampleController < ApplicationController\n  include Matestack::Ui::Core::Helper\n\n  layo"
  },
  {
    "path": "spec/test/core/support/layout.rb",
    "chars": 139,
    "preview": "# used in specs only, look for the demo app here: ./demo/app.rb\n\nclass Layout < Matestack::Ui::Layout\n\n  def response\n  "
  }
]

// ... and 6 more files (download for full content)

About this extraction

This page contains the full source code of the basemate/matestack-ui-core GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 206 files (302.9 KB), approximately 85.2k tokens, and a symbol index with 527 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!