tutuca 0.9.111 → 0.9.113

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.
@@ -10,7 +10,9 @@ var Storybook = component({
10
10
  sectionId: null,
11
11
  exampleId: null,
12
12
  focusExample: null,
13
- sidebarCollapsed: false
13
+ sidebarCollapsed: false,
14
+ theme: "",
15
+ themes: []
14
16
  },
15
17
  statics: {
16
18
  withSections(sections) {
@@ -106,6 +108,11 @@ var Storybook = component({
106
108
  onFocusClose(ctx) {
107
109
  ctx.request("persistState", [this.toUrlState({ example: "" }), this, true]);
108
110
  return this.setSectionId(null).setExampleId(null).setFocusExample(null);
111
+ },
112
+ onSelectTheme(value, ctx) {
113
+ ctx.request("applyTheme", [value, this]);
114
+ ctx.request("persistState", [this.toUrlState({ theme: value }), this, false]);
115
+ return this.setTheme(value);
109
116
  }
110
117
  },
111
118
  bubble: {
@@ -149,7 +156,7 @@ var Storybook = component({
149
156
  loadState(state, err, ctx) {
150
157
  if (err || !state)
151
158
  return this;
152
- const selected = this.selectSectionWithId(state.section).setFilter(state.sectionFilter ?? "").applyFilterToSidebar(state.sectionFilter ?? "").setSelectedSectionFilter(state.exampleFilter ?? "");
159
+ const selected = this.selectSectionWithId(state.section).setTheme(state.theme ?? "").setFilter(state.sectionFilter ?? "").applyFilterToSidebar(state.sectionFilter ?? "").setSelectedSectionFilter(state.exampleFilter ?? "");
153
160
  const next = state.example ? selected.focusExampleByIds(state.section, state.example) : selected.setSectionId(null).setExampleId(null).setFocusExample(null);
154
161
  transitionSections(ctx, next, this.selectedSectionIndex, next.selectedSectionIndex);
155
162
  return next;
@@ -195,6 +202,15 @@ var Storybook = component({
195
202
  @on.input="onApplyFilter value"
196
203
  @on.keydown.cancel="onClearFilter"
197
204
  />
205
+ <select
206
+ class="select w-auto"
207
+ title="Theme"
208
+ @hide="empty? .themes"
209
+ :value=".theme"
210
+ @on.input="onSelectTheme value"
211
+ >
212
+ <option @each=".themes" :value="@value" @text="@value"></option>
213
+ </select>
198
214
  </div>
199
215
  <div class="list h-full flex-1 overflow-y-auto">
200
216
  <x render-each=".sidebar" @when="groupVisible"></x>
@@ -729,11 +745,53 @@ async function attachInspectorViews(root, scope, modules, dev = null) {
729
745
  return root.setSections(sections);
730
746
  }
731
747
 
748
+ // src/storybook/themes.js
749
+ var MARGAUI_THEMES = [
750
+ "light",
751
+ "dark",
752
+ "abyss",
753
+ "acid",
754
+ "aqua",
755
+ "autumn",
756
+ "black",
757
+ "bumblebee",
758
+ "business",
759
+ "caramellatte",
760
+ "cmyk",
761
+ "coffee",
762
+ "corporate",
763
+ "cupcake",
764
+ "cyberpunk",
765
+ "dim",
766
+ "dracula",
767
+ "emerald",
768
+ "fantasy",
769
+ "forest",
770
+ "garden",
771
+ "halloween",
772
+ "lemonade",
773
+ "lofi",
774
+ "luxury",
775
+ "night",
776
+ "nord",
777
+ "pastel",
778
+ "retro",
779
+ "silk",
780
+ "sunset",
781
+ "synthwave",
782
+ "valentine",
783
+ "winter",
784
+ "wireframe"
785
+ ];
786
+ var BUNDLED_THEMES = new Set(["light", "dark"]);
787
+
732
788
  // src/storybook/mount.js
733
- async function mountStorybook(selector, modules, { compileCss, root, persistUrl = true, dev = null, noCache = false } = {}) {
789
+ async function mountStorybook(selector, modules, { compileCss, root, persistUrl = true, dev = null, noCache = false, themes = null } = {}) {
734
790
  const app = tutuca(selector);
735
791
  const built = buildStorybook(modules);
736
- app.state.set(root ?? built.root);
792
+ const themeBaseUrl = themes?.baseUrl ?? null;
793
+ const base = root ?? built.root;
794
+ app.state.set(themeBaseUrl && base.setThemes ? base.setThemes(MARGAUI_THEMES) : base);
737
795
  const rootScope = app.registerComponents(built.engineComponents);
738
796
  rootScope.registerMacros(built.macros);
739
797
  rootScope.registerRequestHandlers(buildExampleRequestHandlers(built));
@@ -741,6 +799,9 @@ async function mountStorybook(selector, modules, { compileCss, root, persistUrl
741
799
  if (persistUrl) {
742
800
  rootScope.registerRequestHandlers({ persistState });
743
801
  }
802
+ if (themeBaseUrl) {
803
+ rootScope.registerRequestHandlers({ applyTheme });
804
+ }
744
805
  const moduleScopes = built.moduleComponents.map((comps) => {
745
806
  const scope = rootScope.enter();
746
807
  scope.registerComponents(comps);
@@ -773,17 +834,53 @@ async function mountStorybook(selector, modules, { compileCss, root, persistUrl
773
834
  }
774
835
  window.history[push ? "pushState" : "replaceState"](null, "", url);
775
836
  }
837
+ function applyTheme(name, instance) {
838
+ if (instance !== app.state.val)
839
+ return;
840
+ ensureThemeLink(name);
841
+ document.documentElement.dataset.theme = name;
842
+ }
776
843
  function loadState() {
777
844
  const p = new URLSearchParams(window.location.search);
778
845
  return {
779
846
  section: p.get("section"),
780
847
  example: p.get("example"),
781
848
  sectionFilter: p.get("sectionFilter") ?? "",
782
- exampleFilter: p.get("exampleFilter") ?? ""
849
+ exampleFilter: p.get("exampleFilter") ?? "",
850
+ theme: resolveTheme(p.get("theme"))
783
851
  };
784
852
  }
785
853
  function loadStateBlank() {
786
- return { section: null, example: null, sectionFilter: "", exampleFilter: "" };
854
+ return {
855
+ section: null,
856
+ example: null,
857
+ sectionFilter: "",
858
+ exampleFilter: "",
859
+ theme: resolveTheme(null)
860
+ };
861
+ }
862
+ function resolveTheme(fromUrl) {
863
+ if (!themeBaseUrl)
864
+ return "";
865
+ const name = MARGAUI_THEMES.includes(fromUrl) ? fromUrl : osTheme();
866
+ ensureThemeLink(name);
867
+ document.documentElement.dataset.theme = name;
868
+ return name;
869
+ }
870
+ function osTheme() {
871
+ return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
872
+ }
873
+ function ensureThemeLink(name) {
874
+ if (BUNDLED_THEMES.has(name) || document.getElementById(themeLinkId(name)))
875
+ return;
876
+ const link = document.createElement("link");
877
+ link.rel = "stylesheet";
878
+ link.id = themeLinkId(name);
879
+ link.href = `${themeBaseUrl}${name}.css`;
880
+ document.head.append(link);
881
+ }
882
+ function themeLinkId(name) {
883
+ return `tutuca-theme-${name}`;
787
884
  }
788
885
  }
789
886
 
@@ -800,5 +897,7 @@ export {
800
897
  buildExampleRequestHandlers,
801
898
  Storybook,
802
899
  Section,
803
- Example
900
+ MARGAUI_THEMES,
901
+ Example,
902
+ BUNDLED_THEMES
804
903
  };
@@ -540,7 +540,6 @@ var PREDICATES = {
540
540
 
541
541
  class ValParser {
542
542
  constructor() {
543
- this.bindValIt = new BindVal("it");
544
543
  this.nullConstVal = new ConstVal(null);
545
544
  }
546
545
  const(v) {
@@ -2086,7 +2085,7 @@ function parseXOp(attrs, childs, opIdx, px) {
2086
2085
  node = px.addNodeIf(RenderNode, parseXOpVal(name, value, px, vp.parseComponent), as);
2087
2086
  break;
2088
2087
  case "render-it":
2089
- node = px.addNodeIf(RenderItNode, vp.bindValIt, as);
2088
+ node = px.addNode(RenderItNode, as);
2090
2089
  break;
2091
2090
  case "render-each":
2092
2091
  node = parseRenderEach(px, value, as, attrs);
@@ -2269,7 +2268,7 @@ function parseRenderEach(px, value, as, attrs) {
2269
2268
  const seqVal = parseXOpVal("render-each", value, px, vp.parseSequence);
2270
2269
  if (seqVal === null)
2271
2270
  return null;
2272
- const renderIt = px.addNodeIf(RenderItNode, vp.bindValIt, as);
2271
+ const renderIt = px.addNode(RenderItNode, as);
2273
2272
  const attrParser = getAttrParser(px);
2274
2273
  const eachAttr = attrParser.eachAttr = attrParser.pushWrapper("each", value, seqVal);
2275
2274
  const when = attrs.getNamedItem("@when") ?? attrs.getNamedItem("when");
@@ -2469,6 +2468,12 @@ class ParseContext {
2469
2468
  }
2470
2469
  return null;
2471
2470
  }
2471
+ addNode(Class, extra) {
2472
+ const nodeId = this.nodes.length;
2473
+ const node = new Class(nodeId, null, extra);
2474
+ this.nodes.push(node);
2475
+ return node;
2476
+ }
2472
2477
  registerEvents() {
2473
2478
  const id = this.events.length;
2474
2479
  const events = new NodeEvents(id);
@@ -2900,7 +2905,7 @@ class Stack {
2900
2905
  return new Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
2901
2906
  }
2902
2907
  static root(comps, it, ctx) {
2903
- const binds = [new BindFrame(it, { it }, true), null];
2908
+ const binds = [new BindFrame(it, {}, true), null];
2904
2909
  const dynBinds = [new ObjectFrame({}), null];
2905
2910
  const views = ["main", null];
2906
2911
  return new Stack(comps, it, binds, dynBinds, views, "", ctx)._pushProvides();
package/dist/tutuca.js CHANGED
@@ -4911,7 +4911,6 @@ var PREDICATES = {
4911
4911
 
4912
4912
  class ValParser {
4913
4913
  constructor() {
4914
- this.bindValIt = new BindVal("it");
4915
4914
  this.nullConstVal = new ConstVal(null);
4916
4915
  }
4917
4916
  const(v) {
@@ -6454,7 +6453,7 @@ function parseXOp(attrs, childs, opIdx, px) {
6454
6453
  node = px.addNodeIf(RenderNode, parseXOpVal(name, value, px, vp.parseComponent), as);
6455
6454
  break;
6456
6455
  case "render-it":
6457
- node = px.addNodeIf(RenderItNode, vp.bindValIt, as);
6456
+ node = px.addNode(RenderItNode, as);
6458
6457
  break;
6459
6458
  case "render-each":
6460
6459
  node = parseRenderEach(px, value, as, attrs);
@@ -6637,7 +6636,7 @@ function parseRenderEach(px, value, as, attrs) {
6637
6636
  const seqVal = parseXOpVal("render-each", value, px, vp.parseSequence);
6638
6637
  if (seqVal === null)
6639
6638
  return null;
6640
- const renderIt = px.addNodeIf(RenderItNode, vp.bindValIt, as);
6639
+ const renderIt = px.addNode(RenderItNode, as);
6641
6640
  const attrParser = getAttrParser(px);
6642
6641
  const eachAttr = attrParser.eachAttr = attrParser.pushWrapper("each", value, seqVal);
6643
6642
  const when = attrs.getNamedItem("@when") ?? attrs.getNamedItem("when");
@@ -6837,6 +6836,12 @@ class ParseContext {
6837
6836
  }
6838
6837
  return null;
6839
6838
  }
6839
+ addNode(Class, extra) {
6840
+ const nodeId = this.nodes.length;
6841
+ const node = new Class(nodeId, null, extra);
6842
+ this.nodes.push(node);
6843
+ return node;
6844
+ }
6840
6845
  registerEvents() {
6841
6846
  const id = this.events.length;
6842
6847
  const events = new NodeEvents(id);
@@ -7268,7 +7273,7 @@ class Stack2 {
7268
7273
  return new Stack2(comps, it, binds, newDynBinds, views, viewsId, ctx);
7269
7274
  }
7270
7275
  static root(comps, it, ctx) {
7271
- const binds = [new BindFrame(it, { it }, true), null];
7276
+ const binds = [new BindFrame(it, {}, true), null];
7272
7277
  const dynBinds = [new ObjectFrame({}), null];
7273
7278
  const views = ["main", null];
7274
7279
  return new Stack2(comps, it, binds, dynBinds, views, "", ctx)._pushProvides();