@storybook/addon-a11y 10.0.0-rc.1 → 10.0.0-rc.3

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.
@@ -2,6 +2,7 @@
2
2
  var ADDON_ID = "storybook/a11y";
3
3
  var PANEL_ID = `${ADDON_ID}/panel`;
4
4
  var PARAM_KEY = `a11y`;
5
+ var UI_STATE_ID = `${ADDON_ID}/ui`;
5
6
  var RESULT = `${ADDON_ID}/result`;
6
7
  var REQUEST = `${ADDON_ID}/request`;
7
8
  var RUNNING = `${ADDON_ID}/running`;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  EVENTS,
3
3
  PANEL_ID
4
- } from "./chunk-ULDMWS76.js";
4
+ } from "./chunk-JZJ5QO7P.js";
5
5
  import {
6
6
  __export,
7
7
  __name
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  preview_exports
3
- } from "./_browser-chunks/chunk-XD4HDXPO.js";
3
+ } from "./_browser-chunks/chunk-W2OC36OK.js";
4
4
  import {
5
5
  PARAM_KEY
6
- } from "./_browser-chunks/chunk-ULDMWS76.js";
6
+ } from "./_browser-chunks/chunk-JZJ5QO7P.js";
7
7
  import {
8
8
  __name
9
9
  } from "./_browser-chunks/chunk-JFJ5UJ7Q.js";
package/dist/manager.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  PARAM_KEY,
7
7
  STATUS_TYPE_ID_A11Y,
8
8
  STATUS_TYPE_ID_COMPONENT_TEST
9
- } from "./_browser-chunks/chunk-ULDMWS76.js";
9
+ } from "./_browser-chunks/chunk-JZJ5QO7P.js";
10
10
  import {
11
11
  __name
12
12
  } from "./_browser-chunks/chunk-JFJ5UJ7Q.js";
@@ -631,14 +631,16 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
631
631
  }
632
632
  return value;
633
633
  }, [api]);
634
- const [results, setResults] = useAddonState(ADDON_ID);
635
- const [tab, setTab] = useState(() => {
636
- const [type] = a11ySelection?.split(".") ?? [];
637
- return type && Object.values(RuleType).includes(type) ? type : RuleType.VIOLATION;
634
+ const [state, setState] = useAddonState(ADDON_ID, {
635
+ ui: {
636
+ highlighted: false,
637
+ tab: RuleType.VIOLATION
638
+ },
639
+ results: void 0,
640
+ error: void 0,
641
+ status: getInitialStatus(manual)
638
642
  });
639
- const [error, setError] = useState(void 0);
640
- const [status, setStatus] = useState(getInitialStatus(manual));
641
- const [highlighted, setHighlighted] = useState(!!a11ySelection);
643
+ const { ui, results, error, status } = state;
642
644
  const { storyId } = useStorybookState();
643
645
  const currentStoryA11yStatusValue = experimental_useStatusStore(
644
646
  (allStatuses) => allStatuses[storyId]?.[STATUS_TYPE_ID_A11Y]?.value
@@ -649,16 +651,15 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
649
651
  const current = statuses[storyId]?.[STATUS_TYPE_ID_COMPONENT_TEST];
650
652
  const previous = previousStatuses[storyId]?.[STATUS_TYPE_ID_COMPONENT_TEST];
651
653
  if (current?.value === "status-value:error" && previous?.value !== "status-value:error") {
652
- setStatus("component-test-error");
654
+ setState((prev) => ({ ...prev, status: "component-test-error" }));
653
655
  }
654
656
  }
655
657
  );
656
658
  return unsubscribe;
657
- }, [storyId]);
658
- const handleToggleHighlight = useCallback(
659
- () => setHighlighted((prevHighlighted) => !prevHighlighted),
660
- []
661
- );
659
+ }, [setState, storyId]);
660
+ const handleToggleHighlight = useCallback(() => {
661
+ setState((prev) => ({ ...prev, ui: { ...prev.ui, highlighted: !prev.ui.highlighted } }));
662
+ }, [setState]);
662
663
  const [selectedItems, setSelectedItems] = useState(() => {
663
664
  const initialValue = /* @__PURE__ */ new Map();
664
665
  if (a11ySelection && /^[a-z]+.[a-z-]+.[0-9]+$/.test(a11ySelection)) {
@@ -668,9 +669,9 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
668
669
  return initialValue;
669
670
  });
670
671
  const allExpanded = useMemo(() => {
671
- const currentResults = results?.[tab];
672
- return currentResults?.every((result) => selectedItems.has(`${tab}.${result.id}`)) ?? false;
673
- }, [results, selectedItems, tab]);
672
+ const currentResults = results?.[ui.tab];
673
+ return currentResults?.every((result) => selectedItems.has(`${ui.tab}.${result.id}`)) ?? false;
674
+ }, [results, selectedItems, ui.tab]);
674
675
  const toggleOpen = useCallback(
675
676
  (event, type, item) => {
676
677
  event.stopPropagation();
@@ -685,38 +686,45 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
685
686
  const handleExpandAll = useCallback(() => {
686
687
  setSelectedItems(
687
688
  (prev) => new Map(
688
- results?.[tab]?.map((result) => {
689
- const key = `${tab}.${result.id}`;
689
+ results?.[ui.tab]?.map((result) => {
690
+ const key = `${ui.tab}.${result.id}`;
690
691
  return [key, prev.get(key) ?? `${key}.1`];
691
692
  }) ?? []
692
693
  )
693
694
  );
694
- }, [results, tab]);
695
+ }, [results, ui.tab]);
695
696
  const handleSelectionChange = useCallback((key) => {
696
697
  const [type, id] = key.split(".");
697
698
  setSelectedItems((prev) => new Map(prev.set(`${type}.${id}`, key)));
698
699
  }, []);
699
- const handleError = useCallback((err) => {
700
- setStatus("error");
701
- setError(err);
702
- }, []);
700
+ const handleError = useCallback(
701
+ (err) => {
702
+ setState((prev) => ({ ...prev, status: "error", error: err }));
703
+ },
704
+ [setState]
705
+ );
703
706
  const handleResult = useCallback(
704
707
  (axeResults, id) => {
705
708
  if (storyId === id) {
706
- setStatus("ran");
707
- setResults(axeResults);
709
+ setState((prev) => ({ ...prev, status: "ran", results: axeResults }));
708
710
  setTimeout(() => {
709
- if (status === "ran") {
710
- setStatus("ready");
711
- }
712
- if (selectedItems.size === 1) {
713
- const [key] = selectedItems.values();
714
- document.getElementById(key)?.scrollIntoView({ behavior: "smooth", block: "center" });
715
- }
711
+ setState((prev) => {
712
+ if (prev.status === "ran") {
713
+ return { ...prev, status: "ready" };
714
+ }
715
+ return prev;
716
+ });
717
+ setSelectedItems((prev) => {
718
+ if (prev.size === 1) {
719
+ const [key] = prev.values();
720
+ document.getElementById(key)?.scrollIntoView({ behavior: "smooth", block: "center" });
721
+ }
722
+ return prev;
723
+ });
716
724
  }, 900);
717
725
  }
718
726
  },
719
- [setResults, status, storyId, selectedItems]
727
+ [storyId, setState, setSelectedItems]
720
728
  );
721
729
  const handleSelect = useCallback(
722
730
  (itemId, details) => {
@@ -752,14 +760,16 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
752
760
  const handleReset = useCallback(
753
761
  ({ newPhase }) => {
754
762
  if (newPhase === "loading") {
755
- setResults(void 0);
756
- setStatus(manual ? "manual" : "initial");
757
- }
758
- if (newPhase === "afterEach" && !manual) {
759
- setStatus("running");
763
+ setState((prev) => ({
764
+ ...prev,
765
+ results: void 0,
766
+ status: manual ? "manual" : "initial"
767
+ }));
768
+ } else if (newPhase === "afterEach" && !manual) {
769
+ setState((prev) => ({ ...prev, status: "running" }));
760
770
  }
761
771
  },
762
- [manual, setResults]
772
+ [manual, setState]
763
773
  );
764
774
  const emit = useChannel(
765
775
  {
@@ -770,16 +780,16 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
770
780
  [STORY_RENDER_PHASE_CHANGED]: handleReset,
771
781
  [STORY_FINISHED]: handleReport,
772
782
  [STORY_HOT_UPDATED]: () => {
773
- setStatus("running");
783
+ setState((prev) => ({ ...prev, status: "running" }));
774
784
  emit(EVENTS.MANUAL, storyId, parameters);
775
785
  }
776
786
  },
777
787
  [handleReset, handleReport, handleSelect, handleError, handleResult, parameters, storyId]
778
788
  );
779
789
  const handleManual = useCallback(() => {
780
- setStatus("running");
790
+ setState((prev) => ({ ...prev, status: "running" }));
781
791
  emit(EVENTS.MANUAL, storyId, parameters);
782
- }, [emit, parameters, storyId]);
792
+ }, [emit, parameters, setState, storyId]);
783
793
  const handleCopyLink = useCallback(async (linkPath) => {
784
794
  const { createCopyToClipboardFunction } = await import("storybook/internal/components");
785
795
  await createCopyToClipboardFunction()(`${window.location.origin}${linkPath}`);
@@ -789,18 +799,31 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
789
799
  [emit]
790
800
  );
791
801
  useEffect(() => {
792
- setStatus(getInitialStatus(manual));
793
- }, [getInitialStatus, manual]);
802
+ setState((prev) => ({ ...prev, status: getInitialStatus(manual) }));
803
+ }, [getInitialStatus, manual, setState]);
794
804
  const isInitial = status === "initial";
805
+ useEffect(() => {
806
+ if (!a11ySelection) {
807
+ return;
808
+ }
809
+ setState((prev) => {
810
+ const update = { ...prev.ui, highlighted: true };
811
+ const [type] = a11ySelection.split(".") ?? [];
812
+ if (type && Object.values(RuleType).includes(type)) {
813
+ update.tab = type;
814
+ }
815
+ return { ...prev, ui: update };
816
+ });
817
+ }, [a11ySelection]);
795
818
  useEffect(() => {
796
819
  emit(REMOVE_HIGHLIGHT, `${ADDON_ID}/selected`);
797
820
  emit(REMOVE_HIGHLIGHT, `${ADDON_ID}/others`);
798
- if (!highlighted || isInitial) {
821
+ if (!ui.highlighted || isInitial) {
799
822
  return;
800
823
  }
801
824
  const selected = Array.from(selectedItems.values()).flatMap((key) => {
802
825
  const [type, id, number] = key.split(".");
803
- if (type !== tab) {
826
+ if (type !== ui.tab) {
804
827
  return [];
805
828
  }
806
829
  const result = results?.[type]?.find((r) => r.id === id);
@@ -813,7 +836,7 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
813
836
  priority: 1,
814
837
  selectors: selected,
815
838
  styles: {
816
- outline: `1px solid color-mix(in srgb, ${colorsByType[tab]}, transparent 30%)`,
839
+ outline: `1px solid color-mix(in srgb, ${colorsByType[ui.tab]}, transparent 30%)`,
817
840
  backgroundColor: "transparent"
818
841
  },
819
842
  hoverStyles: {
@@ -822,17 +845,17 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
822
845
  focusStyles: {
823
846
  backgroundColor: "transparent"
824
847
  },
825
- menu: results?.[tab].map((result) => {
848
+ menu: results?.[ui.tab].map((result) => {
826
849
  const selectors = result.nodes.flatMap((n) => n.target).map(String).filter((e) => selected.includes(e));
827
850
  return [
828
851
  {
829
- id: `${tab}.${result.id}:info`,
852
+ id: `${ui.tab}.${result.id}:info`,
830
853
  title: getTitleForAxeResult(result),
831
854
  description: getFriendlySummaryForAxeResult(result),
832
855
  selectors
833
856
  },
834
857
  {
835
- id: `${tab}.${result.id}`,
858
+ id: `${ui.tab}.${result.id}`,
836
859
  iconLeft: "info",
837
860
  iconRight: "shareAlt",
838
861
  title: "Learn how to resolve this violation",
@@ -843,14 +866,14 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
843
866
  })
844
867
  });
845
868
  }
846
- const others = results?.[tab].flatMap((r) => r.nodes.flatMap((n) => n.target).map(String)).filter((e) => ![...unhighlightedSelectors, ...selected].includes(e));
869
+ const others = results?.[ui.tab].flatMap((r) => r.nodes.flatMap((n) => n.target).map(String)).filter((e) => ![...unhighlightedSelectors, ...selected].includes(e));
847
870
  if (others?.length) {
848
871
  emit(HIGHLIGHT, {
849
872
  id: `${ADDON_ID}/others`,
850
873
  selectors: others,
851
874
  styles: {
852
- outline: `1px solid color-mix(in srgb, ${colorsByType[tab]}, transparent 30%)`,
853
- backgroundColor: `color-mix(in srgb, ${colorsByType[tab]}, transparent 60%)`
875
+ outline: `1px solid color-mix(in srgb, ${colorsByType[ui.tab]}, transparent 30%)`,
876
+ backgroundColor: `color-mix(in srgb, ${colorsByType[ui.tab]}, transparent 60%)`
854
877
  },
855
878
  hoverStyles: {
856
879
  outlineWidth: "2px"
@@ -858,17 +881,17 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
858
881
  focusStyles: {
859
882
  backgroundColor: "transparent"
860
883
  },
861
- menu: results?.[tab].map((result) => {
884
+ menu: results?.[ui.tab].map((result) => {
862
885
  const selectors = result.nodes.flatMap((n) => n.target).map(String).filter((e) => !selected.includes(e));
863
886
  return [
864
887
  {
865
- id: `${tab}.${result.id}:info`,
888
+ id: `${ui.tab}.${result.id}:info`,
866
889
  title: getTitleForAxeResult(result),
867
890
  description: getFriendlySummaryForAxeResult(result),
868
891
  selectors
869
892
  },
870
893
  {
871
- id: `${tab}.${result.id}`,
894
+ id: `${ui.tab}.${result.id}`,
872
895
  iconLeft: "info",
873
896
  iconRight: "shareAlt",
874
897
  title: "Learn how to resolve this violation",
@@ -879,7 +902,7 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
879
902
  })
880
903
  });
881
904
  }
882
- }, [isInitial, emit, highlighted, results, tab, selectedItems]);
905
+ }, [isInitial, emit, ui.highlighted, results, ui.tab, selectedItems]);
883
906
  const discrepancy = useMemo(() => {
884
907
  if (!currentStoryA11yStatusValue) {
885
908
  return null;
@@ -903,13 +926,19 @@ var A11yContextProvider = /* @__PURE__ */ __name((props) => {
903
926
  value: {
904
927
  parameters,
905
928
  results,
906
- highlighted,
929
+ highlighted: ui.highlighted,
907
930
  toggleHighlight: handleToggleHighlight,
908
- tab,
909
- setTab,
931
+ tab: ui.tab,
932
+ setTab: useCallback(
933
+ (type) => setState((prev) => ({ ...prev, ui: { ...prev.ui, tab: type } })),
934
+ [setState]
935
+ ),
910
936
  handleCopyLink,
911
937
  status,
912
- setStatus,
938
+ setStatus: useCallback(
939
+ (status2) => setState((prev) => ({ ...prev, status: status2 })),
940
+ [setState]
941
+ ),
913
942
  error,
914
943
  handleManual,
915
944
  discrepancy,
@@ -3377,9 +3406,17 @@ var VisionSimulator = /* @__PURE__ */ __name(() => {
3377
3406
  var Title3 = /* @__PURE__ */ __name(() => {
3378
3407
  const api = useStorybookApi3();
3379
3408
  const selectedPanel = api.getSelectedPanel();
3380
- const [addonState] = useAddonState2(ADDON_ID);
3381
- const violationsNb = addonState?.violations?.length || 0;
3382
- const incompleteNb = addonState?.incomplete?.length || 0;
3409
+ const [{ results }] = useAddonState2(ADDON_ID, {
3410
+ ui: {
3411
+ highlighted: false,
3412
+ tab: RuleType.VIOLATION
3413
+ },
3414
+ results: void 0,
3415
+ error: void 0,
3416
+ status: "initial"
3417
+ });
3418
+ const violationsNb = results?.violations?.length ?? 0;
3419
+ const incompleteNb = results?.incomplete?.length ?? 0;
3383
3420
  const count = violationsNb + incompleteNb;
3384
3421
  const suffix = count === 0 ? null : React10.createElement(Badge3, { compact: true, status: selectedPanel === PANEL_ID ? "active" : "neutral" }, count);
3385
3422
  return React10.createElement("div", { style: { display: "flex", alignItems: "center", gap: 6 } }, React10.createElement("span", null, "Accessibility"), suffix);
@@ -1,10 +1,10 @@
1
- import CJS_COMPAT_NODE_URL_cwc04mhl6w from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_cwc04mhl6w from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_cwc04mhl6w from "node:module";
1
+ import CJS_COMPAT_NODE_URL_g32lnsegga7 from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_g32lnsegga7 from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_g32lnsegga7 from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_cwc04mhl6w.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_cwc04mhl6w.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_cwc04mhl6w.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_g32lnsegga7.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_g32lnsegga7.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_g32lnsegga7.createRequire(import.meta.url);
8
8
 
9
9
  // ------------------------------------------------------------
10
10
  // end of CJS compatibility banner, injected by Storybook's esbuild configuration
package/dist/preview.js CHANGED
@@ -2,8 +2,8 @@ import {
2
2
  afterEach,
3
3
  initialGlobals,
4
4
  parameters
5
- } from "./_browser-chunks/chunk-XD4HDXPO.js";
6
- import "./_browser-chunks/chunk-ULDMWS76.js";
5
+ } from "./_browser-chunks/chunk-W2OC36OK.js";
6
+ import "./_browser-chunks/chunk-JZJ5QO7P.js";
7
7
  import "./_browser-chunks/chunk-JFJ5UJ7Q.js";
8
8
  export {
9
9
  afterEach,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/addon-a11y",
3
- "version": "10.0.0-rc.1",
3
+ "version": "10.0.0-rc.3",
4
4
  "description": "Storybook Addon A11y: Test UI component compliance with WCAG web accessibility standards",
5
5
  "keywords": [
6
6
  "a11y",
@@ -74,7 +74,7 @@
74
74
  "vitest-axe": "^0.1.0"
75
75
  },
76
76
  "peerDependencies": {
77
- "storybook": "^10.0.0-rc.1"
77
+ "storybook": "^10.0.0-rc.3"
78
78
  },
79
79
  "publishConfig": {
80
80
  "access": "public"