lookbook 0.8.2 → 1.0.0.beta.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +43 -830
  3. data/app/assets/lookbook/css/lookbook.css +55 -0
  4. data/app/assets/lookbook/css/themes/blue.css +42 -0
  5. data/app/assets/lookbook/css/themes/indigo.css +42 -0
  6. data/app/assets/lookbook/css/themes/zinc.css +42 -0
  7. data/app/assets/lookbook/css/{tooltip_theme.css → tooltip.css} +14 -8
  8. data/app/assets/lookbook/js/app.js +64 -61
  9. data/app/assets/lookbook/js/components/clipboard.js +47 -0
  10. data/app/assets/lookbook/js/components/tooltip.js +30 -0
  11. data/app/assets/lookbook/js/config.js +7 -4
  12. data/app/assets/lookbook/js/helpers/build.js +22 -0
  13. data/app/assets/lookbook/js/helpers/dom.js +45 -0
  14. data/app/assets/lookbook/js/helpers/layout.js +21 -0
  15. data/app/assets/lookbook/js/helpers/request.js +16 -0
  16. data/app/assets/lookbook/js/helpers/string.js +11 -0
  17. data/app/assets/lookbook/js/lib/socket.js +4 -3
  18. data/app/assets/lookbook/js/lib/tippy.js +8 -0
  19. data/app/assets/lookbook/js/lookbook.js +61 -0
  20. data/app/assets/lookbook/js/plugins/logger.js +39 -0
  21. data/app/assets/lookbook/js/stores/filter.js +2 -2
  22. data/app/assets/lookbook/js/stores/inspector.js +22 -16
  23. data/app/assets/lookbook/js/stores/layout.js +101 -5
  24. data/app/assets/lookbook/js/stores/nav.js +17 -16
  25. data/app/assets/lookbook/js/stores/pages.js +4 -2
  26. data/app/assets/lookbook/js/stores/settings.js +7 -0
  27. data/app/assets/lookbook/js/stores/workbench.js +29 -0
  28. data/app/components/lookbook/button/component.html.erb +28 -0
  29. data/app/components/lookbook/button/component.js +55 -0
  30. data/app/components/lookbook/button/component.rb +39 -0
  31. data/app/components/lookbook/button_group/component.html.erb +3 -0
  32. data/app/components/lookbook/button_group/component.rb +18 -0
  33. data/app/components/lookbook/code/component.css +57 -0
  34. data/app/components/lookbook/code/component.html.erb +10 -0
  35. data/app/components/lookbook/code/component.js +3 -0
  36. data/app/components/lookbook/code/component.rb +56 -0
  37. data/app/components/lookbook/code/highlight_github_light.css +217 -0
  38. data/app/components/lookbook/component.rb +41 -0
  39. data/app/components/lookbook/copy_button/component.html.erb +11 -0
  40. data/app/components/lookbook/copy_button/component.js +16 -0
  41. data/app/components/lookbook/copy_button/component.rb +23 -0
  42. data/app/components/lookbook/dimensions_display/component.html.erb +10 -0
  43. data/app/components/lookbook/dimensions_display/component.js +30 -0
  44. data/app/components/lookbook/dimensions_display/component.rb +18 -0
  45. data/app/components/lookbook/embed/component.html.erb +50 -0
  46. data/app/components/lookbook/embed/component.js +39 -0
  47. data/app/components/lookbook/embed/component.rb +22 -0
  48. data/app/components/lookbook/filter/component.html.erb +17 -0
  49. data/app/components/lookbook/filter/component.js +21 -0
  50. data/app/components/lookbook/filter/component.rb +15 -0
  51. data/app/components/lookbook/header/component.html.erb +79 -0
  52. data/app/components/lookbook/header/component.rb +9 -0
  53. data/app/components/lookbook/icon/component.css +11 -0
  54. data/app/components/lookbook/icon/component.html.erb +5 -0
  55. data/app/components/lookbook/icon/component.js +5 -0
  56. data/app/components/lookbook/icon/component.rb +23 -0
  57. data/app/components/lookbook/nav/component.html.erb +33 -0
  58. data/app/components/lookbook/nav/component.js +52 -0
  59. data/app/components/lookbook/nav/component.rb +37 -0
  60. data/app/components/lookbook/nav/item/component.html.erb +23 -0
  61. data/app/components/lookbook/nav/item/component.js +66 -0
  62. data/app/components/lookbook/nav/item/component.rb +84 -0
  63. data/app/components/lookbook/params_editor/component.html.erb +3 -0
  64. data/app/components/lookbook/params_editor/component.js +12 -0
  65. data/app/components/lookbook/params_editor/component.rb +11 -0
  66. data/app/components/lookbook/params_editor/field/component.html.erb +50 -0
  67. data/app/components/lookbook/params_editor/field/component.js +36 -0
  68. data/app/components/lookbook/params_editor/field/component.rb +41 -0
  69. data/app/components/lookbook/prose/component.css +12 -0
  70. data/app/components/lookbook/prose/component.html.erb +3 -0
  71. data/app/components/lookbook/prose/component.rb +26 -0
  72. data/app/components/lookbook/split_layout/component.html.erb +13 -0
  73. data/app/components/lookbook/split_layout/component.js +151 -0
  74. data/app/components/lookbook/split_layout/component.rb +11 -0
  75. data/app/components/lookbook/tabbed_content/component.html.erb +5 -0
  76. data/app/components/lookbook/tabbed_content/component.js +21 -0
  77. data/app/components/lookbook/tabbed_content/component.rb +20 -0
  78. data/app/components/lookbook/tabbed_content/section/component.html.erb +8 -0
  79. data/app/components/lookbook/tabbed_content/section/component.rb +9 -0
  80. data/app/components/lookbook/tabs/component.css +8 -0
  81. data/app/components/lookbook/tabs/component.html.erb +14 -0
  82. data/app/components/lookbook/tabs/component.js +107 -0
  83. data/app/components/lookbook/tabs/component.rb +30 -0
  84. data/app/components/lookbook/tabs/dropdown_tab/component.html.erb +14 -0
  85. data/app/components/lookbook/tabs/dropdown_tab/component.rb +16 -0
  86. data/app/components/lookbook/tabs/tab/component.html.erb +18 -0
  87. data/app/components/lookbook/tabs/tab/component.rb +16 -0
  88. data/app/components/lookbook/tag_component.rb +29 -0
  89. data/app/components/lookbook/toolbar/component.css +16 -0
  90. data/app/components/lookbook/toolbar/component.html.erb +5 -0
  91. data/app/components/lookbook/toolbar/component.rb +26 -0
  92. data/app/components/lookbook/viewport/component.css +11 -0
  93. data/app/components/lookbook/viewport/component.html.erb +57 -0
  94. data/app/{assets/lookbook/js/components/preview-window.js → components/lookbook/viewport/component.js} +57 -14
  95. data/app/components/lookbook/viewport/component.rb +21 -0
  96. data/app/controllers/lookbook/application_controller.rb +16 -5
  97. data/app/controllers/lookbook/pages_controller.rb +18 -8
  98. data/app/controllers/lookbook/previews_controller.rb +60 -23
  99. data/app/helpers/lookbook/application_helper.rb +5 -1
  100. data/app/helpers/lookbook/component_helper.rb +22 -10
  101. data/app/helpers/lookbook/output_helper.rb +8 -4
  102. data/app/helpers/lookbook/page_helper.rb +13 -21
  103. data/app/views/layouts/lookbook/application.html.erb +76 -28
  104. data/app/views/layouts/lookbook/inspector.html.erb +7 -0
  105. data/app/views/layouts/lookbook/page.html.erb +53 -0
  106. data/app/views/layouts/lookbook/shell.html.erb +64 -0
  107. data/app/views/layouts/lookbook/skeleton.html.erb +27 -10
  108. data/app/views/layouts/lookbook/standalone.html.erb +5 -0
  109. data/app/views/lookbook/404.html.erb +15 -0
  110. data/app/views/lookbook/error.html.erb +34 -34
  111. data/app/views/lookbook/index.html.erb +11 -6
  112. data/app/views/lookbook/pages/show.html.erb +29 -67
  113. data/app/views/{layouts/lookbook → lookbook}/preview.html.erb +3 -5
  114. data/app/views/lookbook/previews/panels/_notes.html.erb +19 -25
  115. data/app/views/lookbook/previews/panels/_output.html.erb +7 -18
  116. data/app/views/lookbook/previews/panels/_params.html.erb +13 -15
  117. data/app/views/lookbook/previews/panels/_preview.html.erb +6 -52
  118. data/app/views/lookbook/previews/panels/_source.html.erb +7 -16
  119. data/app/views/lookbook/previews/show.html.erb +130 -24
  120. data/config/routes.rb +5 -5
  121. data/lib/lookbook/code_formatter.rb +37 -13
  122. data/lib/lookbook/collection.rb +19 -16
  123. data/lib/lookbook/config.rb +125 -0
  124. data/lib/lookbook/engine.rb +66 -59
  125. data/lib/lookbook/entity.rb +47 -0
  126. data/lib/lookbook/error.rb +1 -2
  127. data/lib/lookbook/features.rb +1 -1
  128. data/lib/lookbook/markdown.rb +3 -4
  129. data/lib/lookbook/page.rb +21 -12
  130. data/lib/lookbook/page_collection.rb +8 -0
  131. data/lib/lookbook/params.rb +14 -3
  132. data/lib/lookbook/preview.rb +15 -6
  133. data/lib/lookbook/preview_collection.rb +8 -0
  134. data/lib/lookbook/preview_controller.rb +6 -2
  135. data/lib/lookbook/preview_example.rb +5 -6
  136. data/lib/lookbook/preview_group.rb +4 -9
  137. data/lib/lookbook/{code_inspector.rb → source_inspector.rb} +2 -2
  138. data/lib/lookbook/theme.rb +22 -0
  139. data/lib/lookbook/utils.rb +10 -2
  140. data/lib/lookbook/version.rb +1 -1
  141. data/lib/lookbook.rb +4 -1
  142. data/lib/tasks/lookbook_tasks.rake +12 -0
  143. data/public/lookbook-assets/css/app.css +2340 -1
  144. data/public/lookbook-assets/css/app.css.map +11 -1
  145. data/public/lookbook-assets/css/lookbook.css +3040 -0
  146. data/public/lookbook-assets/css/lookbook.css.map +1 -0
  147. data/public/lookbook-assets/css/themes/blue.css +44 -0
  148. data/public/lookbook-assets/css/themes/blue.css.map +1 -0
  149. data/public/lookbook-assets/css/themes/indigo.css +44 -0
  150. data/public/lookbook-assets/css/themes/indigo.css.map +1 -0
  151. data/public/lookbook-assets/css/themes/zinc.css +44 -0
  152. data/public/lookbook-assets/css/themes/zinc.css.map +1 -0
  153. data/public/lookbook-assets/js/app.js +10861 -1
  154. data/public/lookbook-assets/js/app.js.map +2571 -1
  155. data/public/lookbook-assets/js/embed.js +895 -1
  156. data/public/lookbook-assets/js/embed.js.map +1 -1
  157. data/public/lookbook-assets/js/lookbook.js +13529 -0
  158. data/public/lookbook-assets/js/lookbook.js.map +1 -0
  159. metadata +127 -114
  160. data/app/assets/lookbook/css/app.css +0 -161
  161. data/app/assets/lookbook/css/code_theme.css +0 -214
  162. data/app/assets/lookbook/js/components/app.js +0 -55
  163. data/app/assets/lookbook/js/components/code.js +0 -5
  164. data/app/assets/lookbook/js/components/copy.js +0 -20
  165. data/app/assets/lookbook/js/components/embed.js +0 -89
  166. data/app/assets/lookbook/js/components/filter.js +0 -35
  167. data/app/assets/lookbook/js/components/inspector.js +0 -66
  168. data/app/assets/lookbook/js/components/nav-group.js +0 -47
  169. data/app/assets/lookbook/js/components/nav-item.js +0 -29
  170. data/app/assets/lookbook/js/components/nav.js +0 -28
  171. data/app/assets/lookbook/js/components/page.js +0 -25
  172. data/app/assets/lookbook/js/components/param.js +0 -34
  173. data/app/assets/lookbook/js/components/sidebar.js +0 -18
  174. data/app/assets/lookbook/js/components/sizes.js +0 -16
  175. data/app/assets/lookbook/js/components/splitter.js +0 -25
  176. data/app/assets/lookbook/js/components/tabs.js +0 -52
  177. data/app/assets/lookbook/js/lib/split.js +0 -15
  178. data/app/assets/lookbook/js/stores/sidebar.js +0 -26
  179. data/app/views/layouts/lookbook/basic.html.erb +0 -7
  180. data/app/views/lookbook/components/_branding.html.erb +0 -8
  181. data/app/views/lookbook/components/_code.html.erb +0 -17
  182. data/app/views/lookbook/components/_copy_button.html.erb +0 -11
  183. data/app/views/lookbook/components/_drawer.html.erb +0 -112
  184. data/app/views/lookbook/components/_embed.html.erb +0 -39
  185. data/app/views/lookbook/components/_errors.html.erb +0 -13
  186. data/app/views/lookbook/components/_filter.html.erb +0 -18
  187. data/app/views/lookbook/components/_header.html.erb +0 -6
  188. data/app/views/lookbook/components/_icon.html.erb +0 -5
  189. data/app/views/lookbook/components/_nav.html.erb +0 -16
  190. data/app/views/lookbook/components/_nav_collection.html.erb +0 -5
  191. data/app/views/lookbook/components/_nav_group.html.erb +0 -14
  192. data/app/views/lookbook/components/_nav_item.html.erb +0 -24
  193. data/app/views/lookbook/components/_nav_page.html.erb +0 -22
  194. data/app/views/lookbook/components/_nav_preview.html.erb +0 -13
  195. data/app/views/lookbook/components/_not_found.html.erb +0 -11
  196. data/app/views/lookbook/components/_param.html.erb +0 -21
  197. data/app/views/lookbook/components/_preview.html.erb +0 -77
  198. data/app/views/lookbook/components/_sidebar.html.erb +0 -69
  199. data/app/views/lookbook/pages/not_found.html.erb +0 -15
  200. data/app/views/lookbook/previews/error.html.erb +0 -1
  201. data/app/views/lookbook/previews/inputs/_select.html.erb +0 -7
  202. data/app/views/lookbook/previews/inputs/_text.html.erb +0 -8
  203. data/app/views/lookbook/previews/inputs/_textarea.html.erb +0 -8
  204. data/app/views/lookbook/previews/inputs/_toggle.html.erb +0 -13
  205. data/app/views/lookbook/previews/not_found.html.erb +0 -23
@@ -0,0 +1,61 @@
1
+ import Alpine from "alpinejs";
2
+
3
+ import Morph from "@alpinejs/morph";
4
+ import Persist from "@alpinejs/persist";
5
+ import Collapse from "@alpinejs/morph";
6
+ import Tooltip from "@ryangjchandler/alpine-tooltip";
7
+
8
+ import Logger, { log } from "./plugins/logger";
9
+
10
+ import initLayoutStore from "./stores/layout";
11
+ import initNavStore from "./stores/nav";
12
+ import initInspectorStore from "./stores/inspector";
13
+ import initPagesStore from "./stores/pages";
14
+ import initSettingsStore from "./stores/settings";
15
+ import initWorkbenchStore from "./stores/workbench";
16
+
17
+ import app from "./app";
18
+
19
+ // Note: A ParcelJS issue prevents loading all depths of component JS files in one glob,
20
+ // so need to split it up. Path aliases also do not work with the glob imports.
21
+ import { getComponents } from "./helpers/build";
22
+ import * as components from "../../../components/lookbook/*/component.js";
23
+ import * as subComponents from "../../../components/lookbook/*/*/component.js";
24
+ import * as jsComponents from "./components/*.js";
25
+
26
+ // Plugins
27
+
28
+ Alpine.plugin(Morph);
29
+ Alpine.plugin(Persist);
30
+ Alpine.plugin(Collapse);
31
+ Alpine.plugin(Tooltip);
32
+ Alpine.plugin(Logger);
33
+
34
+ // Stores
35
+ const prefix = window.APP_NAME;
36
+ Alpine.store("layout", initLayoutStore(Alpine, { prefix }));
37
+ Alpine.store("nav", initNavStore(Alpine, { prefix }));
38
+ Alpine.store("inspector", initInspectorStore(Alpine, { prefix }));
39
+ Alpine.store("pages", initPagesStore(Alpine, { prefix }));
40
+ Alpine.store("settings", initSettingsStore(Alpine, { prefix }));
41
+
42
+ if (process.env.NODE_ENV !== "production") {
43
+ Alpine.store("workbench", initWorkbenchStore(Alpine, { prefix }));
44
+ }
45
+
46
+ // Components
47
+
48
+ Alpine.data("app", app);
49
+
50
+ [components, subComponents, jsComponents].forEach((scripts) => {
51
+ const components = getComponents(scripts);
52
+ Object.keys(components).forEach((name) => {
53
+ Alpine.data(`${name}Component`, components[name]);
54
+ });
55
+ });
56
+
57
+ // Init
58
+
59
+ window.log = log;
60
+ window.Alpine = Alpine;
61
+ Alpine.start();
@@ -0,0 +1,39 @@
1
+ import log from "loglevel";
2
+ import logPrefix from "loglevel-plugin-prefix";
3
+
4
+ logPrefix.reg(log);
5
+ logPrefix.apply(log, {
6
+ format: (level) => `${`[${level}]`.padStart(7)} Lookbook:`,
7
+ });
8
+
9
+ let logLevel = process.env.NODE_ENV === "development" ? 2 : 3;
10
+ if (window.LOG_LEVEL !== undefined) {
11
+ logLevel = window.LOG_LEVEL;
12
+ }
13
+ log.setLevel(logLevel);
14
+
15
+ export default function loggerPlugin(Alpine) {
16
+ Alpine.directive(
17
+ "log",
18
+ (el, { modifiers, expression }, { evaluateLater, effect }) => {
19
+ let logFn =
20
+ typeof expression === "string"
21
+ ? (callback) => callback(expression)
22
+ : evaluateLater(expression);
23
+ effect(() =>
24
+ logFn((message) => {
25
+ const level = modifiers[0] || "debug";
26
+ log[level](message);
27
+ })
28
+ );
29
+ }
30
+ );
31
+
32
+ Alpine.magic("log", () => {
33
+ return log;
34
+ });
35
+
36
+ Alpine.$log = log;
37
+ }
38
+
39
+ export { log };
@@ -1,6 +1,6 @@
1
- export default function createFilterStore(Alpine) {
1
+ export default function initFilterStore(Alpine, name) {
2
2
  return {
3
- raw: Alpine.$persist("").as("filter-text"),
3
+ raw: Alpine.$persist("").as(name),
4
4
  get text() {
5
5
  return this.raw.replace(/\s/g, "").toLowerCase();
6
6
  },
@@ -1,25 +1,31 @@
1
- import config from "../config";
1
+ import { prefixString } from "../helpers/string";
2
2
 
3
- export default function createInspectorStore(Alpine) {
4
- const { drawer, preview } = config.inspector;
3
+ export default function initInspectorStore(Alpine, { prefix }) {
5
4
  return {
6
- drawer: {
7
- hidden: Alpine.$persist(false).as("drawer-hidden"),
8
- orientation: Alpine.$persist(drawer.orientation).as("drawer-orientation"),
9
- panel: Alpine.$persist(drawer.defaultPanel).as("drawer-panel"),
10
- height: Alpine.$persist(drawer.defaultHeight).as("drawer-height"),
11
- width: Alpine.$persist(drawer.defaultWidth).as("drawer-width"),
12
- minWidth: drawer.minWidth,
13
- minHeight: drawer.minHeight,
14
- visibleTabCount: Infinity,
15
- },
5
+ minVerticalSplitWidth: 800,
6
+
16
7
  preview: {
17
- width: Alpine.$persist("100%").as("preview-width"),
18
- height: Alpine.$persist("100%").as("preview-height"),
19
- panel: Alpine.$persist(preview.defaultPanel).as("preview-panel"),
8
+ activeTab: Alpine.$persist("").as(
9
+ prefixString("inspector-preview-active-tab", prefix)
10
+ ),
11
+ width: Alpine.$persist("100%").as(
12
+ prefixString("inspector-preview-width", prefix)
13
+ ),
14
+ height: Alpine.$persist("100%").as(
15
+ prefixString("inspector-preview-height", prefix)
16
+ ),
20
17
  lastWidth: null,
21
18
  lastHeight: null,
22
19
  resizing: false,
23
20
  },
21
+
22
+ drawer: {
23
+ hidden: Alpine.$persist(false).as(
24
+ prefixString("inspector-drawer-hidden", prefix)
25
+ ),
26
+ activeTab: Alpine.$persist("").as(
27
+ prefixString("inspector-drawer-active-tab", prefix)
28
+ ),
29
+ },
24
30
  };
25
31
  }
@@ -1,15 +1,111 @@
1
1
  import config from "../config";
2
+ import { addMediaQueryListener } from "../helpers/layout";
3
+ import { log } from "../plugins/logger";
4
+ import { prefixString } from "../helpers/string";
2
5
 
3
- export default function createLayoutStore() {
6
+ const { sidebar, main, inspector } = config;
7
+
8
+ export default function initLayoutStore(Alpine, { prefix }) {
4
9
  return {
5
10
  init() {
6
- this.desktop = window.innerWidth >= config.desktopWidth;
11
+ addMediaQueryListener(
12
+ `(min-width: ${config.desktopWidth}px)`,
13
+ (matches) => {
14
+ this._isDesktop = matches;
15
+ log.debug(
16
+ `Media query 'desktop': ${matches ? "✅ match" : "❌ no match"}`
17
+ );
18
+ }
19
+ );
7
20
  },
8
- reflowing: false,
9
- desktop: true,
10
- desktopWidth: config.desktopWidth,
21
+
22
+ get desktop() {
23
+ return this._isDesktop;
24
+ },
25
+
11
26
  get mobile() {
12
27
  return !this.desktop;
13
28
  },
29
+
30
+ reflowing: false,
31
+
32
+ // Main app sidebar/content layout
33
+ main: {
34
+ split: Alpine.$persist({
35
+ direction: "vertical",
36
+ sizes: [`${sidebar.defaultWidth}px`, "1fr"],
37
+ }).as(prefixString("main-split", prefix)),
38
+
39
+ opts: {
40
+ minSizes: [sidebar.minWidth, main.minWidth],
41
+ },
42
+ },
43
+
44
+ // Sidebar visibility and sections
45
+ sidebar: {
46
+ _hiddenDesktop: Alpine.$persist(false).as(
47
+ prefixString("sidebar-hidden-desktop", prefix)
48
+ ),
49
+
50
+ _hiddenMobile: Alpine.$persist(true).as(
51
+ prefixString("sidebar-hidden-mobile", prefix)
52
+ ),
53
+
54
+ set hidden(value) {
55
+ if (Alpine.store("layout").desktop) {
56
+ this._hiddenDesktop = value;
57
+ } else {
58
+ this._hiddenMobile = value;
59
+ }
60
+ },
61
+
62
+ get hidden() {
63
+ const isDesktop = Alpine.store("layout").desktop;
64
+ return (
65
+ (isDesktop && this._hiddenDesktop) ||
66
+ (!isDesktop && this._hiddenMobile)
67
+ );
68
+ },
69
+
70
+ split: Alpine.$persist({
71
+ direction: "horizontal",
72
+ sizes: ["50%", "50%"],
73
+ }).as(prefixString("sidebar-split", prefix)),
74
+
75
+ opts: {
76
+ minSizes: [sidebar.minSectionHeight, sidebar.minSectionHeight],
77
+ },
78
+ },
79
+
80
+ singleSectionSidebar: {
81
+ split: {
82
+ direction: "horizontal",
83
+ sizes: null,
84
+ },
85
+ },
86
+
87
+ // Inspector drawer/preview layout
88
+ inspector: {
89
+ split: Alpine.$persist({
90
+ direction: "horizontal",
91
+ horizontalSizes: ["1fr", `${inspector.drawer.defaultHeight}px`],
92
+ verticalSizes: ["1fr", `${inspector.drawer.defaultWidth}px`],
93
+ }).as(prefixString("inspector-split", prefix)),
94
+
95
+ opts: {
96
+ minVerticalSizes: [
97
+ inspector.drawer.minWidth,
98
+ inspector.drawer.minWidth,
99
+ ],
100
+ minHorizontalSizes: [
101
+ inspector.drawer.minHeight,
102
+ inspector.drawer.minHeight,
103
+ ],
104
+ },
105
+ },
106
+
107
+ // protected
108
+
109
+ _isDesktop: true,
14
110
  };
15
111
  }
@@ -1,21 +1,22 @@
1
- export default function createNavStore(Alpine) {
1
+ import initFilterStore from "./filter";
2
+ import { prefixString } from "../helpers/string";
3
+
4
+ export default function initNavStore(Alpine, { prefix }) {
2
5
  return {
3
- open: Alpine.$persist([]).as("nav-open"),
4
- active: Alpine.$persist(null).as("nav-active"),
5
- isOpen(id) {
6
- return this.open.includes(id);
6
+ previews: {
7
+ filter: initFilterStore(
8
+ Alpine,
9
+ prefixString("previews-filter-text", prefix)
10
+ ),
11
+ open: Alpine.$persist([]).as(prefixString("previews-nav-open", prefix)),
7
12
  },
8
- setOpen(id) {
9
- this.open.push(id);
10
- },
11
- setClosed(id) {
12
- const index = this.open.indexOf(id);
13
- if (index > -1) {
14
- this.open.splice(index, 1);
15
- }
16
- },
17
- toggle(id) {
18
- this.isOpen(id) ? this.setClosed(id) : this.setOpen(id);
13
+
14
+ pages: {
15
+ filter: initFilterStore(
16
+ Alpine,
17
+ prefixString("pages-filter-text", prefix)
18
+ ),
19
+ open: Alpine.$persist([]).as(prefixString("pages-nav-open", prefix)),
19
20
  },
20
21
  };
21
22
  }
@@ -1,5 +1,7 @@
1
- export default function createNavStore(Alpine) {
1
+ import { prefixString } from "../helpers/string";
2
+
3
+ export default function initPagesStore(Alpine, { prefix }) {
2
4
  return {
3
- embeds: {},
5
+ embeds: Alpine.$persist({}).as(prefixString("pages-embeds", prefix)),
4
6
  };
5
7
  }
@@ -0,0 +1,7 @@
1
+ import { prefixString } from "../helpers/string";
2
+
3
+ export default function initSettingsStore(Alpine, { prefix }) {
4
+ return {
5
+ showTooltips: true,
6
+ };
7
+ }
@@ -0,0 +1,29 @@
1
+ import initFilterStore from "./filter";
2
+ import { prefixString } from "../helpers/string";
3
+
4
+ export default function initWorkbenchStore(Alpine, { prefix }) {
5
+ return {
6
+ filter: initFilterStore(Alpine, prefixString("workbench-filter", prefix)),
7
+ nav: {
8
+ open: Alpine.$persist([]).as(prefixString("workbench-nav-open", prefix)),
9
+ location: {
10
+ pathname: null,
11
+ },
12
+ },
13
+ horizontalSplitLayout: {
14
+ split: Alpine.$persist({
15
+ direction: "horizontal",
16
+ sizes: ["50%", "50%"],
17
+ }).as(prefixString("workbench-horizontal-split", prefix)),
18
+ },
19
+ verticalSplitLayout: {
20
+ split: Alpine.$persist({
21
+ direction: "vertical",
22
+ sizes: ["40%", "30%", "30%"],
23
+ }).as(prefixString("workbench-vertical-split", prefix)),
24
+ },
25
+ tabbedPanels: {
26
+ activeTab: "tab-1",
27
+ },
28
+ };
29
+ }
@@ -0,0 +1,28 @@
1
+ <%= render_component_tag tag_name,
2
+ href: @href,
3
+ class: [
4
+ "block text-lookbook-button-text focus:outline-none focus-visible:outline-none #{padding}",
5
+ {
6
+ "hover:text-lookbook-button-text-hover": !@disabled,
7
+ "cursor-[not-allowed] opacity-50": @disabled
8
+ }
9
+ ],
10
+ disabled: @disabled,
11
+ "@keydown.esc.stop": "hideDropdown" do %>
12
+ <span x-ref="icon">
13
+ <%= icon || render_component(:icon, name: @icon, size: icon_size, ":class": "{'animate-spin': _spinning}") %>
14
+ </span>
15
+ <% if @tooltip %>
16
+ <label class="hidden" x-ref="tooltip"><%= @tooltip %></label>
17
+ <% end %>
18
+ <% if content %>
19
+ <div x-ref="content"><%== content %></div>
20
+ <% end %>
21
+ <% if dropdown %>
22
+ <div class="hidden" x-ref="dropdown">
23
+ <div class="bg-white divide-y divide-lookbook-divider text-left">
24
+ <%== dropdown %>
25
+ </div>
26
+ </div>
27
+ <% end %>
28
+ <% end %>
@@ -0,0 +1,55 @@
1
+ import tippy from "~/app/assets/lookbook/js/lib/tippy";
2
+ import { initTooltip } from "~/app/assets/lookbook/js/components/tooltip";
3
+
4
+ export default function buttonComponent() {
5
+ let tooltip = null;
6
+ let dropdown = null;
7
+
8
+ return {
9
+ init() {
10
+ if (this.$refs.tooltip) {
11
+ tooltip = initTooltip(this, {
12
+ target: this.$refs.icon,
13
+ });
14
+ }
15
+
16
+ if (this.$refs.dropdown) {
17
+ dropdown = tippy(this.$el, {
18
+ content: this.$refs.dropdown.innerHTML,
19
+ trigger: "click",
20
+ theme: "menu",
21
+ triggerTarget: this.$el,
22
+ interactive: true,
23
+ zIndex: 99999,
24
+ onShow: () => {
25
+ if (!this.$store.settings.showTooltips) {
26
+ return false;
27
+ }
28
+ this.$dispatch("dropdown:show", { dropdown: this });
29
+ },
30
+ onHide: () => this.$dispatch("dropdown:hide", { dropdown: this }),
31
+ });
32
+ }
33
+ },
34
+
35
+ hideDropdown() {
36
+ if (dropdown) {
37
+ dropdown.hide();
38
+ }
39
+ },
40
+
41
+ startSpin() {
42
+ this._spinning = true;
43
+ },
44
+
45
+ stopSpin(delay = 0) {
46
+ setTimeout(() => (this._spinning = false), delay);
47
+ },
48
+
49
+ get _tooltip() {
50
+ return tooltip;
51
+ },
52
+
53
+ _spinning: false,
54
+ };
55
+ }
@@ -0,0 +1,39 @@
1
+ module Lookbook
2
+ class Button::Component < Lookbook::Component
3
+ renders_one :icon, Lookbook::Icon::Component
4
+ renders_one :dropdown
5
+
6
+ ICON_SIZES = {
7
+ sm: 3.5,
8
+ md: 4,
9
+ lg: 6
10
+ }
11
+
12
+ def initialize(icon: nil, tooltip: nil, disabled: false, size: :md, href: nil, **html_attrs)
13
+ @icon = icon
14
+ @tooltip = tooltip
15
+ @disabled = disabled
16
+ @size = size
17
+ @href = href
18
+ super(**html_attrs)
19
+ end
20
+
21
+ def icon_size
22
+ ICON_SIZES[@size]
23
+ end
24
+
25
+ def padding
26
+ @size == :sm ? "p-1" : "p-2"
27
+ end
28
+
29
+ def tag_name
30
+ @href.present? ? :a : :button
31
+ end
32
+
33
+ protected
34
+
35
+ def alpine_component
36
+ "buttonComponent"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ <%= render_component_tag :div, class: "flex items-center" do %>
2
+ <%= safe_join(buttons) %>
3
+ <% end %>
@@ -0,0 +1,18 @@
1
+ module Lookbook
2
+ class ButtonGroup::Component < Lookbook::Component
3
+ renders_many :buttons, ->(copy: nil, **attrs, &block) do
4
+ attrs[:size] = @size
5
+ instance = if copy.present?
6
+ CopyButton::Component.new(target: copy, **attrs)
7
+ else
8
+ Button::Component.new(**attrs)
9
+ end
10
+ render instance, &block
11
+ end
12
+
13
+ def initialize(size: :md, **html_attrs)
14
+ @size = size
15
+ super(**html_attrs)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,57 @@
1
+ @import "./highlight_github_light.css";
2
+
3
+ @layer components {
4
+ [data-component="code"] {
5
+ @apply text-sm px-4 overflow-x-hidden;
6
+
7
+ & .line {
8
+ min-height: 1.625em;
9
+ @apply leading-relaxed;
10
+ }
11
+
12
+ & .code {
13
+ @apply overflow-x-auto overflow-y-hidden py-4;
14
+ }
15
+
16
+ /* Line numbers */
17
+
18
+ &.numbered {
19
+ @apply p-0;
20
+
21
+ & .wrapper {
22
+ grid-template-columns: min-content 1fr;
23
+ @apply grid h-full w-full relative;
24
+ }
25
+
26
+ & .line-numbers {
27
+ width: min-content;
28
+ @apply bg-white border-r border-dashed border-lookbook-divider z-10 h-full p-3 select-none text-gray-400 text-right;
29
+ }
30
+
31
+ & .line-number {
32
+ min-width: 1.4em;
33
+ @apply text-xs block pt-[4px];
34
+ }
35
+
36
+ & .code {
37
+ @apply py-3;
38
+ }
39
+
40
+ & .code .line {
41
+ @apply px-3;
42
+ }
43
+ }
44
+
45
+ /* Focusing on specific lines */
46
+
47
+ &.focussed {
48
+ & .line:not(.highlighted) {
49
+ @apply !opacity-30;
50
+ }
51
+
52
+ & .code .line.highlighted {
53
+ @apply bg-yellow-50;
54
+ }
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,10 @@
1
+ <%= render_component_tag class: [
2
+ "not-prose font-mono #{theme_classname}",
3
+ {
4
+ "numbered": numbered?,
5
+ "focussed": focussed?,
6
+ "h-full": full_height?
7
+ }
8
+ ] do %>
9
+ <%= Lookbook::CodeFormatter.highlight(source, **@highlight_opts) %>
10
+ <% end %>
@@ -0,0 +1,3 @@
1
+ export default function codeComponent() {
2
+ return {};
3
+ }
@@ -0,0 +1,56 @@
1
+ module Lookbook
2
+ class Code::Component < Lookbook::Component
3
+ include Lookbook::OutputHelper
4
+
5
+ def initialize(
6
+ source: nil,
7
+ language: :html,
8
+ line_numbers: false,
9
+ highlight_lines: [],
10
+ start_line: 1,
11
+ wrap: false,
12
+ theme: :github_light,
13
+ full_height: false,
14
+ **html_attrs
15
+ )
16
+ @source_code = source
17
+ @highlight_opts = {
18
+ language: language,
19
+ line_numbers: line_numbers,
20
+ highlight_lines: highlight_lines,
21
+ start_line: start_line
22
+ }
23
+ @highlight_lines = highlight_lines
24
+ @wrap = wrap
25
+ @theme = theme
26
+ @full_height = full_height
27
+ super(**html_attrs)
28
+ end
29
+
30
+ def theme_classname
31
+ "theme-#{@theme.to_s.tr("_", "-")}"
32
+ end
33
+
34
+ def source
35
+ (@source_code || content).strip_heredoc.strip
36
+ end
37
+
38
+ def numbered?
39
+ @highlight_opts[:line_numbers] == true
40
+ end
41
+
42
+ def focussed?
43
+ @highlight_opts[:highlight_lines].any?
44
+ end
45
+
46
+ def full_height?
47
+ @full_height == true
48
+ end
49
+
50
+ protected
51
+
52
+ def alpine_component
53
+ "codeComponent"
54
+ end
55
+ end
56
+ end