lookbook 0.4.3 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +223 -54
- data/app/assets/lookbook/css/app.css +64 -8
- data/app/assets/lookbook/js/app.js +39 -53
- data/app/assets/lookbook/js/components/copy.js +16 -0
- data/app/assets/lookbook/js/components/filter.js +24 -0
- data/app/assets/lookbook/js/components/inspector.js +21 -0
- data/app/assets/lookbook/js/{nav/node.js → components/nav-group.js} +16 -15
- data/app/assets/lookbook/js/components/nav-item.js +26 -0
- data/app/assets/lookbook/js/components/nav.js +35 -0
- data/app/assets/lookbook/js/components/page.js +33 -0
- data/app/assets/lookbook/js/components/param.js +18 -0
- data/app/assets/lookbook/js/{workbench/preview.js → components/preview-window.js} +9 -10
- data/app/assets/lookbook/js/components/sidebar.js +3 -0
- data/app/assets/lookbook/js/components/sizes.js +16 -0
- data/app/assets/lookbook/js/components/splitter.js +25 -0
- data/app/assets/lookbook/js/config.js +14 -0
- data/app/assets/lookbook/js/{utils/reloader.js → lib/socket.js} +7 -12
- data/app/assets/lookbook/js/lib/split.js +21 -0
- data/app/assets/lookbook/js/lib/utils.js +3 -0
- data/app/assets/lookbook/js/stores/filter.js +11 -0
- data/app/assets/lookbook/js/stores/inspector.js +17 -0
- data/app/assets/lookbook/js/stores/layout.js +12 -0
- data/app/assets/lookbook/js/stores/nav.js +21 -0
- data/app/assets/lookbook/js/stores/sidebar.js +14 -0
- data/app/controllers/lookbook/app_controller.rb +82 -87
- data/app/helpers/lookbook/application_helper.rb +49 -5
- data/app/helpers/lookbook/preview_helper.rb +7 -0
- data/app/views/layouts/lookbook/app.html.erb +54 -0
- data/app/views/layouts/lookbook/preview.html.erb +12 -0
- data/app/views/lookbook/components/_code.html.erb +8 -0
- data/app/views/lookbook/{shared/_clipboard.html.erb → components/_copy.html.erb} +4 -5
- data/app/views/lookbook/components/_filter.html.erb +15 -0
- data/app/views/lookbook/{shared → components}/_header.html.erb +3 -3
- data/app/views/lookbook/components/_icon.html.erb +5 -0
- data/app/views/lookbook/components/_nav.html.erb +17 -0
- data/app/views/lookbook/components/_nav_collection.html.erb +5 -0
- data/app/views/lookbook/components/_nav_group.html.erb +17 -0
- data/app/views/lookbook/components/_nav_item.html.erb +21 -0
- data/app/views/lookbook/components/_nav_preview.html.erb +11 -0
- data/app/views/lookbook/components/_param.html.erb +20 -0
- data/app/views/lookbook/{workbench → components}/_preview.html.erb +8 -8
- data/app/views/lookbook/{app/error.html.erb → error.html.erb} +0 -0
- data/app/views/lookbook/index.html.erb +9 -0
- data/app/views/lookbook/inputs/_select.html.erb +8 -0
- data/app/views/lookbook/inputs/_text.html.erb +8 -0
- data/app/views/lookbook/inputs/_textarea.html.erb +8 -0
- data/app/views/lookbook/inputs/_toggle.html.erb +13 -0
- data/app/views/lookbook/{app/not_found.html.erb → not_found.html.erb} +2 -4
- data/app/views/lookbook/panels/_notes.html.erb +25 -0
- data/app/views/lookbook/panels/_output.html.erb +18 -0
- data/app/views/lookbook/panels/_params.html.erb +17 -0
- data/app/views/lookbook/panels/_source.html.erb +20 -0
- data/app/views/lookbook/show.html.erb +90 -0
- data/lib/lookbook/code_formatter.rb +20 -0
- data/lib/lookbook/engine.rb +10 -1
- data/lib/lookbook/features.rb +24 -0
- data/lib/lookbook/lang.rb +10 -5
- data/lib/lookbook/params.rb +110 -0
- data/lib/lookbook/parser.rb +1 -1
- data/lib/lookbook/preview.rb +1 -1
- data/lib/lookbook/preview_controller.rb +1 -1
- data/lib/lookbook/preview_example.rb +13 -1
- data/lib/lookbook/preview_group.rb +9 -1
- data/lib/lookbook/taggable.rb +2 -2
- data/lib/lookbook/version.rb +1 -1
- data/lib/lookbook.rb +3 -0
- data/public/lookbook-assets/css/app.css +2 -0
- data/public/lookbook-assets/css/app.css.map +1 -0
- data/public/lookbook-assets/js/app.js +2 -0
- data/public/lookbook-assets/js/app.js.map +1 -0
- metadata +58 -38
- data/app/assets/lookbook/js/nav/leaf.js +0 -20
- data/app/assets/lookbook/js/nav.js +0 -39
- data/app/assets/lookbook/js/page.js +0 -33
- data/app/assets/lookbook/js/utils/clipboard.js +0 -13
- data/app/assets/lookbook/js/utils/morph.js +0 -16
- data/app/assets/lookbook/js/utils/screen.js +0 -44
- data/app/assets/lookbook/js/utils/size_observer.js +0 -16
- data/app/assets/lookbook/js/utils/split.js +0 -26
- data/app/assets/lookbook/js/workbench/inspector.js +0 -11
- data/app/assets/lookbook/js/workbench.js +0 -14
- data/app/views/lookbook/app/index.html.erb +0 -11
- data/app/views/lookbook/app/show.html.erb +0 -1
- data/app/views/lookbook/layouts/app.html.erb +0 -41
- data/app/views/lookbook/nav/_collection.html.erb +0 -5
- data/app/views/lookbook/nav/_leaf.html.erb +0 -22
- data/app/views/lookbook/nav/_node.html.erb +0 -19
- data/app/views/lookbook/nav/_preview.html.erb +0 -11
- data/app/views/lookbook/preview/group.html.erb +0 -8
- data/app/views/lookbook/shared/_sidebar.html.erb +0 -45
- data/app/views/lookbook/shared/_workbench.html.erb +0 -12
- data/app/views/lookbook/workbench/_header.html.erb +0 -39
- data/app/views/lookbook/workbench/_inspector.html.erb +0 -33
- data/app/views/lookbook/workbench/inspector/_code.html.erb +0 -3
- data/app/views/lookbook/workbench/inspector/_notes.html.erb +0 -24
- data/app/views/lookbook/workbench/inspector/_plain.html.erb +0 -3
- data/public/lookbook-assets/app.css +0 -2504
- data/public/lookbook-assets/app.js +0 -8680
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce922c11cf8df5a1161c555189786265e51e29881c5a5e0948153fa65e855a50
|
|
4
|
+
data.tar.gz: 38fe97d9e04c6505ebc8e1b8bc877fe761db215b525117b42a044cadf7b2eb50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d319e159fc2b87e710532dbd6c426360f2a6173e174d3e0eac05c677bdfd945cf0c5a391c426a8f987cb7539797aa10241e45cdddd55048f25af84689d0af9b2
|
|
7
|
+
data.tar.gz: 80a217bf6303a778676872bd9d6c1412a3811323903031d491e945c0788ebba20cc2ccbb059d011e823b80d74b5342994c9b42f7590fd4fbfd305166b187d345
|
data/README.md
CHANGED
|
@@ -28,12 +28,15 @@ Lookbook uses [RDoc/Yard-style comment tags](#annotating-preview-files) to exten
|
|
|
28
28
|
- Auto-updating UI when component or preview files are updated _(Rails v6.0+ only)_
|
|
29
29
|
- Use comment tag annotations for granular customisation of the preview experience
|
|
30
30
|
- Fully compatible with standard the ViewComponent preview system
|
|
31
|
+
- [**Experimental**] In-browser live editable preview parameters (similar to Storybook Controls/Knobs)
|
|
31
32
|
|
|
32
33
|
## Lookbook demo
|
|
33
34
|
|
|
34
35
|
If you want to have a quick play with Lookbook, the easiest way is to [give the demo app](https://github.com/allmarkedup/lookbook-demo) a spin. It's a basic Rails/ViewComponent app with a few test components included to tinker with.
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
**Online demo: https://lookbook-demo-app.herokuapp.com/lookbook**
|
|
38
|
+
|
|
39
|
+
If you'd rather dig in a bit more and run the demo app locally, the [demo repo](https://github.com/allmarkedup/lookbook-demo) contains instructions on how to get it up and running.
|
|
37
40
|
|
|
38
41
|
## Installing
|
|
39
42
|
|
|
@@ -76,7 +79,7 @@ Lookbook parses [Yard-style comment tags](https://rubydoc.info/gems/yard/file/do
|
|
|
76
79
|
|
|
77
80
|
```ruby
|
|
78
81
|
# @label Basic Button
|
|
79
|
-
# @display bg_color
|
|
82
|
+
# @display bg_color #fff
|
|
80
83
|
class ButtonComponentPreview < ViewComponent::Preview
|
|
81
84
|
|
|
82
85
|
# Primary button
|
|
@@ -90,11 +93,24 @@ class ButtonComponentPreview < ViewComponent::Preview
|
|
|
90
93
|
end
|
|
91
94
|
end
|
|
92
95
|
|
|
96
|
+
# Button with icon
|
|
97
|
+
# ----------------
|
|
98
|
+
# This example uses dynamic preview parameters
|
|
99
|
+
# which can be edited live in the Lookbook UI
|
|
100
|
+
#
|
|
101
|
+
# @param text
|
|
102
|
+
# @param icon select [heart, cog, alert]
|
|
103
|
+
def icon(text: "Spread the love", icon: "heart")
|
|
104
|
+
render ButtonComponent.new(icon: icon) do
|
|
105
|
+
text
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
93
109
|
# Inverted button
|
|
94
110
|
# ---------------
|
|
95
111
|
# For light-on-dark screens
|
|
96
112
|
#
|
|
97
|
-
# @display bg_color
|
|
113
|
+
# @display bg_color #000
|
|
98
114
|
def secondary
|
|
99
115
|
render ButtonComponent.new(style: :inverted) do
|
|
100
116
|
"Click me"
|
|
@@ -141,54 +157,41 @@ end
|
|
|
141
157
|
|
|
142
158
|
The following Lookbook-specific tags are available for use:
|
|
143
159
|
|
|
144
|
-
* `@label
|
|
145
|
-
* `@
|
|
146
|
-
*
|
|
147
|
-
*
|
|
160
|
+
* [`@label`](#label-tag)
|
|
161
|
+
* [`@display`](#display-tag)
|
|
162
|
+
* [`@!group ... @!endgroup`](#group-tag)
|
|
163
|
+
* [`@hidden`](#hidden-tag)
|
|
164
|
+
* [`@param`](#param-tag) [⚠️ **experimental!** - requires [feature opt-in](#experimental-features) ⚠️]
|
|
148
165
|
|
|
149
|
-
|
|
166
|
+
<h3 id="label-tag">🏷 @label</h3>
|
|
150
167
|
|
|
151
168
|
Used to replace the auto-generated navigation label for the item with `<text>`.
|
|
152
169
|
|
|
153
|
-
> Available for preview classes & example methods.
|
|
154
|
-
|
|
155
170
|
```ruby
|
|
156
|
-
|
|
157
|
-
class FooComponentPreview < ViewComponent::Preview
|
|
158
|
-
|
|
159
|
-
# @label Example Label
|
|
160
|
-
def default
|
|
161
|
-
end
|
|
162
|
-
end
|
|
171
|
+
@label <text>
|
|
163
172
|
```
|
|
164
173
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
Used to temporarily exclude an item from the Lookbook navigation. The item will still be accessible via it's URL.
|
|
168
|
-
|
|
169
|
-
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.
|
|
170
|
-
|
|
171
|
-
> Available for both preview classes & example methods.
|
|
174
|
+
> Available for preview classes & example methods.
|
|
172
175
|
|
|
173
176
|
```ruby
|
|
174
|
-
# @
|
|
177
|
+
# @label Preview Label
|
|
175
178
|
class FooComponentPreview < ViewComponent::Preview
|
|
176
179
|
|
|
177
|
-
# @
|
|
180
|
+
# @label Example Label
|
|
178
181
|
def default
|
|
179
182
|
end
|
|
180
183
|
end
|
|
181
184
|
```
|
|
182
185
|
|
|
183
|
-
|
|
186
|
+
<h3 id="display-tag">🏷 @display</h3>
|
|
184
187
|
|
|
185
188
|
The `@display` tag lets you pass custom parameters to your preview layout so that the component preview can be customised on a per-example basis.
|
|
186
189
|
|
|
187
190
|
```ruby
|
|
188
|
-
# @display bg_color
|
|
191
|
+
# @display bg_color #eee
|
|
189
192
|
class FooComponentPreview < ViewComponent::Preview
|
|
190
193
|
|
|
191
|
-
# @display max_width
|
|
194
|
+
# @display max_width 500px
|
|
192
195
|
# @display wrapper true
|
|
193
196
|
def default
|
|
194
197
|
end
|
|
@@ -198,13 +201,11 @@ end
|
|
|
198
201
|
The `@display` tag can be applied at the preview (class) or at the example (method) level, and takes the following format:
|
|
199
202
|
|
|
200
203
|
```ruby
|
|
201
|
-
|
|
204
|
+
@display <key> <value>
|
|
202
205
|
```
|
|
203
206
|
|
|
204
207
|
- `<key>` must be a valid Ruby hash key name, without quotes or spaces
|
|
205
|
-
- `<value>`
|
|
206
|
-
|
|
207
|
-
> [See below for some examples](#some-display-value-examples) of valid and invalid `@display` values.
|
|
208
|
+
- `<value>` will be parsed using the [Ruby YAML parser](https://yaml.org/YAML_for_ruby.html) to resolve the value
|
|
208
209
|
|
|
209
210
|
These display parameters can then be accessed via the `params` hash in your preview layout using `params[:lookbook][:display][<key>]`:
|
|
210
211
|
|
|
@@ -244,27 +245,7 @@ config.lookbook.preview_display_params = {
|
|
|
244
245
|
|
|
245
246
|
Globally defined display params will be available to all previews. Any preview or example-level `@display` values with the same name will take precedence and override a globally-set one.
|
|
246
247
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
Valid:
|
|
250
|
-
|
|
251
|
-
```ruby
|
|
252
|
-
# @display body_classes "bg-red border border-4 border-green"
|
|
253
|
-
# @display wrap_in_container true
|
|
254
|
-
# @display emojis_to_show 4
|
|
255
|
-
# @display page_title "Special example title"
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
Invalid:
|
|
259
|
-
|
|
260
|
-
```ruby
|
|
261
|
-
# @display body_classes 'bg-red border border-4 border-green' [❌ single quotes]
|
|
262
|
-
# @display wrap_in_container should_wrap [❌ unquoted string, perhaps trying to call a method]
|
|
263
|
-
# @display page title "Special example title" [❌ space in key]
|
|
264
|
-
# @display bg_color #fff [❌ colors need quotes around them, it's not CSS!]
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### 🔖 `@!group <name> ... @!endgroup`
|
|
248
|
+
<h3 id="group-tag">🔖 `@!group ... @!endgroup`</h3>
|
|
268
249
|
|
|
269
250
|
For smaller components, it can often make sense to render a set of preview examples in a single window, rather than representing them as individual items in the navigation which can start to look a bit cluttered.
|
|
270
251
|
|
|
@@ -310,6 +291,167 @@ The example above would display the `Sizes` examples grouped together on a singl
|
|
|
310
291
|
|
|
311
292
|
You can have as many groups as you like within a single preview class, but each example can only belong to one group.
|
|
312
293
|
|
|
294
|
+
<h3 id="hidden-tag">🏷 `@hidden`</h3>
|
|
295
|
+
|
|
296
|
+
Used to temporarily exclude an item from the Lookbook navigation. The item will still be accessible via it's URL.
|
|
297
|
+
|
|
298
|
+
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.
|
|
299
|
+
|
|
300
|
+
> Available for both preview classes & example methods.
|
|
301
|
+
|
|
302
|
+
```ruby
|
|
303
|
+
# @hidden
|
|
304
|
+
class FooComponentPreview < ViewComponent::Preview
|
|
305
|
+
|
|
306
|
+
# @hidden
|
|
307
|
+
def default
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
<h3 id="param-tag"> 🚧 @param (experimental)</h3>
|
|
313
|
+
|
|
314
|
+
> ⚠️ This feature is currently flagged as an **experimental** feature which requires [feature opt-in](#experimental-features) to use. Its API and implementation may change in the future.
|
|
315
|
+
|
|
316
|
+
The `@param` tag provides the ability to specify **editable preview parameters** which can be changed in the Lookbook UI in order to customise the rendered output on the fly, much like the [Controls (knobs) addon](https://storybook.js.org/addons/@storybook/addon-controls) for Storybook.
|
|
317
|
+
|
|
318
|
+
Each `@param` will have an associated form field generated for it. The values for each field will be handled as [dynamic preview params](https://viewcomponent.org/guide/previews.html#:~:text=It%E2%80%99s%20also%20possible%20to%20set%20dynamic%20values%20from%20the%20params%20by%20setting%20them%20as%20arguments%3A) when rendering the example.
|
|
319
|
+
|
|
320
|
+
The `@param` tag takes the following format:
|
|
321
|
+
|
|
322
|
+
```ruby
|
|
323
|
+
@param <name> <input_type> <opts?>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
- `<name>` - name of the dynamic preview param
|
|
327
|
+
- `<input_type>` - input field type to generate in the UI
|
|
328
|
+
- `<opts?>` - YAML-encoded field options, used for some field types
|
|
329
|
+
|
|
330
|
+
#### Input types
|
|
331
|
+
|
|
332
|
+
The following **input field types** are available for use:
|
|
333
|
+
|
|
334
|
+
📝 **Text-style inputs** - Single line fields, useful for short strings of text or numbers.
|
|
335
|
+
|
|
336
|
+
```ruby
|
|
337
|
+
@param <name> text
|
|
338
|
+
@param <name> email
|
|
339
|
+
@param <name> number
|
|
340
|
+
@param <name> url
|
|
341
|
+
@param <name> tel
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
> The above types only differ in the validation constraints they impose on the input field.
|
|
345
|
+
|
|
346
|
+
📝 **Textarea** - Multi-line textarea field for longer-form content.
|
|
347
|
+
|
|
348
|
+
```ruby
|
|
349
|
+
@param <name> textarea
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
📝 **Select box** - Dropdown select field for selecting from a list of known options.
|
|
353
|
+
|
|
354
|
+
```ruby
|
|
355
|
+
@param <name> select <options>
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
`<options>` should be a [YAML array](https://yaml.org/YAML_for_ruby.html#simple_inline_array) of options which must be formatted in the same style as the input for Rails' [`options_for_select`](https://apidock.com/rails/v6.0.0/ActionView/Helpers/FormOptionsHelper/options_for_select) helper:
|
|
359
|
+
|
|
360
|
+
```ruby
|
|
361
|
+
# Basic options:
|
|
362
|
+
# @param theme select [primary, secondary, danger]
|
|
363
|
+
|
|
364
|
+
# With custom labels (each item itself an array of [label, value]):
|
|
365
|
+
# @param theme select [[Primary theme, primary], [Secondary theme, secondary], [Danger theme, danger]]
|
|
366
|
+
|
|
367
|
+
# With empty option (`~` in YAML)
|
|
368
|
+
# @param theme select [~, primary, secondary, danger]
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
> **Note**: In most cases YAML does not require quoting of strings, however if you are running into issues check out the [Ruby YAML docs](https://yaml.org/YAML_for_ruby.html) for a complete syntax reference.
|
|
372
|
+
|
|
373
|
+
📝 **Toggle** - On/off switch for toggling boolean values.
|
|
374
|
+
|
|
375
|
+
```ruby
|
|
376
|
+
@param <name> toggle
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
#### Default values
|
|
380
|
+
|
|
381
|
+
Default values are specified as part of the preview example method parameters in the usual Ruby way:
|
|
382
|
+
|
|
383
|
+
```ruby
|
|
384
|
+
def button(content: "Click me", theme: "primary", arrow: false)
|
|
385
|
+
# ...
|
|
386
|
+
end
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
These will be used as the default values for the param fields.
|
|
390
|
+
|
|
391
|
+
> Note that the default values are **not** evaluated at runtime, so you cannot use method calls to generate the defaults. Only static default values are supported.
|
|
392
|
+
|
|
393
|
+
#### Type casting values
|
|
394
|
+
|
|
395
|
+
Most dynamic param values are passed to the example method as strings, with the following exceptions:
|
|
396
|
+
|
|
397
|
+
- `toggle` input - values are cast to booleans
|
|
398
|
+
- `number` input - values are cast to integers
|
|
399
|
+
|
|
400
|
+
In some cases, you may want to type cast the parameter value to something else (for example a `Symbol`) before using it when initializing the component.
|
|
401
|
+
|
|
402
|
+
To help with this, a `type` option can be specified in the `@param` definition to automatically cast the dynamic value to a different type:
|
|
403
|
+
|
|
404
|
+
```ruby
|
|
405
|
+
# @param <name> [<type>] <input_type> <opts?>
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
In the example below, the value of the `theme` param (by default a string) will be automatically cast to a Symbol, ready for use in instantiating the component.
|
|
409
|
+
|
|
410
|
+
```ruby
|
|
411
|
+
# @param theme [Symbol] select [primary, secondary, danger]
|
|
412
|
+
def default(theme: :primary)
|
|
413
|
+
render Elements::ButtonComponent.new(theme: theme) do
|
|
414
|
+
"Click me"
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
The supported types to cast to are:
|
|
420
|
+
|
|
421
|
+
- `String` - *default for all except `toggle` inputs*
|
|
422
|
+
- `Boolean` - *default for `toggle` inputs*
|
|
423
|
+
- `Symbol`
|
|
424
|
+
- `Date`
|
|
425
|
+
- `DateTime`
|
|
426
|
+
- `Integer`
|
|
427
|
+
- `Float`
|
|
428
|
+
|
|
429
|
+
The following structured types are also available but should be considered **experimental** - you may run into bugs!
|
|
430
|
+
|
|
431
|
+
- `Hash` - *value string converted to Hash using the Ruby YAML parser*
|
|
432
|
+
- `Array` - *value string converted to Array using the Ruby YAML parser*
|
|
433
|
+
|
|
434
|
+
#### Full example:
|
|
435
|
+
|
|
436
|
+
```ruby
|
|
437
|
+
class ButtonComponentPreview < ViewComponent::Preview
|
|
438
|
+
|
|
439
|
+
# The params defined below will be editable in the UI:
|
|
440
|
+
#
|
|
441
|
+
# @param content text
|
|
442
|
+
# @param theme select [primary, secondary, danger]
|
|
443
|
+
# @param arrow toggle
|
|
444
|
+
def default(content: "Click me", theme: "primary", arrow: true)
|
|
445
|
+
render Elements::ButtonComponent.new(theme: theme, arrow: arrow) do
|
|
446
|
+
content
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
end
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
<img src=".github/assets/dynamic_params.png">
|
|
454
|
+
|
|
313
455
|
### Adding notes
|
|
314
456
|
|
|
315
457
|
All comment text other than tags will be treated as markdown and rendered in the **Notes** panel for that example in the Lookbook UI.
|
|
@@ -352,6 +494,33 @@ If you wish to add additional paths to listen for changes in, you can use the `l
|
|
|
352
494
|
config.lookbook.listen_paths << Rails.root.join('app/other/directory')
|
|
353
495
|
```
|
|
354
496
|
|
|
497
|
+
<h3 id="experimental-features">Experimental features opt-in</h3>
|
|
498
|
+
|
|
499
|
+
Some features may occasionally be released behind a 'experimental' feature flag while they are being tested and refined, to allow people to try them out and provide feedback.
|
|
500
|
+
|
|
501
|
+
> ⚠️ **Please note:** Experimental features should be considered to be **subject to extensive change** and breaking changes to them may be made within point releases - these features are **not** considered to be covered by [semver](https://semver.org/) whilst flagged as 'experimental'. ⚠️
|
|
502
|
+
|
|
503
|
+
#### Opting into specific features (recommended)
|
|
504
|
+
|
|
505
|
+
To opt into individual experimental features, include the name of the feature in the `experimental_features` config option:
|
|
506
|
+
|
|
507
|
+
```ruby
|
|
508
|
+
config.lookbook.experimental_features = ["feature_name"]
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
The current experimental features that can be opted into are:
|
|
512
|
+
|
|
513
|
+
- `params`: Live-editable, dynamic preview parameters ([read more](#param-tag)). Include `"params"` in the `experimental_features` config option to opt in.
|
|
514
|
+
|
|
515
|
+
#### Opting into all experimental features (not recommended!)
|
|
516
|
+
|
|
517
|
+
If you want to live life on the bleeding-edge you can opt-in to all current **and future** experimental features (usual caveats apply):
|
|
518
|
+
|
|
519
|
+
```ruby
|
|
520
|
+
config.lookbook.experimental_features = true
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
|
|
355
524
|
## Keyboard shortcuts
|
|
356
525
|
|
|
357
526
|
Lookbook provides a few keyboard shortcuts to help you quickly move around the UI.
|
|
@@ -35,14 +35,6 @@
|
|
|
35
35
|
fill: none;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
.h-fill {
|
|
39
|
-
height: fill-available;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.min-h-fill {
|
|
43
|
-
min-height: fill-available;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
38
|
::-webkit-scrollbar {
|
|
47
39
|
width: 8px;
|
|
48
40
|
height: 8px;
|
|
@@ -63,3 +55,67 @@
|
|
|
63
55
|
@apply bg-gray-400;
|
|
64
56
|
}
|
|
65
57
|
}
|
|
58
|
+
|
|
59
|
+
@layer components {
|
|
60
|
+
#nav > ul > li {
|
|
61
|
+
@apply py-1;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.nav-toggle {
|
|
65
|
+
@apply flex items-center cursor-pointer pr-3 hover:bg-gray-200 hover:bg-opacity-50;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.nav-label {
|
|
69
|
+
@apply truncate w-full whitespace-nowrap text-left select-none;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.code {
|
|
73
|
+
@apply font-mono;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.code pre {
|
|
77
|
+
@apply block;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.code .line {
|
|
81
|
+
@apply flex items-center leading-relaxed;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.code.numbered {
|
|
85
|
+
@apply relative pt-3;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.code.numbered:before {
|
|
89
|
+
content: "";
|
|
90
|
+
left: calc(2.7em + 8px);
|
|
91
|
+
@apply absolute top-0 bottom-0 border-r border-gray-200;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.code .line-number {
|
|
95
|
+
width: calc(2.7em + 8px);
|
|
96
|
+
padding-top: 3px;
|
|
97
|
+
padding-bottom: 3px;
|
|
98
|
+
padding-right: 8px;
|
|
99
|
+
margin-right: 16px;
|
|
100
|
+
@apply font-mono text-right text-gray-400 flex-none text-xs;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.code .line-content {
|
|
104
|
+
@apply flex-none pr-4;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* .code .line:before {
|
|
108
|
+
content: counter(line);
|
|
109
|
+
width: calc(3em + 8px);
|
|
110
|
+
padding-top: 2px;
|
|
111
|
+
padding-bottom: 2px;
|
|
112
|
+
padding-right: 8px;
|
|
113
|
+
@apply font-mono inline-block text-right mr-4 text-gray-400 border-r border-gray-200;
|
|
114
|
+
} */
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@layer utilities {
|
|
118
|
+
.form-input {
|
|
119
|
+
@apply border-gray-300 text-gray-700 focus:ring-indigo-300 focus:border-indigo-300 rounded-sm text-sm w-full;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -1,64 +1,54 @@
|
|
|
1
1
|
import { install } from "@github/hotkey";
|
|
2
2
|
import Alpine from "alpinejs";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import nav from "./nav";
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
|
|
3
|
+
import Persist from "@alpinejs/persist";
|
|
4
|
+
import Morph from "@alpinejs/morph";
|
|
5
|
+
import Tooltip from "@ryangjchandler/alpine-tooltip";
|
|
6
|
+
|
|
7
|
+
import page from "./components/page";
|
|
8
|
+
import inspector from "./components/inspector";
|
|
9
|
+
import previewWindow from "./components/preview-window";
|
|
10
|
+
import filter from "./components/filter";
|
|
11
|
+
import param from "./components/param";
|
|
12
|
+
import nav from "./components/nav";
|
|
13
|
+
import navItem from "./components/nav-item";
|
|
14
|
+
import navGroup from "./components/nav-group";
|
|
15
|
+
import splitter from "./components/splitter";
|
|
16
|
+
import copy from "./components/copy";
|
|
17
|
+
import sizes from "./components/sizes";
|
|
18
|
+
|
|
19
|
+
import initFilterStore from "./stores/filter";
|
|
20
|
+
import initLayoutStore from "./stores/layout";
|
|
21
|
+
import initNavStore from "./stores/nav";
|
|
22
|
+
import initSidebarStore from "./stores/sidebar";
|
|
23
|
+
import initInspectorStore from "./stores/inspector";
|
|
20
24
|
|
|
21
25
|
// Plugins
|
|
22
26
|
|
|
23
|
-
Alpine.plugin(
|
|
24
|
-
Alpine.plugin(
|
|
25
|
-
Alpine.plugin(
|
|
26
|
-
Alpine.plugin(Screen);
|
|
27
|
+
Alpine.plugin(Persist);
|
|
28
|
+
Alpine.plugin(Morph);
|
|
29
|
+
Alpine.plugin(Tooltip);
|
|
27
30
|
|
|
28
31
|
// Stores
|
|
29
32
|
|
|
30
|
-
Alpine.store("
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Alpine.persistedStore("nav", {
|
|
36
|
-
width: 280,
|
|
37
|
-
filter: "",
|
|
38
|
-
open: {},
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
Alpine.persistedStore("inspector", {
|
|
42
|
-
height: 200,
|
|
43
|
-
active: "source",
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
Alpine.persistedStore("preview", {
|
|
47
|
-
width: "100%",
|
|
48
|
-
});
|
|
33
|
+
Alpine.store("filter", initFilterStore(Alpine));
|
|
34
|
+
Alpine.store("layout", initLayoutStore(Alpine));
|
|
35
|
+
Alpine.store("nav", initNavStore(Alpine));
|
|
36
|
+
Alpine.store("sidebar", initSidebarStore(Alpine));
|
|
37
|
+
Alpine.store("inspector", initInspectorStore(Alpine));
|
|
49
38
|
|
|
50
|
-
// Components
|
|
39
|
+
// Components
|
|
51
40
|
|
|
52
41
|
Alpine.data("page", page);
|
|
53
|
-
Alpine.data("
|
|
54
|
-
Alpine.data("
|
|
55
|
-
Alpine.data("
|
|
56
|
-
Alpine.data("workbench", workbench);
|
|
57
|
-
Alpine.data("preview", preview);
|
|
42
|
+
Alpine.data("splitter", splitter);
|
|
43
|
+
Alpine.data("previewWindow", previewWindow);
|
|
44
|
+
Alpine.data("copy", copy);
|
|
58
45
|
Alpine.data("inspector", inspector);
|
|
59
|
-
Alpine.data("
|
|
60
|
-
Alpine.data("
|
|
61
|
-
Alpine.data("
|
|
46
|
+
Alpine.data("filter", filter);
|
|
47
|
+
Alpine.data("param", param);
|
|
48
|
+
Alpine.data("sizes", sizes);
|
|
49
|
+
Alpine.data("nav", nav);
|
|
50
|
+
Alpine.data("navItem", navItem);
|
|
51
|
+
Alpine.data("navGroup", navGroup);
|
|
62
52
|
|
|
63
53
|
// Init
|
|
64
54
|
|
|
@@ -66,9 +56,5 @@ for (const el of document.querySelectorAll("[data-hotkey]")) {
|
|
|
66
56
|
install(el);
|
|
67
57
|
}
|
|
68
58
|
|
|
69
|
-
if (window.SOCKET_PATH) {
|
|
70
|
-
reloader(window.SOCKET_PATH).start();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
59
|
window.Alpine = Alpine;
|
|
74
60
|
Alpine.start();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default function copy(id) {
|
|
2
|
+
return {
|
|
3
|
+
get content() {
|
|
4
|
+
const target = document.getElementById(id);
|
|
5
|
+
return (target ? target.innerHTML : "").trim();
|
|
6
|
+
},
|
|
7
|
+
done: false,
|
|
8
|
+
async save() {
|
|
9
|
+
await window.navigator.clipboard.writeText(this.content);
|
|
10
|
+
this.done = true;
|
|
11
|
+
setTimeout(() => {
|
|
12
|
+
this.done = false;
|
|
13
|
+
}, 1000);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export default function filter() {
|
|
2
|
+
return {
|
|
3
|
+
get active() {
|
|
4
|
+
return this.$store.filter.active;
|
|
5
|
+
},
|
|
6
|
+
checkEsc($event) {
|
|
7
|
+
if ($event.key === "Escape") {
|
|
8
|
+
this.active ? this.clear() : this.blur();
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
clear() {
|
|
12
|
+
this.$store.filter.raw = "";
|
|
13
|
+
},
|
|
14
|
+
focus($event) {
|
|
15
|
+
if ($event.target.tagName === "INPUT") {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
setTimeout(() => this.$refs.input.focus(), 0);
|
|
19
|
+
},
|
|
20
|
+
blur() {
|
|
21
|
+
setTimeout(() => this.$refs.input.blur(), 0);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default function inspector() {
|
|
2
|
+
return {
|
|
3
|
+
isActivePanel(panel) {
|
|
4
|
+
return this.$store.inspector.panels.active == panel;
|
|
5
|
+
},
|
|
6
|
+
switchPanel(panel) {
|
|
7
|
+
this.$store.inspector.panels.active = panel;
|
|
8
|
+
},
|
|
9
|
+
get showSource() {
|
|
10
|
+
return this.$store.inspector.preview.source;
|
|
11
|
+
},
|
|
12
|
+
toggleSource() {
|
|
13
|
+
this.$store.inspector.preview.source =
|
|
14
|
+
!this.$store.inspector.preview.source;
|
|
15
|
+
},
|
|
16
|
+
preview: {
|
|
17
|
+
width: null,
|
|
18
|
+
height: null,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|