@storybook/addon-onboarding 0.0.0-pr-32799-sha-e72c6b25 → 0.0.0-pr-32921-sha-e379604f

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.
@@ -1,6 +1,3 @@
1
- import {
2
- IntentSurvey
3
- } from "./chunk-2GE6IOLL.js";
4
1
  import {
5
2
  ADDON_CONTROLS_ID,
6
3
  STORYBOOK_ADDON_ONBOARDING_CHANNEL
@@ -1253,10 +1250,10 @@ var require_prop_types = __commonJS({
1253
1250
  });
1254
1251
 
1255
1252
  // src/Onboarding.tsx
1256
- import React14, { useCallback as useCallback2, useEffect as useEffect5, useState as useState3 } from "react";
1253
+ import React15, { useCallback as useCallback2, useEffect as useEffect5, useState as useState4 } from "react";
1257
1254
  import { SyntaxHighlighter } from "storybook/internal/components";
1258
1255
  import { SAVE_STORY_RESPONSE } from "storybook/internal/core-events";
1259
- import { ThemeProvider, convert, styled as styled5, themes } from "storybook/theming";
1256
+ import { ThemeProvider, convert, styled as styled6, themes } from "storybook/theming";
1260
1257
 
1261
1258
  // src/components/Confetti/Confetti.tsx
1262
1259
  import React from "react";
@@ -7686,10 +7683,190 @@ function GuidedTour({
7686
7683
  }
7687
7684
  __name(GuidedTour, "GuidedTour");
7688
7685
 
7686
+ // src/features/IntentSurvey/IntentSurvey.tsx
7687
+ import React13, { useState as useState2 } from "react";
7688
+ import { Button as Button3, Form, Modal } from "storybook/internal/components";
7689
+ import { styled as styled4 } from "storybook/theming";
7690
+
7691
+ // ../../.storybook/isChromatic.ts
7692
+ function isChromatic(windowArg) {
7693
+ const windowToCheck = windowArg || typeof window !== "undefined" && window;
7694
+ return !!(windowToCheck && (windowToCheck.navigator.userAgent.match(/Chromatic/) || windowToCheck.location.href.match(/chromatic=true/)));
7695
+ }
7696
+ __name(isChromatic, "isChromatic");
7697
+
7698
+ // src/features/IntentSurvey/IntentSurvey.tsx
7699
+ var Content = styled4(Modal.Content)(({ theme: theme2 }) => ({
7700
+ fontSize: theme2.typography.size.s2,
7701
+ color: theme2.color.defaultText,
7702
+ gap: 8
7703
+ }));
7704
+ var Row = styled4.div({
7705
+ display: "grid",
7706
+ gridTemplateColumns: "1fr 1fr",
7707
+ gap: 14,
7708
+ marginBottom: 8
7709
+ });
7710
+ var Question = styled4.div(({ theme: theme2 }) => ({
7711
+ marginTop: 8,
7712
+ marginBottom: 2,
7713
+ fontWeight: theme2.typography.weight.bold
7714
+ }));
7715
+ var Label = styled4.label({
7716
+ display: "flex",
7717
+ gap: 8,
7718
+ '&:has(input[type="checkbox"]:not(:disabled), input[type="radio"]:not(:disabled))': {
7719
+ cursor: "pointer"
7720
+ }
7721
+ });
7722
+ var Actions = styled4(Modal.Actions)({
7723
+ marginTop: 8
7724
+ });
7725
+ var Checkbox = styled4(Form.Checkbox)({
7726
+ margin: 2
7727
+ });
7728
+ var IntentSurvey = /* @__PURE__ */ __name(({
7729
+ onComplete,
7730
+ onDismiss
7731
+ }) => {
7732
+ const [isSubmitting, setIsSubmitting] = useState2(false);
7733
+ const [formFields, setFormFields] = useState2({
7734
+ building: {
7735
+ label: "What are you building?",
7736
+ type: "checkbox",
7737
+ required: true,
7738
+ options: shuffleObject({
7739
+ "design-system": { label: "Design system" },
7740
+ "application-ui": { label: "Application UI" }
7741
+ }),
7742
+ values: {
7743
+ "design-system": false,
7744
+ "application-ui": false
7745
+ }
7746
+ },
7747
+ interest: {
7748
+ label: "Which of these are you interested in?",
7749
+ type: "checkbox",
7750
+ required: true,
7751
+ options: shuffleObject({
7752
+ "ui-documentation": { label: "Generating UI docs" },
7753
+ "functional-testing": { label: "Functional testing" },
7754
+ "accessibility-testing": { label: "Accessibility testing" },
7755
+ "visual-testing": { label: "Visual testing" },
7756
+ "ai-augmented-development": { label: "Building UI with AI" },
7757
+ "team-collaboration": { label: "Team collaboration" },
7758
+ "design-handoff": { label: "Design handoff" }
7759
+ }),
7760
+ values: {
7761
+ "ui-documentation": false,
7762
+ "functional-testing": false,
7763
+ "accessibility-testing": false,
7764
+ "visual-testing": false,
7765
+ "ai-augmented-development": false,
7766
+ "team-collaboration": false,
7767
+ "design-handoff": false
7768
+ }
7769
+ },
7770
+ referrer: {
7771
+ label: "How did you discover Storybook?",
7772
+ type: "select",
7773
+ required: true,
7774
+ options: shuffleObject({
7775
+ "we-use-it-at-work": { label: "We use it at work" },
7776
+ "via-friend-or-colleague": { label: "Via friend or colleague" },
7777
+ "via-social-media": { label: "Via social media" },
7778
+ youtube: { label: "YouTube" },
7779
+ "web-search": { label: "Web Search" },
7780
+ "ai-agent": { label: "AI Agent (e.g. ChatGPT)" }
7781
+ }),
7782
+ values: {
7783
+ "we-use-it-at-work": false,
7784
+ "via-friend-or-colleague": false,
7785
+ "via-social-media": false,
7786
+ youtube: false,
7787
+ "web-search": false,
7788
+ "ai-agent": false
7789
+ }
7790
+ }
7791
+ });
7792
+ const updateFormData = /* @__PURE__ */ __name((key, optionOrValue, value) => {
7793
+ const field = formFields[key];
7794
+ setFormFields((fields) => {
7795
+ if (field.type === "checkbox") {
7796
+ const values = { ...field.values, [optionOrValue]: !!value };
7797
+ return { ...fields, [key]: { ...field, values } };
7798
+ }
7799
+ if (field.type === "select") {
7800
+ const values = Object.fromEntries(
7801
+ Object.entries(field.values).map(([opt]) => [opt, opt === optionOrValue])
7802
+ );
7803
+ return { ...fields, [key]: { ...field, values } };
7804
+ }
7805
+ return fields;
7806
+ });
7807
+ }, "updateFormData");
7808
+ const isValid = Object.values(formFields).every((field) => {
7809
+ if (!field.required) {
7810
+ return true;
7811
+ }
7812
+ return Object.values(field.values).some((value) => value === true);
7813
+ });
7814
+ const onSubmitForm = /* @__PURE__ */ __name((e2) => {
7815
+ if (!isValid) {
7816
+ return;
7817
+ }
7818
+ e2.preventDefault();
7819
+ setIsSubmitting(true);
7820
+ onComplete(
7821
+ Object.fromEntries(Object.entries(formFields).map(([key, field]) => [key, field.values]))
7822
+ );
7823
+ }, "onSubmitForm");
7824
+ return React13.createElement(Modal, { defaultOpen: true, width: 420, onEscapeKeyDown: onDismiss }, React13.createElement(Form, { onSubmit: onSubmitForm, id: "intent-survey-form" }, React13.createElement(Content, null, React13.createElement(Modal.Header, null, React13.createElement(Modal.Title, null, "Help improve Storybook")), Object.keys(formFields).map((key) => {
7825
+ const field = formFields[key];
7826
+ return React13.createElement(React13.Fragment, { key }, React13.createElement(Question, null, field.label), field.type === "checkbox" && React13.createElement(Row, null, Object.entries(field.options).map(([opt, option]) => {
7827
+ const id = `${key}:${opt}`;
7828
+ return React13.createElement("div", { key: id }, React13.createElement(Label, { htmlFor: id }, React13.createElement(
7829
+ Checkbox,
7830
+ {
7831
+ name: id,
7832
+ id,
7833
+ checked: field.values[opt],
7834
+ disabled: isSubmitting,
7835
+ onChange: (e2) => updateFormData(key, opt, e2.target.checked)
7836
+ }
7837
+ ), option.label));
7838
+ })), field.type === "select" && React13.createElement(
7839
+ Form.Select,
7840
+ {
7841
+ name: key,
7842
+ id: key,
7843
+ value: Object.entries(field.values).find(([, isSelected]) => isSelected)?.[0] || "",
7844
+ required: field.required,
7845
+ disabled: isSubmitting,
7846
+ onChange: (e2) => updateFormData(key, e2.target.value)
7847
+ },
7848
+ React13.createElement("option", { disabled: true, hidden: true, value: "" }, "Select an option..."),
7849
+ Object.entries(field.options).map(([opt, option]) => React13.createElement("option", { key: opt, value: opt }, option.label))
7850
+ ));
7851
+ }), React13.createElement(Actions, null, React13.createElement(Button3, { disabled: isSubmitting || !isValid, size: "medium", type: "submit", variant: "solid" }, "Submit")))));
7852
+ }, "IntentSurvey");
7853
+ function shuffle(array) {
7854
+ for (let i2 = array.length - 1; i2 > 0; i2--) {
7855
+ const j = Math.floor(Math.random() * (i2 + 1));
7856
+ [array[i2], array[j]] = [array[j], array[i2]];
7857
+ }
7858
+ return array;
7859
+ }
7860
+ __name(shuffle, "shuffle");
7861
+ function shuffleObject(object) {
7862
+ return isChromatic() ? object : Object.fromEntries(shuffle(Object.entries(object)));
7863
+ }
7864
+ __name(shuffleObject, "shuffleObject");
7865
+
7689
7866
  // src/features/SplashScreen/SplashScreen.tsx
7690
- import React13, { useCallback, useEffect as useEffect4, useState as useState2 } from "react";
7867
+ import React14, { useCallback, useEffect as useEffect4, useState as useState3 } from "react";
7691
7868
  import { ArrowRightIcon } from "@storybook/icons";
7692
- import { keyframes, styled as styled4 } from "storybook/theming";
7869
+ import { keyframes, styled as styled5 } from "storybook/theming";
7693
7870
  var fadeIn = keyframes({
7694
7871
  from: {
7695
7872
  opacity: 0
@@ -7726,7 +7903,7 @@ var rotate = keyframes({
7726
7903
  transform: "rotate(360deg)"
7727
7904
  }
7728
7905
  });
7729
- var Wrapper3 = styled4.div(({ visible }) => ({
7906
+ var Wrapper3 = styled5.div(({ visible }) => ({
7730
7907
  position: "fixed",
7731
7908
  top: 0,
7732
7909
  left: 0,
@@ -7739,7 +7916,7 @@ var Wrapper3 = styled4.div(({ visible }) => ({
7739
7916
  zIndex: 1e3,
7740
7917
  transition: "opacity 1s 0.5s"
7741
7918
  }));
7742
- var Backdrop = styled4.div({
7919
+ var Backdrop = styled5.div({
7743
7920
  position: "absolute",
7744
7921
  top: 0,
7745
7922
  left: 0,
@@ -7766,7 +7943,7 @@ var Backdrop = styled4.div({
7766
7943
  animation: `${rotate} 12s linear infinite`
7767
7944
  }
7768
7945
  });
7769
- var Content = styled4.div(({ visible }) => ({
7946
+ var Content2 = styled5.div(({ visible }) => ({
7770
7947
  position: "absolute",
7771
7948
  top: "50%",
7772
7949
  left: "50%",
@@ -7784,7 +7961,7 @@ var Content = styled4.div(({ visible }) => ({
7784
7961
  animation: `${slideIn} 1.5s 1s backwards`
7785
7962
  }
7786
7963
  }));
7787
- var Features = styled4.div({
7964
+ var Features = styled5.div({
7788
7965
  display: "flex",
7789
7966
  marginTop: 40,
7790
7967
  div: {
@@ -7807,7 +7984,7 @@ var Features = styled4.div({
7807
7984
  marginBottom: 10
7808
7985
  }
7809
7986
  });
7810
- var RadialButton = styled4.button({
7987
+ var RadialButton = styled5.button({
7811
7988
  display: "inline-flex",
7812
7989
  position: "relative",
7813
7990
  alignItems: "center",
@@ -7827,11 +8004,11 @@ var RadialButton = styled4.button({
7827
8004
  background: "rgba(255, 255, 255, 0.4)"
7828
8005
  }
7829
8006
  });
7830
- var ArrowIcon = styled4(ArrowRightIcon)({
8007
+ var ArrowIcon = styled5(ArrowRightIcon)({
7831
8008
  width: 30,
7832
8009
  color: "white"
7833
8010
  });
7834
- var ProgressCircle = styled4.svg(({ progress }) => ({
8011
+ var ProgressCircle = styled5.svg(({ progress }) => ({
7835
8012
  position: "absolute",
7836
8013
  top: -1,
7837
8014
  left: -1,
@@ -7851,8 +8028,8 @@ var ProgressCircle = styled4.svg(({ progress }) => ({
7851
8028
  }
7852
8029
  }));
7853
8030
  var SplashScreen = /* @__PURE__ */ __name(({ onDismiss, duration = 6e3 }) => {
7854
- const [progress, setProgress] = useState2(-4e3 * 100 / duration);
7855
- const [visible, setVisible] = useState2(true);
8031
+ const [progress, setProgress] = useState3(-4e3 * 100 / duration);
8032
+ const [visible, setVisible] = useState3(true);
7856
8033
  const ready = progress >= 100;
7857
8034
  const dismiss = useCallback(() => {
7858
8035
  setVisible(false);
@@ -7873,26 +8050,26 @@ var SplashScreen = /* @__PURE__ */ __name(({ onDismiss, duration = 6e3 }) => {
7873
8050
  dismiss();
7874
8051
  }
7875
8052
  }, [ready, dismiss]);
7876
- return React13.createElement(Wrapper3, { visible }, React13.createElement(Backdrop, null), React13.createElement(Content, { visible }, React13.createElement("h1", null, "Meet your new frontend workshop"), React13.createElement(Features, null, React13.createElement("div", null, React13.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "33", height: "32" }, React13.createElement(
8053
+ return React14.createElement(Wrapper3, { visible }, React14.createElement(Backdrop, null), React14.createElement(Content2, { visible }, React14.createElement("h1", null, "Meet your new frontend workshop"), React14.createElement(Features, null, React14.createElement("div", null, React14.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "33", height: "32" }, React14.createElement(
7877
8054
  "path",
7878
8055
  {
7879
8056
  d: "M4.06 0H32.5v28.44h-3.56V32H.5V3.56h3.56V0Zm21.33 7.11H4.06v21.33h21.33V7.11Z",
7880
8057
  fill: "currentColor"
7881
8058
  }
7882
- )), "Development"), React13.createElement("div", null, React13.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "32", height: "32" }, React13.createElement(
8059
+ )), "Development"), React14.createElement("div", null, React14.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "32", height: "32" }, React14.createElement(
7883
8060
  "path",
7884
8061
  {
7885
8062
  d: "M15.95 32c-1.85 0-3.1-1.55-3.1-3.54 0-1.1.45-2.78 1.35-5.03.9-2.3 1.35-4.51 1.35-6.81a22.21 22.21 0 0 0-5.1 3.67c-2.5 2.47-4.95 4.9-7.55 4.9-1.6 0-2.9-1.1-2.9-2.43 0-1.46 1.35-2.91 4.3-3.62 1.45-.36 3.1-.75 4.95-1.06 1.8-.31 3.8-1.02 5.9-2.08a23.77 23.77 0 0 0-6.1-2.12C5.3 13.18 2.3 12.6 1 11.28.35 10.6 0 9.9 0 9.14 0 7.82 1.2 6.8 2.95 6.8c2.65 0 5.75 3.1 7.95 5.3 1.1 1.1 2.65 2.21 4.65 3.27v-.57c0-1.77-.15-3.23-.55-4.3-.8-2.11-2.05-5.43-2.05-6.97 0-2.04 1.3-3.54 3.1-3.54 1.75 0 3.1 1.41 3.1 3.54 0 1.06-.45 2.78-1.35 5.12-.9 2.35-1.35 4.6-1.35 6.72 2.85-1.59 2.5-1.41 4.95-3.5 2.35-2.29 4-3.7 4.9-4.23.95-.58 1.9-.84 2.9-.84 1.6 0 2.8.97 2.8 2.34 0 1.5-1.25 2.78-4.15 3.62-1.4.4-3.05.75-4.9 1.1-1.9.36-3.9 1.07-6.1 2.13a23.3 23.3 0 0 0 5.95 2.08c3.65.7 6.75 1.32 8.15 2.6.7.67 1.05 1.33 1.05 2.08 0 1.33-1.2 2.43-2.95 2.43-2.95 0-6.75-4.15-8.2-5.61-.7-.7-2.2-1.72-4.4-2.96v.57c0 1.9.45 4.03 1.3 6.32.85 2.3 1.3 3.94 1.3 4.95 0 2.08-1.35 3.54-3.1 3.54Z",
7886
8063
  fill: "currentColor"
7887
8064
  }
7888
- )), "Testing"), React13.createElement("div", null, React13.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "33", height: "32" }, React13.createElement(
8065
+ )), "Testing"), React14.createElement("div", null, React14.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "33", height: "32" }, React14.createElement(
7889
8066
  "path",
7890
8067
  {
7891
8068
  d: "M.5 16a16 16 0 1 1 32 0 16 16 0 0 1-32 0Zm16 12.44A12.44 12.44 0 0 1 4.3 13.53a8 8 0 1 0 9.73-9.73 12.44 12.44 0 1 1 2.47 24.64ZM12.06 16a4.44 4.44 0 1 1 0-8.89 4.44 4.44 0 0 1 0 8.89Z",
7892
8069
  fill: "currentColor",
7893
8070
  fillRule: "evenodd"
7894
8071
  }
7895
- )), "Documentation")), React13.createElement(RadialButton, { onClick: dismiss }, React13.createElement(ArrowIcon, null), React13.createElement(ProgressCircle, { xmlns: "http://www.w3.org/2000/svg" }, React13.createElement("circle", null)), React13.createElement(ProgressCircle, { xmlns: "http://www.w3.org/2000/svg", progress: true }, React13.createElement(
8072
+ )), "Documentation")), React14.createElement(RadialButton, { onClick: dismiss }, React14.createElement(ArrowIcon, null), React14.createElement(ProgressCircle, { xmlns: "http://www.w3.org/2000/svg" }, React14.createElement("circle", null)), React14.createElement(ProgressCircle, { xmlns: "http://www.w3.org/2000/svg", progress: true }, React14.createElement(
7896
8073
  "circle",
7897
8074
  {
7898
8075
  strokeDashoffset: Math.PI * 48 * (1 - Math.max(0, Math.min(progress, 100)) / 100)
@@ -7901,7 +8078,7 @@ var SplashScreen = /* @__PURE__ */ __name(({ onDismiss, duration = 6e3 }) => {
7901
8078
  }, "SplashScreen");
7902
8079
 
7903
8080
  // src/Onboarding.tsx
7904
- var SpanHighlight = styled5.span(({ theme: theme2 }) => ({
8081
+ var SpanHighlight = styled6.span(({ theme: theme2 }) => ({
7905
8082
  display: "inline-flex",
7906
8083
  borderRadius: 3,
7907
8084
  padding: "0 5px",
@@ -7915,7 +8092,7 @@ var SpanHighlight = styled5.span(({ theme: theme2 }) => ({
7915
8092
  boxSizing: "border-box",
7916
8093
  lineHeight: "17px"
7917
8094
  }));
7918
- var CodeWrapper = styled5.div(({ theme: theme2 }) => ({
8095
+ var CodeWrapper = styled6.div(({ theme: theme2 }) => ({
7919
8096
  background: theme2.background.content,
7920
8097
  borderRadius: 3,
7921
8098
  marginTop: 15,
@@ -7927,13 +8104,13 @@ var CodeWrapper = styled5.div(({ theme: theme2 }) => ({
7927
8104
  }));
7928
8105
  var theme = convert();
7929
8106
  function Onboarding({ api }) {
7930
- const [enabled, setEnabled] = useState3(true);
7931
- const [showConfetti, setShowConfetti] = useState3(false);
7932
- const [step, setStep] = useState3("1:Intro");
7933
- const [primaryControl, setPrimaryControl] = useState3();
7934
- const [saveFromControls, setSaveFromControls] = useState3();
7935
- const [createNewStoryForm, setCreateNewStoryForm] = useState3();
7936
- const [createdStory, setCreatedStory] = useState3();
8107
+ const [enabled, setEnabled] = useState4(true);
8108
+ const [showConfetti, setShowConfetti] = useState4(false);
8109
+ const [step, setStep] = useState4("1:Intro");
8110
+ const [primaryControl, setPrimaryControl] = useState4();
8111
+ const [saveFromControls, setSaveFromControls] = useState4();
8112
+ const [createNewStoryForm, setCreateNewStoryForm] = useState4();
8113
+ const [createdStory, setCreatedStory] = useState4();
7937
8114
  const userAgent = globalThis?.navigator?.userAgent;
7938
8115
  const selectStory = useCallback2(
7939
8116
  (storyId) => {
@@ -7947,24 +8124,14 @@ function Onboarding({ api }) {
7947
8124
  },
7948
8125
  [api]
7949
8126
  );
7950
- const disableOnboarding = useCallback2(
7951
- (dismissedStep) => {
7952
- if (dismissedStep) {
7953
- api.emit(STORYBOOK_ADDON_ONBOARDING_CHANNEL, {
7954
- step: dismissedStep,
7955
- type: "dismiss",
7956
- userAgent
7957
- });
7958
- }
7959
- const url = new URL(window.location.href);
7960
- const path = decodeURIComponent(url.searchParams.get("path"));
7961
- url.search = `?path=${path}&onboarding=false`;
7962
- history.replaceState({}, "", url.href);
7963
- api.setQueryParams({ onboarding: "false" });
7964
- setEnabled(false);
7965
- },
7966
- [api, setEnabled, userAgent]
7967
- );
8127
+ const disableOnboarding = useCallback2(() => {
8128
+ const url = new URL(window.location.href);
8129
+ const path = decodeURIComponent(url.searchParams.get("path"));
8130
+ url.search = `?path=${path}&onboarding=false`;
8131
+ history.replaceState({}, "", url.href);
8132
+ api.setQueryParams({ onboarding: "false" });
8133
+ setEnabled(false);
8134
+ }, [api, setEnabled]);
7968
8135
  const completeOnboarding = useCallback2(
7969
8136
  (answers) => {
7970
8137
  api.emit(STORYBOOK_ADDON_ONBOARDING_CHANNEL, {
@@ -8043,7 +8210,7 @@ function Onboarding({ api }) {
8043
8210
  key: "2:Controls",
8044
8211
  target: "#control-primary",
8045
8212
  title: "Interactive story playground",
8046
- content: React14.createElement(React14.Fragment, null, "See how a story renders with different data and state without touching code. Try it out by toggling this button.", React14.createElement(HighlightElement, { targetSelector: "#control-primary", pulsating: true })),
8213
+ content: React15.createElement(React15.Fragment, null, "See how a story renders with different data and state without touching code. Try it out by toggling this button.", React15.createElement(HighlightElement, { targetSelector: "#control-primary", pulsating: true })),
8047
8214
  offset: 20,
8048
8215
  placement: "right",
8049
8216
  disableBeacon: true,
@@ -8058,7 +8225,7 @@ function Onboarding({ api }) {
8058
8225
  key: "3:SaveFromControls",
8059
8226
  target: 'button[aria-label="Create new story with these settings"]',
8060
8227
  title: "Save your changes as a new story",
8061
- content: React14.createElement(React14.Fragment, null, "Great! Storybook stories represent the key states of each of your components. After modifying a story, you can save your changes from here or reset it.", React14.createElement(HighlightElement, { targetSelector: "button[aria-label='Create new story with these settings']" })),
8228
+ content: React15.createElement(React15.Fragment, null, "Great! Storybook stories represent the key states of each of your components. After modifying a story, you can save your changes from here or reset it.", React15.createElement(HighlightElement, { targetSelector: "button[aria-label='Create new story with these settings']" })),
8062
8229
  offset: 6,
8063
8230
  placement: "top",
8064
8231
  disableBeacon: true,
@@ -8080,7 +8247,7 @@ function Onboarding({ api }) {
8080
8247
  key: "5:StoryCreated",
8081
8248
  target: '#storybook-explorer-tree [data-selected="true"]',
8082
8249
  title: "You just added your first story!",
8083
- content: React14.createElement(React14.Fragment, null, "Well done! You just created your first story from the Storybook manager. This automatically added a few lines of code in", " ", React14.createElement(SpanHighlight, null, createdStory?.sourceFileName), ".", snippet && React14.createElement(ThemeProvider, { theme: convert(themes.dark) }, React14.createElement(CodeWrapper, null, React14.createElement(
8250
+ content: React15.createElement(React15.Fragment, null, "Well done! You just created your first story from the Storybook manager. This automatically added a few lines of code in", " ", React15.createElement(SpanHighlight, null, createdStory?.sourceFileName), ".", snippet && React15.createElement(ThemeProvider, { theme: convert(themes.dark) }, React15.createElement(CodeWrapper, null, React15.createElement(
8084
8251
  SyntaxHighlighter,
8085
8252
  {
8086
8253
  language: "jsx",
@@ -8100,18 +8267,12 @@ function Onboarding({ api }) {
8100
8267
  }
8101
8268
  }
8102
8269
  ];
8103
- return React14.createElement(ThemeProvider, { theme }, showConfetti && React14.createElement(Confetti, null), step === "1:Intro" ? React14.createElement(SplashScreen, { onDismiss: () => setStep("2:Controls") }) : step === "6:IntentSurvey" ? React14.createElement(
8104
- IntentSurvey,
8105
- {
8106
- onComplete: completeOnboarding,
8107
- onDismiss: () => disableOnboarding("6:IntentSurvey")
8108
- }
8109
- ) : React14.createElement(
8270
+ return React15.createElement(ThemeProvider, { theme }, showConfetti && React15.createElement(Confetti, null), step === "1:Intro" ? React15.createElement(SplashScreen, { onDismiss: () => setStep("2:Controls") }) : step === "6:IntentSurvey" ? React15.createElement(IntentSurvey, { onComplete: completeOnboarding, onDismiss: disableOnboarding }) : React15.createElement(
8110
8271
  GuidedTour,
8111
8272
  {
8112
8273
  step,
8113
8274
  steps,
8114
- onClose: () => disableOnboarding(step),
8275
+ onClose: disableOnboarding,
8115
8276
  onComplete: () => setStep("6:IntentSurvey")
8116
8277
  }
8117
8278
  ));
package/dist/manager.js CHANGED
@@ -1,46 +1,37 @@
1
1
  import {
2
2
  ADDON_CONTROLS_ID
3
3
  } from "./_browser-chunks/chunk-B266DSPW.js";
4
- import {
5
- __name
6
- } from "./_browser-chunks/chunk-CBI7MY27.js";
4
+ import "./_browser-chunks/chunk-CBI7MY27.js";
7
5
 
8
6
  // src/manager.tsx
9
7
  import React, { Suspense, lazy } from "react";
10
- import { createRoot } from "react-dom/client";
8
+ import ReactDOM from "react-dom";
11
9
  import { STORY_SPECIFIED } from "storybook/internal/core-events";
12
10
  import { addons } from "storybook/manager-api";
13
- var Onboarding = lazy(() => import("./_browser-chunks/Onboarding-JPHTTZDC.js"));
14
- var Survey = lazy(() => import("./_browser-chunks/Survey-FXIM2EKF.js"));
15
- var render = /* @__PURE__ */ __name((node) => {
16
- let container = document.getElementById("storybook-addon-onboarding");
17
- if (!container) {
18
- container = document.createElement("div");
19
- container.id = "storybook-addon-onboarding";
20
- document.body.appendChild(container);
21
- }
22
- createRoot(container).render(React.createElement(Suspense, { fallback: React.createElement("div", null) }, node));
23
- }, "render");
11
+ var Onboarding = lazy(() => import("./_browser-chunks/Onboarding-XBLXWDOE.js"));
24
12
  addons.register("@storybook/addon-onboarding", async (api) => {
25
- const { path, queryParams } = api.getUrlState();
26
- const isOnboarding = path === "/onboarding" || queryParams.onboarding === "true";
27
- const isSurvey = queryParams.onboarding === "survey";
28
- if (isSurvey) {
29
- return render(React.createElement(Survey, { api }));
30
- }
31
- await new Promise((resolve) => api.once(STORY_SPECIFIED, resolve));
32
- const hasButtonStories = !!api.getData("example-button--primary") || !!document.getElementById("example-button--primary");
33
- if (!hasButtonStories) {
34
- console.warn(
35
- `[@storybook/addon-onboarding] It seems like you have finished the onboarding experience in Storybook! Therefore this addon is not necessary anymore and will not be loaded. You are free to remove it from your project. More info: https://github.com/storybookjs/storybook/tree/next/code/addons/onboarding#uninstalling`
13
+ const urlState = api.getUrlState();
14
+ const isOnboarding = urlState.path === "/onboarding" || urlState.queryParams.onboarding === "true";
15
+ api.once(STORY_SPECIFIED, () => {
16
+ const hasButtonStories = !!api.getData("example-button--primary") || !!document.getElementById("example-button--primary");
17
+ if (!hasButtonStories) {
18
+ console.warn(
19
+ `[@storybook/addon-onboarding] It seems like you have finished the onboarding experience in Storybook! Therefore this addon is not necessary anymore and will not be loaded. You are free to remove it from your project. More info: https://github.com/storybookjs/storybook/tree/next/code/addons/onboarding#uninstalling`
20
+ );
21
+ return;
22
+ }
23
+ if (!isOnboarding || window.innerWidth < 730) {
24
+ return;
25
+ }
26
+ api.togglePanel(true);
27
+ api.togglePanelPosition("bottom");
28
+ api.setSelectedPanel(ADDON_CONTROLS_ID);
29
+ const domNode = document.createElement("div");
30
+ domNode.id = "storybook-addon-onboarding";
31
+ document.body.appendChild(domNode);
32
+ ReactDOM.render(
33
+ React.createElement(Suspense, { fallback: React.createElement("div", null) }, React.createElement(Onboarding, { api })),
34
+ domNode
36
35
  );
37
- return;
38
- }
39
- if (!isOnboarding || window.innerWidth < 730) {
40
- return;
41
- }
42
- api.togglePanel(true);
43
- api.togglePanelPosition("bottom");
44
- api.setSelectedPanel(ADDON_CONTROLS_ID);
45
- return render(React.createElement(Onboarding, { api }));
36
+ });
46
37
  });
package/dist/preset.js CHANGED
@@ -1,10 +1,10 @@
1
- import CJS_COMPAT_NODE_URL_3sdx6dbqxah from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_3sdx6dbqxah from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_3sdx6dbqxah from "node:module";
1
+ import CJS_COMPAT_NODE_URL_k5hyqr07skg from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_k5hyqr07skg from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_k5hyqr07skg from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_3sdx6dbqxah.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_3sdx6dbqxah.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_3sdx6dbqxah.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_k5hyqr07skg.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_k5hyqr07skg.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_k5hyqr07skg.createRequire(import.meta.url);
8
8
 
9
9
  // ------------------------------------------------------------
10
10
  // end of CJS compatibility banner, injected by Storybook's esbuild configuration
@@ -16,7 +16,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
16
16
  import { telemetry } from "storybook/internal/telemetry";
17
17
 
18
18
  // package.json
19
- var version = "0.0.0-pr-32799-sha-e72c6b25";
19
+ var version = "0.0.0-pr-32921-sha-e379604f";
20
20
 
21
21
  // src/constants.ts
22
22
  var STORYBOOK_ADDON_ONBOARDING_CHANNEL = "STORYBOOK_ADDON_ONBOARDING_CHANNEL";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/addon-onboarding",
3
- "version": "0.0.0-pr-32799-sha-e72c6b25",
3
+ "version": "0.0.0-pr-32921-sha-e379604f",
4
4
  "description": "Storybook Onboarding: Help new users learn how to write stories",
5
5
  "keywords": [
6
6
  "storybook",
@@ -59,7 +59,7 @@
59
59
  "typescript": "^5.8.3"
60
60
  },
61
61
  "peerDependencies": {
62
- "storybook": "^0.0.0-pr-32799-sha-e72c6b25"
62
+ "storybook": "^0.0.0-pr-32921-sha-e379604f"
63
63
  },
64
64
  "publishConfig": {
65
65
  "access": "public"
@@ -1,46 +0,0 @@
1
- import {
2
- IntentSurvey
3
- } from "./chunk-2GE6IOLL.js";
4
- import {
5
- STORYBOOK_ADDON_ONBOARDING_CHANNEL
6
- } from "./chunk-B266DSPW.js";
7
- import {
8
- __name
9
- } from "./chunk-CBI7MY27.js";
10
-
11
- // src/Survey.tsx
12
- import React, { useCallback } from "react";
13
- import { ThemeProvider, convert } from "storybook/theming";
14
- var theme = convert();
15
- function Survey({ api }) {
16
- const userAgent = globalThis?.navigator?.userAgent;
17
- const disableOnboarding = useCallback(() => {
18
- const url = new URL(window.location.href);
19
- const path = decodeURIComponent(url.searchParams.get("path"));
20
- url.search = `?path=${path}&onboarding=false`;
21
- history.replaceState({}, "", url.href);
22
- api.setQueryParams({ onboarding: "false" });
23
- }, [api]);
24
- const complete = useCallback(
25
- (answers) => {
26
- api.emit(STORYBOOK_ADDON_ONBOARDING_CHANNEL, {
27
- answers,
28
- type: "survey",
29
- userAgent
30
- });
31
- disableOnboarding();
32
- },
33
- [api, disableOnboarding, userAgent]
34
- );
35
- const dismiss = useCallback(() => {
36
- api.emit(STORYBOOK_ADDON_ONBOARDING_CHANNEL, {
37
- type: "skipSurvey"
38
- });
39
- disableOnboarding();
40
- }, [api, disableOnboarding]);
41
- return React.createElement(ThemeProvider, { theme }, React.createElement(IntentSurvey, { onComplete: complete, onDismiss: dismiss }));
42
- }
43
- __name(Survey, "Survey");
44
- export {
45
- Survey as default
46
- };
@@ -1,187 +0,0 @@
1
- import {
2
- __name
3
- } from "./chunk-CBI7MY27.js";
4
-
5
- // src/features/IntentSurvey/IntentSurvey.tsx
6
- import React, { useState } from "react";
7
- import { Button, Form, Modal } from "storybook/internal/components";
8
- import { styled } from "storybook/theming";
9
-
10
- // ../../.storybook/isChromatic.ts
11
- function isChromatic(windowArg) {
12
- const windowToCheck = windowArg || typeof window !== "undefined" && window;
13
- return !!(windowToCheck && (windowToCheck.navigator.userAgent.match(/Chromatic/) || windowToCheck.location.href.match(/chromatic=true/)));
14
- }
15
- __name(isChromatic, "isChromatic");
16
-
17
- // src/features/IntentSurvey/IntentSurvey.tsx
18
- var Content = styled(Modal.Content)(({ theme }) => ({
19
- fontSize: theme.typography.size.s2,
20
- color: theme.color.defaultText,
21
- gap: 8
22
- }));
23
- var Row = styled.div({
24
- display: "grid",
25
- gridTemplateColumns: "1fr 1fr",
26
- gap: 14,
27
- marginBottom: 8
28
- });
29
- var Question = styled.div(({ theme }) => ({
30
- marginTop: 8,
31
- marginBottom: 2,
32
- fontWeight: theme.typography.weight.bold
33
- }));
34
- var Label = styled.label({
35
- display: "flex",
36
- gap: 8,
37
- '&:has(input[type="checkbox"]:not(:disabled), input[type="radio"]:not(:disabled))': {
38
- cursor: "pointer"
39
- }
40
- });
41
- var Actions = styled(Modal.Actions)({
42
- marginTop: 8
43
- });
44
- var Checkbox = styled(Form.Checkbox)({
45
- margin: 2
46
- });
47
- var IntentSurvey = /* @__PURE__ */ __name(({
48
- onComplete,
49
- onDismiss
50
- }) => {
51
- const [isSubmitting, setIsSubmitting] = useState(false);
52
- const [formFields, setFormFields] = useState({
53
- building: {
54
- label: "What are you building?",
55
- type: "checkbox",
56
- required: true,
57
- options: shuffleObject({
58
- "design-system": { label: "Design system" },
59
- "application-ui": { label: "Application UI" }
60
- }),
61
- values: {
62
- "design-system": false,
63
- "application-ui": false
64
- }
65
- },
66
- interest: {
67
- label: "Which of these are you interested in?",
68
- type: "checkbox",
69
- required: true,
70
- options: shuffleObject({
71
- "ui-documentation": { label: "Generating UI docs" },
72
- "functional-testing": { label: "Functional testing" },
73
- "accessibility-testing": { label: "Accessibility testing" },
74
- "visual-testing": { label: "Visual testing" },
75
- "ai-augmented-development": { label: "Building UI with AI" },
76
- "team-collaboration": { label: "Team collaboration" },
77
- "design-handoff": { label: "Design handoff" }
78
- }),
79
- values: {
80
- "ui-documentation": false,
81
- "functional-testing": false,
82
- "accessibility-testing": false,
83
- "visual-testing": false,
84
- "ai-augmented-development": false,
85
- "team-collaboration": false,
86
- "design-handoff": false
87
- }
88
- },
89
- referrer: {
90
- label: "How did you discover Storybook?",
91
- type: "select",
92
- required: true,
93
- options: shuffleObject({
94
- "we-use-it-at-work": { label: "We use it at work" },
95
- "via-friend-or-colleague": { label: "Via friend or colleague" },
96
- "via-social-media": { label: "Via social media" },
97
- youtube: { label: "YouTube" },
98
- "web-search": { label: "Web Search" },
99
- "ai-agent": { label: "AI Agent (e.g. ChatGPT)" }
100
- }),
101
- values: {
102
- "we-use-it-at-work": false,
103
- "via-friend-or-colleague": false,
104
- "via-social-media": false,
105
- youtube: false,
106
- "web-search": false,
107
- "ai-agent": false
108
- }
109
- }
110
- });
111
- const updateFormData = /* @__PURE__ */ __name((key, optionOrValue, value) => {
112
- const field = formFields[key];
113
- setFormFields((fields) => {
114
- if (field.type === "checkbox") {
115
- const values = { ...field.values, [optionOrValue]: !!value };
116
- return { ...fields, [key]: { ...field, values } };
117
- }
118
- if (field.type === "select") {
119
- const values = Object.fromEntries(
120
- Object.entries(field.values).map(([opt]) => [opt, opt === optionOrValue])
121
- );
122
- return { ...fields, [key]: { ...field, values } };
123
- }
124
- return fields;
125
- });
126
- }, "updateFormData");
127
- const isValid = Object.values(formFields).every((field) => {
128
- if (!field.required) {
129
- return true;
130
- }
131
- return Object.values(field.values).some((value) => value === true);
132
- });
133
- const onSubmitForm = /* @__PURE__ */ __name((e) => {
134
- if (!isValid) {
135
- return;
136
- }
137
- e.preventDefault();
138
- setIsSubmitting(true);
139
- onComplete(
140
- Object.fromEntries(Object.entries(formFields).map(([key, field]) => [key, field.values]))
141
- );
142
- }, "onSubmitForm");
143
- return React.createElement(Modal, { defaultOpen: true, width: 420, onEscapeKeyDown: onDismiss }, React.createElement(Form, { onSubmit: onSubmitForm, id: "intent-survey-form" }, React.createElement(Content, null, React.createElement(Modal.Header, { onClose: onDismiss }, React.createElement(Modal.Title, null, "Help improve Storybook")), Object.keys(formFields).map((key) => {
144
- const field = formFields[key];
145
- return React.createElement(React.Fragment, { key }, React.createElement(Question, null, field.label), field.type === "checkbox" && React.createElement(Row, null, Object.entries(field.options).map(([opt, option]) => {
146
- const id = `${key}:${opt}`;
147
- return React.createElement("div", { key: id }, React.createElement(Label, { htmlFor: id }, React.createElement(
148
- Checkbox,
149
- {
150
- name: id,
151
- id,
152
- checked: field.values[opt],
153
- disabled: isSubmitting,
154
- onChange: (e) => updateFormData(key, opt, e.target.checked)
155
- }
156
- ), option.label));
157
- })), field.type === "select" && React.createElement(
158
- Form.Select,
159
- {
160
- name: key,
161
- id: key,
162
- value: Object.entries(field.values).find(([, isSelected]) => isSelected)?.[0] || "",
163
- required: field.required,
164
- disabled: isSubmitting,
165
- onChange: (e) => updateFormData(key, e.target.value)
166
- },
167
- React.createElement("option", { disabled: true, hidden: true, value: "" }, "Select an option..."),
168
- Object.entries(field.options).map(([opt, option]) => React.createElement("option", { key: opt, value: opt }, option.label))
169
- ));
170
- }), React.createElement(Actions, null, React.createElement(Button, { disabled: isSubmitting || !isValid, size: "medium", type: "submit", variant: "solid" }, "Submit")))));
171
- }, "IntentSurvey");
172
- function shuffle(array) {
173
- for (let i = array.length - 1; i > 0; i--) {
174
- const j = Math.floor(Math.random() * (i + 1));
175
- [array[i], array[j]] = [array[j], array[i]];
176
- }
177
- return array;
178
- }
179
- __name(shuffle, "shuffle");
180
- function shuffleObject(object) {
181
- return isChromatic() ? object : Object.fromEntries(shuffle(Object.entries(object)));
182
- }
183
- __name(shuffleObject, "shuffleObject");
184
-
185
- export {
186
- IntentSurvey
187
- };