shimmer 0.0.4 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32060fa00134259da2eb2723aa0ba4e14a95bbd85f9b214797e76778f2c1500b
4
- data.tar.gz: 18c942b4f19f582e7ae45a89aad5b03d6192201ea0849e14bf9e8f567dccc069
3
+ metadata.gz: 875686b1fc81225c69cbbaedbf38327709de9233c784ee72c32ca2eff2c8fe5d
4
+ data.tar.gz: 324f34718ecca0e2b0d1a88c7f46c59532686b4ad149cdefa3a9098ed997a33f
5
5
  SHA512:
6
- metadata.gz: 752d5f326fcf637ec3fa4d37e3cd6c5a9df88d7c408697ad7c3153b65f75ef1c8fc7f6cbeb8e29d44efe25b314a209a3bf615bd30146f704beb05cd1b156ca52
7
- data.tar.gz: f8465c8a123e351a84e970fcbb6629e79a0b2759095c6378f248255cb41fdacdbb0dbce46e8751438c0737669d22e2eb8dfe8a9afb3574adfc0d0e031976b716
6
+ metadata.gz: 5d640f8e34aef1dd6bbf18e792c6c34ecd3c10a11559f01dcda1877260ae7447d62a8207aee94951028a87000cc3288502ccc2a6ade8037150cefe0132972541
7
+ data.tar.gz: fcf2e88cccb9ee701051358858f6c9c9e8f9978bab1d723571cb0a58eb9d937dde684c068827d6dec98ab2169a4dbf2a29cb9d26ce9476d5a2e6803f98c42cc3
data/README.md CHANGED
@@ -1,38 +1,196 @@
1
- # Shimmer
1
+ # Shimmer - Because Ruby could be more shiny!
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/shimmer`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Shimmer is a collection of Rails extensions that bring advanced UI features into your app and make your life easier as a developer.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ ## Features
6
+
7
+ ### Static File Serving
8
+
9
+ `ActiveStorage` is great, but serving of files, especially behind a CDN, can be complicated to get right. This can be fixed easily:
10
+
11
+ ```ruby
12
+ # use an image tag
13
+ image_tag user.avatar, width: 300
14
+ ```
15
+
16
+ This extension overrides `image_tag` and also supplies a matching `image_file_url` that automatically resizes your image and creates a static, cacheable url.
17
+
18
+ ### Modals
19
+
20
+ Modals are the designer's best friend, but developers usually hate them for their complexity. Fear no more: Shimmer has you covered.
21
+
22
+ ```slim
23
+ a href=modal_path(new_post_path) Create a new Post
24
+ ```
25
+
26
+ This will open a modal on click and then asynchronously request the modal content from the controller. Modals can also be controlled via JavaScript via the global `ui` variable:
27
+
28
+ ```js
29
+ ui.modal.open({ url: "/posts/new" });
30
+ ui.modal.close();
31
+ ```
32
+
33
+ ### Popovers
34
+
35
+ When modals are annoying to implement, popovers are even worse. Thankfully, Shimmer comes to the rescue:
36
+
37
+ ```slim
38
+ a href=popover_path(new_post_path, placement: :left)
39
+ ```
40
+
41
+ This will request `new_post_path` and display it left of the anchor thanks to PopperJS.
42
+
43
+ ### Remote Navigation
44
+
45
+ Remote navigation takes Hotwire to the next level with built-in navigation actions, integrated with modals and popovers.
46
+
47
+ ```ruby
48
+ def create
49
+ @post = current_user.posts.create! post_params
50
+ ui.navigate_to @post
51
+ end
52
+ ```
53
+
54
+ This will automatically close the current modal or popover and navigate via Turbo Drive to the post's url - no redirects necessary.
55
+
56
+ The `ui` helper comes with several built-in functions:
57
+
58
+ ```ruby
59
+ # run any kind of javascript upon request completion
60
+ ui.run_javascript("alert('hello world')")
61
+
62
+ # open or replace a modal's content (dependent on its ID)
63
+ ui.open_modal(new_post_path, size: :small)
64
+
65
+ # close an open modal
66
+ ui.close_modal
67
+
68
+ # same methods also available for popovers
69
+ ui.open_popover(new_post_path, selector: "#user-profile", placement: :left)
70
+ ui.close_popover
71
+
72
+ # navigate via Turbo Drive
73
+ ui.navigate_to(@post)
74
+
75
+ # manipulate the page's content
76
+ ui.append(@post, with: "comments/comment", comment: @comment)
77
+ ui.prepend("#user-profile", with: "users/extra")
78
+ ui.replace(@post)
79
+ ui.remove(@post)
80
+ ```
81
+
82
+ ### Sitemaps
83
+
84
+ Want to implement sitemaps, but the ephemeral filesystem of Heroku hates you? Here's a simple way to upload sitemaps:
85
+
86
+ - install the sitemap gem and configure the `sitemap.rb` as usual
87
+ - use the shimmer adapter to automatically upload your sitemap to your configured ActiveStorage adapter
88
+ - use the shimmer controller to display the sitemap in your app
89
+ - (optional) tell sidekiq scheduler to regularly update your sitemap
90
+
91
+ ```ruby
92
+ # sitemap.rb
93
+ SitemapGenerator::Sitemap.adapter = Shimmer::SitemapAdapter.new
94
+
95
+ # routes.rb
96
+ get "sitemaps/*path", to: "shimmer/sitemaps#show"
97
+
98
+ # sidekiq.yml
99
+ :schedule:
100
+ sitemap:
101
+ cron: '0 0 12 * * * Europe/Berlin' # every day at 16:00, Berlin time
102
+ class: Shimmer::SitemapJob
103
+ ```
104
+
105
+ ### Cloudflare Support
106
+
107
+ As you might have noticed, Cloudflare SSL will cause some issues with your Rails app if you're not using SSL strict mode (https://github.com/rails/rails/issues/22965). If you can't switch to strict mode, go for the standard flexible mode instead and add this middleware to your stack:
108
+
109
+ ```ruby
110
+ # application.rb
111
+ config.middleware.use Shimmer::CloudflareProxy
112
+ ```
113
+
114
+ ### Heroku Database Helpers
115
+
116
+ Can't reproduce an issue with your local test data and just want the production or staging data on your development machine? Here you go:
117
+
118
+ ```bash
119
+ rails db:pull
120
+ ```
121
+
122
+ This will drop your local database and pull in the database of your connected Heroku app (make sure you executed `heroku git:remote -a your_app` before to have the git remote). But what about assets you might ask? Easy - assets are pulled from S3 as well via the AWS CLI automatically (make sure your environment variables in Heroku are correctly named as `AWS_REGION`, `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`) and the database is updated to use your local filesystem instead.
123
+
124
+ If you don't want the asset support, you can also only pull the database or only the assets:
125
+
126
+ ```bash
127
+ rails db:pull_data
128
+ rails db:pull_assets
129
+ ```
130
+
131
+ ### Localizable Routes with Browser Locale Support
132
+
133
+ To localize a page via urls, this will help you tremendously.
134
+
135
+ ```ruby
136
+ # routes.rb
137
+ Rails.application.routes.draw do
138
+ scope "/(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
139
+ get "login", to: "sessions#new"
140
+ end
141
+ end
142
+ ```
143
+
144
+ From now on you can prefix your routes with a locale like `/de/login` or `/en/login` and `I18n.locale` will automatically be set. If there is no locale in the url (it's optional), this will automatically use the browser's locale.
145
+
146
+ You want to redirect from unlocalized paths? Add a before action to your controller:
147
+
148
+ ```ruby
149
+ before_action :check_locale
150
+ ```
151
+
152
+ Trying to figure out which key a certain translation on the page has? Append `?debug` to the url and `I18n.debug?` will be set - which leads to keys being printed on the page.
6
153
 
7
154
  ## Installation
8
155
 
9
156
  Add this line to your application's Gemfile:
10
157
 
11
158
  ```ruby
12
- gem 'shimmer'
159
+ gem "shimmer"
13
160
  ```
14
161
 
15
162
  And then execute:
16
163
 
17
- $ bundle install
164
+ ```bash
165
+ $ bundle install
166
+ ```
18
167
 
19
- Or install it yourself as:
168
+ Add some configuration to your project:
20
169
 
21
- $ gem install shimmer
170
+ ```ruby
171
+ # routes.rb
22
172
 
23
- ## Usage
173
+ resources :files, only: :show, controller: "shimmer/files"
24
174
 
25
- TODO: Write usage instructions here
175
+ # application_controller.rb
176
+ class ApplicationController < ActionController::Base
177
+ include Shimmer::Localizable
178
+ include Shimmer::RemoteNavigation
179
+ end
180
+ ```
26
181
 
27
- ## Development
182
+ ```ts
183
+ // application.ts
28
184
 
29
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
185
+ import { start } from "@nerdgeschoss/shimmer";
186
+ import { application } from "controllers/application";
30
187
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
188
+ start({ application });
189
+ ```
32
190
 
33
191
  ## Contributing
34
192
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/shimmer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/shimmer/blob/master/CODE_OF_CONDUCT.md).
193
+ Bug reports and pull requests are welcome on GitHub at https://github.com/nerdgeschoss/shimmer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/nerdgeschoss/shimmer/blob/master/CODE_OF_CONDUCT.md).
36
194
 
37
195
  ## License
38
196
 
@@ -40,4 +198,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
40
198
 
41
199
  ## Code of Conduct
42
200
 
43
- Everyone interacting in the Shimmer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/shimmer/blob/master/CODE_OF_CONDUCT.md).
201
+ Everyone interacting in the Shimmer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/nerdgeschoss/shimmer/blob/master/CODE_OF_CONDUCT.md).
@@ -29,31 +29,32 @@ module Shimmer
29
29
  def url_locale
30
30
  params[:locale]
31
31
  end
32
- end
33
- end
34
- end
35
-
36
- module I18n
37
- UNTRANSLATED_SCOPES = ["number", "transliterate", "date", "datetime", "errors", "helpers", "support", "time", "faker"].map { |k| "#{k}." }
38
-
39
- thread_mattr_accessor :debug
40
32
 
41
- class << self
42
- alias_method :old_translate, :translate
43
- def translate(key, options = {})
44
- key = key.to_s.downcase
45
- untranslated = UNTRANSLATED_SCOPES.any? { |e| key.include? e }
46
- key_name = [options[:scope], key].flatten.compact.join(".")
47
- option_names = options.except(:count, :default, :raise, :scope).map { |k, v| "#{k}=#{v}" }.join(", ")
48
- return "#{key_name} #{option_names}" if I18n.debug && !untranslated
49
-
50
- options.reverse_merge!(default: old_translate(key, **options.merge(locale: :de))) if untranslated
51
- old_translate(key, **options)
52
- end
53
- alias_method :t, :translate
54
-
55
- def debug?
56
- debug
33
+ I18n.class_eval do
34
+ next if defined? debug
35
+
36
+ thread_mattr_accessor :debug
37
+
38
+ class << self
39
+ alias_method :old_translate, :translate
40
+ def translate(key, options = {})
41
+ untranslated_scopes = ["number", "transliterate", "date", "datetime", "errors", "helpers", "support", "time", "faker"].map { |k| "#{k}." }
42
+ key = key.to_s.downcase
43
+ untranslated = untranslated_scopes.any? { |e| key.include? e }
44
+ key_name = [options[:scope], key].flatten.compact.join(".")
45
+ option_names = options.except(:count, :default, :raise, :scope).map { |k, v| "#{k}=#{v}" }.join(", ")
46
+ return "#{key_name} #{option_names}" if I18n.debug && !untranslated
47
+
48
+ options.reverse_merge!(default: old_translate(key, **options.merge(locale: :de))) if untranslated
49
+ old_translate(key, **options)
50
+ end
51
+ alias_method :t, :translate
52
+
53
+ def debug?
54
+ debug
55
+ end
56
+ end
57
+ end
57
58
  end
58
59
  end
59
60
  end
@@ -6,7 +6,7 @@ module Shimmer
6
6
 
7
7
  included do
8
8
  def ui
9
- @ui ||= RemoteNavigator.new turbo_stream: turbo_stream
9
+ @ui ||= RemoteNavigator.new(self)
10
10
  end
11
11
 
12
12
  def default_render
@@ -17,7 +17,7 @@ module Shimmer
17
17
  end
18
18
 
19
19
  helper_method :modal_path
20
- def modal_path(url, id: nil, size: nil, close: false)
20
+ def modal_path(url, id: nil, size: nil, close: true)
21
21
  "javascript:ui.modal.open(#{{url: url, id: id, size: size, close: close}.to_json})"
22
22
  end
23
23
 
@@ -26,6 +26,11 @@ module Shimmer
26
26
  "javascript:ui.modal.close(#{{id: id}.to_json})"
27
27
  end
28
28
 
29
+ helper_method :popover_path
30
+ def popover_path(url, id: nil, selector: nil, placement: nil)
31
+ "javascript:ui.popover.open(#{{url: url, id: id, selector: selector, placement: placement}.compact.to_json})"
32
+ end
33
+
29
34
  def shimmer_request?
30
35
  request.headers["X-Shimmer"].present?
31
36
  end
@@ -42,10 +47,10 @@ module Shimmer
42
47
  end
43
48
 
44
49
  class RemoteNavigator
45
- attr_reader :turbo_stream
50
+ delegate :polymorphic_path, to: :@controller
46
51
 
47
- def initialize(turbo_stream:)
48
- @turbo_stream = turbo_stream
52
+ def initialize(controller)
53
+ @controller = controller
49
54
  end
50
55
 
51
56
  def queued_updates
@@ -76,18 +81,32 @@ module Shimmer
76
81
  queued_updates.push turbo_stream.remove(id)
77
82
  end
78
83
 
79
- def open_modal(path)
80
- run_javascript "ui.modal.open('#{path}')"
84
+ def open_modal(path, id: nil, size: nil, close: true)
85
+ run_javascript "ui.modal.open(#{{url: url, id: id, size: size, close: close}.to_json})"
81
86
  end
82
87
 
83
88
  def close_modal
84
89
  run_javascript "ui.modal.close()"
85
90
  end
86
91
 
92
+ def open_popover(path, selector:, placement: nil)
93
+ run_javascript "ui.popover.open(#{{url: url, selector: selector, placement: placement}.to_json})"
94
+ end
95
+
96
+ def close_popover
97
+ run_javascript "ui.popover.close()"
98
+ end
99
+
87
100
  def navigate_to(path)
88
101
  close_modal
89
102
  path = polymorphic_path(path) unless path.is_a?(String)
90
103
  run_javascript "Turbo.visit('#{path}')"
91
104
  end
105
+
106
+ private
107
+
108
+ def turbo_stream
109
+ @controller.send(:turbo_stream)
110
+ end
92
111
  end
93
112
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Shimmer
4
- VERSION = "0.0.4"
4
+ VERSION = "0.0.8"
5
5
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nerdgeschoss/shimmer",
3
- "version": "0.0.1",
3
+ "version": "4.0.0",
4
4
  "description": "Simple application development in Rails",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -22,6 +22,8 @@
22
22
  ],
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
+ "@hotwired/stimulus": "^3.0.1",
26
+ "@popperjs/core": "^2.11.0",
25
27
  "@rails/request.js": "^0.0.6"
26
28
  },
27
29
  "devDependencies": {
data/rollup.config.js CHANGED
@@ -4,7 +4,7 @@ import pkg from "./package.json";
4
4
 
5
5
  export default {
6
6
  input: "./src/index.ts",
7
- external: ["@rails/request.js"],
7
+ external: ["@rails/request.js", "@hotwired/stimulus", "@popperjs/core"],
8
8
  plugins: [
9
9
  cleaner({
10
10
  targets: ["./dist/"],
@@ -0,0 +1,9 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+
3
+ export default class extends Controller {
4
+ connect(): void {
5
+ const script = (this.element as HTMLDivElement).innerText;
6
+ (0, eval)(script);
7
+ this.element.remove();
8
+ }
9
+ }
data/src/index.ts CHANGED
@@ -1,17 +1,32 @@
1
- declare global {
2
- interface Window {
3
- ui: typeof ui;
4
- }
5
- }
6
-
1
+ import type { Application } from "@hotwired/stimulus";
7
2
  import { ModalPresenter } from "./modal";
3
+ import { PopoverPresenter } from "./popover";
4
+ import RemoteNavigationController from "./controllers/remote-navigation";
8
5
  import "./touch";
9
6
 
10
- export const ui = {
11
- modal: new ModalPresenter(),
12
- };
13
-
14
- window.ui = ui;
15
-
16
7
  export { registerServiceWorker } from "./serviceworker";
17
8
  export { currentLocale } from "./locale";
9
+
10
+ declare global {
11
+ interface Window {
12
+ ui?: {
13
+ modal: ModalPresenter;
14
+ popover: PopoverPresenter;
15
+ };
16
+ }
17
+ }
18
+
19
+ export async function start({
20
+ application,
21
+ }: {
22
+ application: Application;
23
+ }): Promise<void> {
24
+ const root = document.createElement("div");
25
+ root.id = "shimmer";
26
+ document.body.append(root);
27
+ application.register("remote-navigation", RemoteNavigationController);
28
+ window.ui = {
29
+ modal: new ModalPresenter(),
30
+ popover: new PopoverPresenter(),
31
+ };
32
+ }
data/src/modal.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { get } from "@rails/request.js";
1
+ import { loaded, createElement, nextFrame, getHTML } from "./util";
2
2
 
3
3
  export interface ModalOptions {
4
4
  id?: string;
@@ -7,33 +7,6 @@ export interface ModalOptions {
7
7
  close?: boolean;
8
8
  }
9
9
 
10
- const loaded: Promise<void> = new Promise((res) => {
11
- document.addEventListener("DOMContentLoaded", () => {
12
- res();
13
- });
14
- });
15
-
16
- async function nextFrame(): Promise<void> {
17
- return new Promise((res) => {
18
- setTimeout(res, 10);
19
- });
20
- }
21
-
22
- async function getHTML(url: string): Promise<string> {
23
- const response = await get(url, { headers: { "X-Shimmer": "true" } });
24
- if (response.ok) {
25
- return await response.response.text();
26
- }
27
- return "";
28
- }
29
-
30
- function createElement(parent: HTMLElement, className: string): HTMLDivElement {
31
- const element = document.createElement("div");
32
- element.className = className;
33
- parent.append(element);
34
- return element;
35
- }
36
-
37
10
  export class ModalPresenter {
38
11
  private modals: Record<string, Modal> = {};
39
12
 
data/src/popover.ts ADDED
@@ -0,0 +1,89 @@
1
+ import { Instance as Popper, createPopper, Placement } from "@popperjs/core";
2
+ import { createElement, getHTML } from "./util";
3
+
4
+ export interface PopoverOptions {
5
+ id?: string;
6
+ url: string;
7
+ selector?: HTMLElement | string;
8
+ placement?: Placement;
9
+ }
10
+
11
+ export class PopoverPresenter {
12
+ private popovers: Record<string, Popover> = {};
13
+ private lastClickedElement?: HTMLElement;
14
+
15
+ constructor() {
16
+ document.addEventListener("click", this.trackElement);
17
+ }
18
+
19
+ async open(options: PopoverOptions): Promise<void> {
20
+ const id = (options.id = options.id ?? "default-popover");
21
+ options.selector = options.selector ?? this.lastClickedElement;
22
+ (this.popovers[id] = new Popover()).open(options);
23
+ }
24
+
25
+ async close({ id }: { id?: string } = {}): Promise<void> {
26
+ let promise: Promise<unknown> | null = null;
27
+ if (id) {
28
+ promise = this.popovers[id]?.close();
29
+ delete this.popovers[id];
30
+ } else {
31
+ promise = Promise.all(Object.values(this.popovers).map((e) => e.close()));
32
+ this.popovers = {};
33
+ }
34
+ await promise;
35
+ }
36
+
37
+ private trackElement = (event: MouseEvent): void => {
38
+ this.lastClickedElement = event.target as HTMLElement;
39
+ };
40
+ }
41
+
42
+ export class Popover {
43
+ private popper?: Popper;
44
+ private popoverDiv?: HTMLDivElement;
45
+
46
+ async open({ url, selector, placement }: PopoverOptions): Promise<void> {
47
+ const root =
48
+ typeof selector === "string"
49
+ ? document.querySelector(selector)
50
+ : selector;
51
+ if (!root) {
52
+ return;
53
+ }
54
+ const popoverDiv = createElement(document.body, "popover");
55
+ const arrow = createElement(popoverDiv, "popover__arrow");
56
+ arrow.setAttribute("data-popper-arrow", "true");
57
+ const content = createElement(popoverDiv, "popover__content");
58
+ content.innerHTML = await getHTML(url);
59
+ this.popper = createPopper(root, popoverDiv, {
60
+ placement: placement ?? "auto",
61
+ modifiers: [
62
+ {
63
+ name: "offset",
64
+ options: {
65
+ offset: [0, 8],
66
+ },
67
+ },
68
+ ],
69
+ });
70
+ this.popoverDiv = popoverDiv;
71
+ document.addEventListener("click", this.clickOutside);
72
+ }
73
+
74
+ async close(): Promise<void> {
75
+ this.popper?.destroy();
76
+ this.popper = undefined;
77
+ document.removeEventListener("click", this.clickOutside);
78
+ this.popoverDiv?.remove();
79
+ this.popoverDiv = undefined;
80
+ }
81
+
82
+ private clickOutside = (event: MouseEvent): void => {
83
+ if (this.popoverDiv?.contains(event.target as HTMLElement)) {
84
+ return;
85
+ }
86
+ event.preventDefault();
87
+ this.close();
88
+ };
89
+ }
data/src/util.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { get } from "@rails/request.js";
2
+
3
+ export async function getHTML(url: string): Promise<string> {
4
+ const response = await get(url, { headers: { "X-Shimmer": "true" } });
5
+ if (response.ok) {
6
+ return await response.response.text();
7
+ }
8
+ return "";
9
+ }
10
+
11
+ export const loaded: Promise<void> = new Promise((res) => {
12
+ document.addEventListener("DOMContentLoaded", () => {
13
+ res();
14
+ });
15
+ });
16
+
17
+ export async function nextFrame(): Promise<void> {
18
+ return new Promise((res) => {
19
+ setTimeout(res, 10);
20
+ });
21
+ }
22
+
23
+ export function createElement(
24
+ parent: HTMLElement,
25
+ className: string
26
+ ): HTMLDivElement {
27
+ const element = document.createElement("div");
28
+ element.className = className;
29
+ parent.append(element);
30
+ return element;
31
+ }
data/yarn.lock CHANGED
@@ -17,6 +17,11 @@
17
17
  minimatch "^3.0.4"
18
18
  strip-json-comments "^3.1.1"
19
19
 
20
+ "@hotwired/stimulus@^3.0.1":
21
+ version "3.0.1"
22
+ resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.0.1.tgz#141f15645acaa3b133b7c247cad58ae252ffae85"
23
+ integrity sha512-oHsJhgY2cip+K2ED7vKUNd2P+BEswVhrCYcJ802DSsblJFv7mPFVk3cQKvm2vHgHeDVdnj7oOKrBbzp1u8D+KA==
24
+
20
25
  "@humanwhocodes/config-array@^0.9.2":
21
26
  version "0.9.2"
22
27
  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914"
@@ -52,6 +57,11 @@
52
57
  "@nodelib/fs.scandir" "2.1.5"
53
58
  fastq "^1.6.0"
54
59
 
60
+ "@popperjs/core@^2.11.0":
61
+ version "2.11.0"
62
+ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.0.tgz#6734f8ebc106a0860dff7f92bf90df193f0935d7"
63
+ integrity sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==
64
+
55
65
  "@rails/request.js@^0.0.6":
56
66
  version "0.0.6"
57
67
  resolved "https://registry.yarnpkg.com/@rails/request.js/-/request.js-0.0.6.tgz#5f0347a9f363e50ec45118c7134080490cda81d8"
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Ravens
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-21 00:00:00.000000000 Z
11
+ date: 2022-01-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description:
13
+ description:
14
14
  email:
15
15
  - jens@nerdgeschoss.de
16
16
  executables: []
@@ -48,12 +48,14 @@ files:
48
48
  - lib/shimmer/version.rb
49
49
  - package.json
50
50
  - rollup.config.js
51
- - shimmer.gemspec
51
+ - src/controllers/remote-navigation.ts
52
52
  - src/index.ts
53
53
  - src/locale.ts
54
54
  - src/modal.ts
55
+ - src/popover.ts
55
56
  - src/serviceworker.ts
56
57
  - src/touch.ts
58
+ - src/util.ts
57
59
  - tsconfig.json
58
60
  - typings.d.ts
59
61
  - yarn.lock
@@ -63,7 +65,7 @@ licenses:
63
65
  metadata:
64
66
  homepage_uri: https://github.com/nerdgeschoss/shimmer
65
67
  source_code_uri: https://github.com/nerdgeschoss/shimmer
66
- post_install_message:
68
+ post_install_message:
67
69
  rdoc_options: []
68
70
  require_paths:
69
71
  - lib
@@ -79,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
81
  version: '0'
80
82
  requirements: []
81
83
  rubygems_version: 3.2.32
82
- signing_key:
84
+ signing_key:
83
85
  specification_version: 4
84
86
  summary: Shimmer brings all the bells and whistles of a hotwired application, right
85
87
  from the start.
data/shimmer.gemspec DELETED
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/shimmer/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "shimmer"
7
- spec.version = Shimmer::VERSION
8
- spec.authors = ["Jens Ravens"]
9
- spec.email = ["jens@nerdgeschoss.de"]
10
-
11
- spec.summary = "Shimmer brings all the bells and whistles of a hotwired application, right from the start."
12
- spec.homepage = "https://github.com/nerdgeschoss/shimmer"
13
- spec.license = "MIT"
14
- spec.required_ruby_version = ">= 2.6.0"
15
-
16
- spec.metadata["homepage_uri"] = spec.homepage
17
- spec.metadata["source_code_uri"] = spec.homepage
18
-
19
- # Specify which files should be added to the gem when it is released.
20
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
- `git ls-files -z`.split("\x0").reject do |f|
23
- (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
24
- end
25
- end
26
- spec.bindir = "exe"
27
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
- spec.require_paths = ["lib"]
29
-
30
- # Uncomment to register a new dependency of your gem
31
- # spec.add_dependency "example-gem", "~> 1.0"
32
-
33
- # For more information and examples about making a new gem, checkout our
34
- # guide at: https://bundler.io/guides/creating_gem.html
35
- end