lookbook 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +69 -84
- data/app/assets/lookbook/js/app.js +3 -1
- data/app/views/lookbook/layouts/app.html.erb +5 -3
- data/config/routes.rb +3 -1
- data/lib/lookbook/engine.rb +6 -4
- data/lib/lookbook/version.rb +1 -1
- data/public/lookbook-assets/app.css +10 -12
- data/public/lookbook-assets/app.js +54 -25
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e8a93baa87f47304f68676fd5884b61eb32782f552e89316e4abb702373003f
|
4
|
+
data.tar.gz: ada4f4b935bc63066b980a8faf7fcf81f4f7a594790f4f4ddd8a01a630b880f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cc694ae333a50382654e9c36f52a9cfe964a20bd6715ce365dd55adcca44c564e1a742c053625286dad9f929bf9640919d961277d4c426ab7c9584cb57fd5da
|
7
|
+
data.tar.gz: ef0fc829bf1528cc521f2cd98887fc67476ed1d0a316e8ebefd9813e744714a0145b897091f7cc6768c2b459b1c3e5bf3982b2ee7ae451f2b2e512fa35e67b4a
|
data/README.md
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
<div align="center">
|
2
|
-
|
2
|
+
<h1>👀 Lookbook 👀</h1>
|
3
3
|
|
4
|
-
|
4
|
+
<p>A native development UI for <a href="http://viewcomponent.org/">ViewComponent</a></p>
|
5
5
|
|
6
|
+
<div>
|
7
|
+
<a href="https://rubygems.org/gems/lookbook"><img src="https://badge.fury.io/rb/lookbook.svg" alt="Gem version">
|
8
|
+
<a href="https://github.com/testdouble/standard"><img src="https://img.shields.io/badge/code_style-standard-brightgreen.svg" alt="Ruby Style Guide">
|
9
|
+
<a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg" alt="Code style: Prettier">
|
10
|
+
</div>
|
6
11
|
</div>
|
7
12
|
|
8
13
|
---
|
9
14
|
|
10
|
-
Lookbook gives [ViewComponent](http://viewcomponent.org/)-based projects a _ready-to-go_ development UI for navigating, inspecting and interacting with component previews
|
15
|
+
**Lookbook gives [ViewComponent](http://viewcomponent.org/)-based projects a _ready-to-go_ development UI for navigating, inspecting and interacting with component previews.**
|
11
16
|
|
12
17
|
It uses (and extends) the native [ViewComponent preview functionality](https://viewcomponent.org/guide/previews.html), so you don't need to learn a new DSL or create any extra files to get up and running.
|
13
18
|
|
@@ -38,18 +43,13 @@ The [demo app repo](https://github.com/allmarkedup/lookbook-demo) contains instr
|
|
38
43
|
|
39
44
|
### 1. Add as a dependency
|
40
45
|
|
41
|
-
|
46
|
+
Add Lookbook to your `Gemfile` somewhere **after** the ViewComponent gem. For example:
|
42
47
|
|
43
48
|
```ruby
|
49
|
+
gem "view_component", require: "view_component/engine"
|
44
50
|
gem "lookbook"
|
45
51
|
```
|
46
52
|
|
47
|
-
or
|
48
|
-
|
49
|
-
```bash
|
50
|
-
gem install lookbook
|
51
|
-
```
|
52
|
-
|
53
53
|
### 2. Mount the Lookbook engine
|
54
54
|
|
55
55
|
You then need to mount the Lookbook engine (at a path of your choosing) in your `routes.rb` file:
|
@@ -70,125 +70,110 @@ Then you can start your app as normal and navigate to `http://localhost:3000/loo
|
|
70
70
|
|
71
71
|
## Usage
|
72
72
|
|
73
|
-
You don't need to do anything special to
|
73
|
+
You don't need to do anything special to see your ViewComponent previews and examples in Lookbook - just create them as normal and they'll automatically appear in the Lookbook UI. Preview templates, custom layouts and even bespoke [preview controllers](https://viewcomponent.org/guide/previews.html#configuring-preview-controller) should all work as you would expect.
|
74
74
|
|
75
|
-
|
75
|
+
> If you are new to ViewComponent development, checkout the ViewComponent [documentation](https://viewcomponent.org/guide/) on how to get started developing your components and [creating previews](https://viewcomponent.org/guide/previews.html).
|
76
76
|
|
77
|
-
|
77
|
+
### Annotating preview files
|
78
78
|
|
79
|
-
Lookbook
|
79
|
+
Lookbook parses [Yard-style comment tags](https://rubydoc.info/gems/yard/file/docs/Tags.md) in your preview classes to customise and extend the standard ViewComponent preview experience:
|
80
80
|
|
81
|
-
|
81
|
+
```ruby
|
82
|
+
# @label Basic Button
|
83
|
+
class ButtonComponentPreview < ViewComponent::Preview
|
82
84
|
|
83
|
-
|
85
|
+
# Primary button
|
86
|
+
# ---------------
|
87
|
+
# This is the button style you should use for most things.
|
88
|
+
#
|
89
|
+
# @label Primary
|
90
|
+
def default
|
91
|
+
render ButtonComponent.new do
|
92
|
+
"Click me"
|
93
|
+
end
|
94
|
+
end
|
84
95
|
|
85
|
-
|
96
|
+
# Secondary button
|
97
|
+
# ---------------
|
98
|
+
# This should be used for less important actions.
|
99
|
+
def secondary
|
100
|
+
render ButtonComponent.new(style: :secondary) do
|
101
|
+
"Click me"
|
102
|
+
end
|
103
|
+
end
|
86
104
|
|
87
|
-
|
88
|
-
#
|
89
|
-
#
|
90
|
-
|
91
|
-
# This is a method-level comment.
|
105
|
+
# Unicorn button
|
106
|
+
# ---------------
|
107
|
+
# This button style is still a **work in progress**.
|
108
|
+
#
|
92
109
|
# @hidden
|
93
|
-
def
|
110
|
+
def secondary
|
111
|
+
render ButtonComponent.new do
|
112
|
+
"Click me"
|
113
|
+
end
|
94
114
|
end
|
95
115
|
end
|
96
116
|
```
|
97
117
|
|
98
|
-
|
118
|
+
**Tags** are just strings identified by their `@` prefix - for example `@hidden`. Tags are always placed in a comment above the relevant preview class or example method.
|
99
119
|
|
100
|
-
|
120
|
+
The following Lookbook-specific tags are available for use:
|
101
121
|
|
102
|
-
|
122
|
+
#### `@label <text>`
|
103
123
|
|
104
|
-
|
124
|
+
Used to replace the auto-generated navigation label for the item with `<text>`.
|
105
125
|
|
106
|
-
|
126
|
+
> Available for preview classes & example methods.
|
107
127
|
|
108
128
|
```ruby
|
109
|
-
|
129
|
+
# @label Preview Label
|
130
|
+
class FooComponentPreview < ViewComponent::Preview
|
110
131
|
|
111
|
-
#
|
112
|
-
# Multi-line is just fine and **markdown** is supported too!
|
113
|
-
#
|
114
|
-
# It's a good place to put usage and implementation instructions
|
115
|
-
# for people browsing the component previews in the UI.
|
132
|
+
# @label Example Label
|
116
133
|
def default
|
117
|
-
render ButtonComponent.new(text: "Click me")
|
118
|
-
end
|
119
|
-
|
120
|
-
# Each preview example has it's own notes, extracted from the method comments.
|
121
|
-
def danger
|
122
|
-
render ButtonComponent.new(text: "Don't do it!", theme: :danger)
|
123
134
|
end
|
124
135
|
end
|
125
136
|
```
|
126
137
|
|
127
|
-
|
138
|
+
#### `@hidden`
|
128
139
|
|
129
|
-
|
140
|
+
Used to temporarily exclude an item from the Lookbook navigation. The item will still be accessible via it's URL.
|
130
141
|
|
131
|
-
|
142
|
+
Can be useful when a component (or a variant of a component) is still in development and is not ready to be shared with the wider team.
|
132
143
|
|
133
|
-
|
134
|
-
|
135
|
-
If you wish to override the automatic navigation label generation for a preview or example you can use the `@label` comment tag:
|
144
|
+
> Available for both preview classes & example methods.
|
136
145
|
|
137
146
|
```ruby
|
138
|
-
# @
|
139
|
-
class
|
147
|
+
# @hidden
|
148
|
+
class FooComponentPreview < ViewComponent::Preview
|
140
149
|
|
141
|
-
# @
|
142
|
-
def
|
150
|
+
# @hidden
|
151
|
+
def default
|
143
152
|
end
|
144
153
|
end
|
145
154
|
```
|
146
155
|
|
147
|
-
|
148
|
-
|
149
|
-
<img src=".github/assets/nav_labels.png" width="200">
|
150
|
-
|
151
|
-
#### Excluding previews and/or examples from the navigation
|
152
|
-
|
153
|
-
Sometimes you may want to temporarily hide a preview or an individual example from the Lookbook UI. This means that the preview or example will not show up in the navigation, but will still be accessible via it's URL. You can use the `@hidden` comment tag to manage this.
|
156
|
+
#### Adding notes
|
154
157
|
|
155
|
-
|
158
|
+
All comment text other than tags will be treated as markdown and rendered in the **Notes** panel for that example in the Lookbook UI.
|
156
159
|
|
157
160
|
```ruby
|
158
161
|
# @hidden
|
159
|
-
class
|
160
|
-
# examples here....
|
161
|
-
end
|
162
|
-
```
|
163
|
-
|
164
|
-
To **hide an individual example** include the `@hidden` tag in the appropriate method comment:
|
165
|
-
|
166
|
-
```ruby
|
167
|
-
class MyComponentPreview < ViewComponent::Preview
|
162
|
+
class ProfileCardComponentPreview < ViewComponent::Preview
|
168
163
|
|
169
|
-
#
|
170
|
-
#
|
171
|
-
#
|
172
|
-
|
173
|
-
# @hidden
|
174
|
-
def hidden_example
|
175
|
-
# ...
|
176
|
-
end
|
177
|
-
|
178
|
-
def a_visible_example
|
179
|
-
# ...
|
180
|
-
end
|
181
|
-
|
182
|
-
# @hidden
|
183
|
-
def another_hidden_example
|
184
|
-
# ...
|
164
|
+
# Profile Card
|
165
|
+
# ------------
|
166
|
+
# Use the default profile card component whenever you need to represent a user.
|
167
|
+
def default
|
185
168
|
end
|
186
169
|
end
|
187
170
|
```
|
188
171
|
|
172
|
+
<img src=".github/assets/preview_example_notes.png" width="400">
|
173
|
+
|
189
174
|
## Configuration
|
190
175
|
|
191
|
-
Lookbook
|
176
|
+
Lookbook will use the ViewComponent [configuration](https://viewcomponent.org/api.html#configuration) for your project to find and render your previews so you generally you won't need to configure anything separately.
|
192
177
|
|
193
178
|
However the following Lookbook-specific config options are also available:
|
194
179
|
|
@@ -8,9 +8,11 @@
|
|
8
8
|
<link href="/lookbook-assets/app.css" rel="stylesheet">
|
9
9
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>👀</text></svg>">
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
<% if config.auto_refresh %>
|
12
|
+
<script>
|
13
|
+
window.SOCKET_PATH = "/lookbook/cable";
|
14
|
+
</script>
|
15
|
+
<% end %>
|
14
16
|
<script src="/lookbook-assets/app.js" defer></script>
|
15
17
|
|
16
18
|
<title><%= [@example&.label, @preview&.label, "Lookbook"].compact.join(" :: ") %></title>
|
data/config/routes.rb
CHANGED
data/lib/lookbook/engine.rb
CHANGED
@@ -35,10 +35,12 @@ module Lookbook
|
|
35
35
|
end
|
36
36
|
|
37
37
|
initializer "lookbook.cable.config" do |app|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
if app.config.lookbook.auto_refresh
|
39
|
+
config_path = Lookbook::Engine.root.join("config", "lookbook_cable.yml")
|
40
|
+
Lookbook::Engine.cable.cable = app.config_for(config_path).with_indifferent_access
|
41
|
+
Lookbook::Engine.cable.mount_path = "/cable"
|
42
|
+
Lookbook::Engine.cable.connection_class = -> { Lookbook::Connection }
|
43
|
+
end
|
42
44
|
end
|
43
45
|
|
44
46
|
initializer "lookbook.cable.logger" do
|
data/lib/lookbook/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! tailwindcss v2.2.
|
1
|
+
/*! tailwindcss v2.2.7 | MIT License | https://tailwindcss.com */
|
2
2
|
|
3
3
|
/*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */
|
4
4
|
|
@@ -575,6 +575,14 @@ video {
|
|
575
575
|
height: auto;
|
576
576
|
}
|
577
577
|
|
578
|
+
/**
|
579
|
+
* Ensure the default browser behavior of the `hidden` attribute.
|
580
|
+
*/
|
581
|
+
|
582
|
+
[hidden] {
|
583
|
+
display: none;
|
584
|
+
}
|
585
|
+
|
578
586
|
*, ::before, ::after {
|
579
587
|
--tw-translate-x: 0;
|
580
588
|
--tw-translate-y: 0;
|
@@ -586,13 +594,13 @@ video {
|
|
586
594
|
--tw-transform: translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
587
595
|
--tw-border-opacity: 1;
|
588
596
|
border-color: rgba(229, 231, 235, var(--tw-border-opacity));
|
589
|
-
--tw-shadow: 0 0 #0000;
|
590
597
|
--tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
|
591
598
|
--tw-ring-offset-width: 0px;
|
592
599
|
--tw-ring-offset-color: #fff;
|
593
600
|
--tw-ring-color: rgba(59, 130, 246, 0.5);
|
594
601
|
--tw-ring-offset-shadow: 0 0 #0000;
|
595
602
|
--tw-ring-shadow: 0 0 #0000;
|
603
|
+
--tw-shadow: 0 0 #0000;
|
596
604
|
--tw-blur: var(--tw-empty,/*!*/ /*!*/);
|
597
605
|
--tw-brightness: var(--tw-empty,/*!*/ /*!*/);
|
598
606
|
--tw-contrast: var(--tw-empty,/*!*/ /*!*/);
|
@@ -603,16 +611,6 @@ video {
|
|
603
611
|
--tw-sepia: var(--tw-empty,/*!*/ /*!*/);
|
604
612
|
--tw-drop-shadow: var(--tw-empty,/*!*/ /*!*/);
|
605
613
|
--tw-filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
606
|
-
--tw-backdrop-blur: var(--tw-empty,/*!*/ /*!*/);
|
607
|
-
--tw-backdrop-brightness: var(--tw-empty,/*!*/ /*!*/);
|
608
|
-
--tw-backdrop-contrast: var(--tw-empty,/*!*/ /*!*/);
|
609
|
-
--tw-backdrop-grayscale: var(--tw-empty,/*!*/ /*!*/);
|
610
|
-
--tw-backdrop-hue-rotate: var(--tw-empty,/*!*/ /*!*/);
|
611
|
-
--tw-backdrop-invert: var(--tw-empty,/*!*/ /*!*/);
|
612
|
-
--tw-backdrop-opacity: var(--tw-empty,/*!*/ /*!*/);
|
613
|
-
--tw-backdrop-saturate: var(--tw-empty,/*!*/ /*!*/);
|
614
|
-
--tw-backdrop-sepia: var(--tw-empty,/*!*/ /*!*/);
|
615
|
-
--tw-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
616
614
|
}
|
617
615
|
|
618
616
|
[type='text'],[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select {
|
@@ -2294,12 +2294,17 @@ Expression: "${expression}"
|
|
2294
2294
|
});
|
2295
2295
|
}
|
2296
2296
|
var isDeferringHandlers = false;
|
2297
|
-
var
|
2297
|
+
var directiveHandlerStacks = new Map();
|
2298
|
+
var currentHandlerStackKey = Symbol();
|
2298
2299
|
function deferHandlingDirectives(callback) {
|
2299
2300
|
isDeferringHandlers = true;
|
2301
|
+
let key = Symbol();
|
2302
|
+
currentHandlerStackKey = key;
|
2303
|
+
directiveHandlerStacks.set(key, []);
|
2300
2304
|
let flushHandlers = () => {
|
2301
|
-
while (
|
2302
|
-
|
2305
|
+
while (directiveHandlerStacks.get(key).length)
|
2306
|
+
directiveHandlerStacks.get(key).shift()();
|
2307
|
+
directiveHandlerStacks.delete(key);
|
2303
2308
|
};
|
2304
2309
|
let stopDeferring = () => {
|
2305
2310
|
isDeferringHandlers = false;
|
@@ -2330,7 +2335,7 @@ Expression: "${expression}"
|
|
2330
2335
|
return;
|
2331
2336
|
handler3.inline && handler3.inline(el, directive2, utilities);
|
2332
2337
|
handler3 = handler3.bind(handler3, el, directive2, utilities);
|
2333
|
-
isDeferringHandlers ?
|
2338
|
+
isDeferringHandlers ? directiveHandlerStacks.get(currentHandlerStackKey).push(handler3) : handler3();
|
2334
2339
|
};
|
2335
2340
|
fullHandler.runCleanups = doCleanup;
|
2336
2341
|
return fullHandler;
|
@@ -2449,7 +2454,7 @@ Expression: "${expression}"
|
|
2449
2454
|
onAttributesAdded((el, attrs) => {
|
2450
2455
|
directives(el, attrs).forEach((handle) => handle());
|
2451
2456
|
});
|
2452
|
-
let outNestedComponents = (el) => !closestRoot(el.
|
2457
|
+
let outNestedComponents = (el) => !closestRoot(el.parentElement);
|
2453
2458
|
Array.from(document.querySelectorAll(allSelectors())).filter(outNestedComponents).forEach((el) => {
|
2454
2459
|
initTree(el);
|
2455
2460
|
});
|
@@ -2470,6 +2475,8 @@ Expression: "${expression}"
|
|
2470
2475
|
initSelectorCallbacks.push(selectorCallback);
|
2471
2476
|
}
|
2472
2477
|
function closestRoot(el) {
|
2478
|
+
if (!el)
|
2479
|
+
return;
|
2473
2480
|
if (rootSelectors().some((selector) => el.matches(selector)))
|
2474
2481
|
return el;
|
2475
2482
|
if (!el.parentElement)
|
@@ -2576,7 +2583,7 @@ Expression: "${expression}"
|
|
2576
2583
|
get raw() {
|
2577
2584
|
return raw;
|
2578
2585
|
},
|
2579
|
-
version: "3.2.
|
2586
|
+
version: "3.2.4",
|
2580
2587
|
disableEffectScheduling,
|
2581
2588
|
setReactivityEngine,
|
2582
2589
|
addRootSelector,
|
@@ -2678,7 +2685,7 @@ Expression: "${expression}"
|
|
2678
2685
|
let previousStyles = {};
|
2679
2686
|
Object.entries(value).forEach(([key, value2]) => {
|
2680
2687
|
previousStyles[key] = el.style[key];
|
2681
|
-
el.style
|
2688
|
+
el.style.setProperty(kebabCase(key), value2);
|
2682
2689
|
});
|
2683
2690
|
setTimeout(() => {
|
2684
2691
|
if (el.style.length === 0) {
|
@@ -2696,6 +2703,9 @@ Expression: "${expression}"
|
|
2696
2703
|
el.setAttribute("style", cache);
|
2697
2704
|
};
|
2698
2705
|
}
|
2706
|
+
function kebabCase(subject) {
|
2707
|
+
return subject.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
2708
|
+
}
|
2699
2709
|
function once(callback, fallback = () => {
|
2700
2710
|
}) {
|
2701
2711
|
let called = false;
|
@@ -3113,6 +3123,8 @@ Expression: "${expression}"
|
|
3113
3123
|
let handler3 = (e) => callback(e);
|
3114
3124
|
let options = {};
|
3115
3125
|
let wrapHandler = (callback2, wrapper) => (e) => wrapper(callback2, e);
|
3126
|
+
if (modifiers.includes("dot"))
|
3127
|
+
event = dotSyntax(event);
|
3116
3128
|
if (modifiers.includes("camel"))
|
3117
3129
|
event = camelCase2(event);
|
3118
3130
|
if (modifiers.includes("passive"))
|
@@ -3174,6 +3186,9 @@ Expression: "${expression}"
|
|
3174
3186
|
listenerTarget.removeEventListener(event, handler3, options);
|
3175
3187
|
};
|
3176
3188
|
}
|
3189
|
+
function dotSyntax(subject) {
|
3190
|
+
return subject.replace(/-/g, ".");
|
3191
|
+
}
|
3177
3192
|
function camelCase2(subject) {
|
3178
3193
|
return subject.toLowerCase().replace(/-(\w)/g, (match, char) => char.toUpperCase());
|
3179
3194
|
}
|
@@ -3203,7 +3218,7 @@ Expression: "${expression}"
|
|
3203
3218
|
function isNumeric(subject) {
|
3204
3219
|
return !Array.isArray(subject) && !isNaN(subject);
|
3205
3220
|
}
|
3206
|
-
function
|
3221
|
+
function kebabCase2(subject) {
|
3207
3222
|
return subject.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[_\s]/, "-").toLowerCase();
|
3208
3223
|
}
|
3209
3224
|
function isKeyEvent(event) {
|
@@ -3219,7 +3234,7 @@ Expression: "${expression}"
|
|
3219
3234
|
}
|
3220
3235
|
if (keyModifiers.length === 0)
|
3221
3236
|
return false;
|
3222
|
-
if (keyModifiers.length === 1 &&
|
3237
|
+
if (keyModifiers.length === 1 && keyToModifiers(e.key).includes(keyModifiers[0]))
|
3223
3238
|
return false;
|
3224
3239
|
const systemKeyModifiers = ["ctrl", "shift", "alt", "meta", "cmd", "super"];
|
3225
3240
|
const selectedSystemKeyModifiers = systemKeyModifiers.filter((modifier) => keyModifiers.includes(modifier));
|
@@ -3231,22 +3246,33 @@ Expression: "${expression}"
|
|
3231
3246
|
return e[`${modifier}Key`];
|
3232
3247
|
});
|
3233
3248
|
if (activelyPressedKeyModifiers.length === selectedSystemKeyModifiers.length) {
|
3234
|
-
if (
|
3249
|
+
if (keyToModifiers(e.key).includes(keyModifiers[0]))
|
3235
3250
|
return false;
|
3236
3251
|
}
|
3237
3252
|
}
|
3238
3253
|
return true;
|
3239
3254
|
}
|
3240
|
-
function
|
3241
|
-
|
3242
|
-
|
3243
|
-
|
3244
|
-
|
3245
|
-
|
3246
|
-
|
3247
|
-
|
3248
|
-
|
3249
|
-
|
3255
|
+
function keyToModifiers(key) {
|
3256
|
+
if (!key)
|
3257
|
+
return [];
|
3258
|
+
key = kebabCase2(key);
|
3259
|
+
let modifierToKeyMap = {
|
3260
|
+
ctrl: "control",
|
3261
|
+
slash: "/",
|
3262
|
+
space: "-",
|
3263
|
+
spacebar: "-",
|
3264
|
+
cmd: "meta",
|
3265
|
+
esc: "escape",
|
3266
|
+
up: "arrow-up",
|
3267
|
+
down: "arrow-down",
|
3268
|
+
left: "arrow-left",
|
3269
|
+
right: "arrow-right"
|
3270
|
+
};
|
3271
|
+
modifierToKeyMap[key] = key;
|
3272
|
+
return Object.keys(modifierToKeyMap).map((modifier) => {
|
3273
|
+
if (modifierToKeyMap[modifier] === key)
|
3274
|
+
return modifier;
|
3275
|
+
}).filter((modifier) => modifier);
|
3250
3276
|
}
|
3251
3277
|
directive("model", (el, { modifiers, expression }, { effect: effect3, cleanup: cleanup2 }) => {
|
3252
3278
|
let evaluate2 = evaluateLater(el, expression);
|
@@ -3287,7 +3313,7 @@ Expression: "${expression}"
|
|
3287
3313
|
return (event, currentValue) => {
|
3288
3314
|
return mutateDom(() => {
|
3289
3315
|
if (event instanceof CustomEvent && event.detail !== void 0) {
|
3290
|
-
return event.detail;
|
3316
|
+
return event.detail || event.target.value;
|
3291
3317
|
} else if (el.type === "checkbox") {
|
3292
3318
|
if (Array.isArray(currentValue)) {
|
3293
3319
|
let newValue = modifiers.includes("number") ? safeParseNumber(event.target.value) : event.target.value;
|
@@ -3383,11 +3409,10 @@ Expression: "${expression}"
|
|
3383
3409
|
let reactiveData = reactive(data2);
|
3384
3410
|
initInterceptors(reactiveData);
|
3385
3411
|
let undo = addScopeToNode(el, reactiveData);
|
3386
|
-
|
3387
|
-
reactiveData["init"]();
|
3412
|
+
reactiveData["init"] && evaluate(el, reactiveData["init"]);
|
3388
3413
|
cleanup2(() => {
|
3389
3414
|
undo();
|
3390
|
-
reactiveData["destroy"] && reactiveData["destroy"]
|
3415
|
+
reactiveData["destroy"] && evaluate(el, reactiveData["destroy"]);
|
3391
3416
|
});
|
3392
3417
|
}));
|
3393
3418
|
directive("show", (el, { modifiers, expression }, { effect: effect3 }) => {
|
@@ -3444,6 +3469,8 @@ Expression: "${expression}"
|
|
3444
3469
|
if (isNumeric3(items) && items >= 0) {
|
3445
3470
|
items = Array.from(Array(items).keys(), (i) => i + 1);
|
3446
3471
|
}
|
3472
|
+
if (items === void 0)
|
3473
|
+
items = [];
|
3447
3474
|
let lookup = el._x_lookup;
|
3448
3475
|
let prevKeys = el._x_prevKeys;
|
3449
3476
|
let scopes = [];
|
@@ -7687,6 +7714,8 @@ Expression: "${expression}"
|
|
7687
7714
|
active: "source"
|
7688
7715
|
});
|
7689
7716
|
window.Alpine = module_default;
|
7690
|
-
|
7717
|
+
if (window.SOCKET_PATH) {
|
7718
|
+
reloader_default(window.SOCKET_PATH).start();
|
7719
|
+
}
|
7691
7720
|
module_default.start();
|
7692
7721
|
})();
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lookbook
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Perkins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '6.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '6.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|