Skip to content

Commit

Permalink
refactor(avatar): ♻️ update avatar stories & imports
Browse files Browse the repository at this point in the history
  • Loading branch information
navin-moorthy committed Jul 4, 2022
1 parent c554bf7 commit 09a710b
Show file tree
Hide file tree
Showing 35 changed files with 228 additions and 151 deletions.
8 changes: 7 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@
// https://github.com/lydell/eslint-plugin-simple-import-sort#custom-grouping
"groups": [
// Packages. `react` related packages come first.
["^react", "^ariakit", "^ariakit-utils", "^@?\\w"],
[
"^react",
"^ariakit-utils/system",
"^ariakit",
"^ariakit-utils",
"^@?\\w"
],
// Parent imports. Put `..` last.
["^\\.\\.(?!/?$)", "^\\.\\./?$"],
// Other relative imports. Put same-folder imports and `.` last.
Expand Down
24 changes: 23 additions & 1 deletion src/accordion/__utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createStoreContext } from "ariakit-utils/store";

import { AccordionState } from "./accordion-state";
import { AccordionState, Item } from "./accordion-state";

export const AccordionContext = createStoreContext<AccordionState>();

Expand All @@ -11,3 +11,25 @@ export const getSelectedId = (state?: AccordionState, id?: string) => {

return state?.selectedId === id;
};

export const findEnabledAccordionById = (items: Item[], id?: string | null) => {
return items.find(item => item.id === id && !item.disabled && !item.dimmed);
};

export const findFirstEnabledAccordion = (items: Item[]) => {
return items.find(item => !item.disabled && !item.dimmed);
};

export const getAccordionId = (
panels?: AccordionState["panels"],
id?: string,
) => {
if (!id) return;

return panels?.items.find(panel => panel.id === id)?.accordionId;
};

export const getPanelId = (panels?: AccordionState["panels"], id?: string) => {
if (!id) return;
return panels?.items.find(panel => panel.accordionId === id)?.id;
};
4 changes: 2 additions & 2 deletions src/accordion/accordion-base.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { CompositeOptions, useComposite } from "ariakit";
import { useStoreProvider } from "ariakit-utils/store";
import {
createComponent,
createElement,
createHook,
} from "ariakit-utils/system";
import { CompositeOptions, useComposite } from "ariakit";
import { useStoreProvider } from "ariakit-utils/store";
import { As, Props } from "ariakit-utils/types";

import { AccordionContext } from "./__utils";
Expand Down
9 changes: 2 additions & 7 deletions src/accordion/accordion-disclosure.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import { FocusEvent, MouseEvent, useCallback } from "react";
import { createElement, createHook } from "ariakit-utils/system";
import {
CompositeItemOptions,
useCompositeItem,
} from "ariakit/composite/composite-item";
import { Item } from "ariakit/ts/collection/__utils";
import { useEvent, useId } from "ariakit-utils/hooks";
import { createMemoComponent, useStore } from "ariakit-utils/store";
import { createElement, createHook } from "ariakit-utils/system";
import { As, Props } from "ariakit-utils/types";

import { AccordionContext, getSelectedId } from "./__utils";
import { AccordionContext, getPanelId, getSelectedId } from "./__utils";
import { AccordionState } from "./accordion-state";

function getPanelId(panels?: AccordionState["panels"], id?: string) {
if (!id) return;
return panels?.items.find(panel => panel.accordionId === id)?.id;
}

/**
* A component hook that returns props that can be passed to `Role` or any other
* Ariakit component to render a accordion element. The underlying element must be
Expand Down
18 changes: 6 additions & 12 deletions src/accordion/accordion-panel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { useCallback, useEffect, useRef, useState } from "react";
import {
createComponent,
createElement,
createHook,
} from "ariakit-utils/system";
import {
CollectionItemOptions,
useCollectionItem,
Expand All @@ -13,22 +18,11 @@ import { Item } from "ariakit/ts/collection/__utils";
import { getAllTabbableIn } from "ariakit-utils/focus";
import { useForkRef, useId } from "ariakit-utils/hooks";
import { useStore } from "ariakit-utils/store";
import {
createComponent,
createElement,
createHook,
} from "ariakit-utils/system";
import { As, Props } from "ariakit-utils/types";

import { AccordionContext, getSelectedId } from "./__utils";
import { AccordionContext, getAccordionId, getSelectedId } from "./__utils";
import { AccordionState } from "./accordion-state";

function getAccordionId(panels?: AccordionState["panels"], id?: string) {
if (!id) return;

return panels?.items.find(panel => panel.id === id)?.accordionId;
}

/**
* A component hook that returns props that can be passed to `Role` or any other
* Ariakit component to render a accordion panel element.
Expand Down
122 changes: 48 additions & 74 deletions src/accordion/accordion-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,7 @@ import { useControlledState, useLiveRef } from "ariakit-utils/hooks";
import { useStorePublisher } from "ariakit-utils/store";
import { SetState } from "ariakit-utils/types";

type Item = CompositeState["items"][number] & {
dimmed?: boolean;
};

type Panel = CollectionState["items"][number] & {
id: string;
accordionId?: string | null;
};

function findEnabledAccordionById(items: Item[], id?: string | null) {
return items.find(item => item.id === id && !item.disabled && !item.dimmed);
}

function findFirstEnabledAccordion(items: Item[]) {
return items.find(item => !item.disabled && !item.dimmed);
}
import { findEnabledAccordionById, findFirstEnabledAccordion } from "./__utils";

/**
* Provides state for the `Accordion` components.
Expand Down Expand Up @@ -76,74 +61,54 @@ export function useAccordionState({
[allowMultiple, setSelectedId],
);

// Automatically set selectedId if it's undefined.
useEffect(() => {
if (!shouldSelectFirstId) return;
if (allowToggle) return;
if (selectedId !== undefined) return;

// First, we try to set selectedId based on the current active accordion.
const activeId = compositeRef.current.activeId;
if (!activeId) return;

const accordion = findEnabledAccordionById(composite.items, activeId);
if (!accordion) {
// If there's no active accordion or the active accordion is dimmed, we get the first
// enabled accordion instead.
const firstEnabledAccordion = findFirstEnabledAccordion(composite.items);
if (!firstEnabledAccordion) return;
// First, we try to set selectedId based on the current active accordion.
const setActiveSelectedId = useCallback(
(isFirstEnabledAccordionSelected: boolean) => {
if (
isFirstEnabledAccordionSelected &&
firstEnabledAccordionSelected.current === true
)
return;

select(firstEnabledAccordion?.id);
const activeId = compositeRef.current.activeId;
if (!activeId) return;

return;
}
const accordion = findEnabledAccordionById(composite.items, activeId);
if (!accordion) {
// If there's no active accordion or the active accordion is dimmed, we get the first
// enabled accordion instead.
const firstEnabledAccordion = findFirstEnabledAccordion(
composite.items,
);
if (!firstEnabledAccordion) return;

select(activeId);
select(firstEnabledAccordion?.id);

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
allowToggle,
shouldSelectFirstId,
selectedId,
composite.items,
allowMultiple,
setSelectedId,
]);

// Automatically set selectedId if it's undefined.
useEffect(() => {
if (!shouldSelectFirstId || !allowToggle) return;
if (firstEnabledAccordionSelected.current === true) return;
return;
}

// First, we try to set selectedId based on the current active accordion.
const activeId = compositeRef.current.activeId;
if (!activeId) return;
if (isFirstEnabledAccordionSelected === true) {
firstEnabledAccordionSelected.current = true;
}

const accordion = findEnabledAccordionById(composite.items, activeId);
if (!accordion) {
// If there's no active accordion or the active accordion is dimmed, we get the first
// enabled accordion instead.
const firstEnabledAccordion = findFirstEnabledAccordion(composite.items);
if (!firstEnabledAccordion) return;
select(activeId);
},
[composite.items, compositeRef, select],
);

select(firstEnabledAccordion?.id);
// Automatically set selectedId if it's undefined if !allowToggle
useEffect(() => {
if (!shouldSelectFirstId || allowToggle || selectedId !== undefined) return;

return;
}
setActiveSelectedId(false);
}, [allowToggle, selectedId, setActiveSelectedId, shouldSelectFirstId]);

firstEnabledAccordionSelected.current = true;
// Automatically set selectedId if it's undefined if allowToggle
useEffect(() => {
if (!shouldSelectFirstId || !allowToggle) return;

select(activeId);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
allowToggle,
shouldSelectFirstId,
selectedId,
composite.items,
setSelectedId,
allowMultiple,
select,
]);
setActiveSelectedId(true);
}, [allowToggle, shouldSelectFirstId, setActiveSelectedId]);

// Keep panels accordionIds in sync with the current accordions.
useEffect(() => {
Expand Down Expand Up @@ -229,6 +194,15 @@ export function useAccordionState({
return useStorePublisher(state);
}

export type Item = CompositeState["items"][number] & {
dimmed?: boolean;
};

export type Panel = CollectionState["items"][number] & {
id: string;
accordionId?: string | null;
};

export type AccordionState = CompositeState<Item> & {
/**
* Whether the accordion panels can be toggled on click. If it's set to
Expand Down
4 changes: 3 additions & 1 deletion src/accordion/stories/AccordionBasic.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import {
useAccordionState,
} from "../../index";

export const AccordionBasic: React.FC<AccordionStateProps> = props => {
export type AccordionBasicProps = AccordionStateProps;

export const AccordionBasic: React.FC<AccordionBasicProps> = props => {
const state = useAccordionState(props);

return (
Expand Down
44 changes: 36 additions & 8 deletions src/accordion/stories/AccordionBasic.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentMeta, ComponentStoryObj } from "@storybook/react";

import { createPreviewTabs } from "../../../.storybook/utils";
import { createControls, createPreviewTabs } from "../../../.storybook/utils";

import js from "./templates/AccordionBasicJsx";
import ts from "./templates/AccordionBasicTsx";
Expand All @@ -16,34 +16,62 @@ export default {
layout: "centered",
preview: createPreviewTabs({ js, ts }),
},
argTypes: createControls({
ignore: [
"items",
"setItems",
"orientation",
"virtualFocus",
"rtl",
"focusLoop",
"focusWrap",
"focusShift",
"moves",
"includesBaseElement",
"activeId",
"defaultActiveId",
"setMoves",
"setActiveId",
"selectedId",
"defaultSelectedId",
"setSelectedId",
],
}),
} as Meta;

export const Default: Story = {};

export const DefaultFirstIdSelected: Story = {
args: { shouldSelectFirstId: true },
...Default,
args: { ...Default.args, shouldSelectFirstId: true },
};

export const DefaultSelected: Story = {
args: { defaultSelectedId: "Trigger 3" },
...Default,
args: { ...Default.args, defaultSelectedId: "Trigger 3" },
};

export const SelectOnMove: Story = {
args: { selectOnMove: true },
...Default,
args: { ...Default.args, selectOnMove: true },
};

export const NoLoop: Story = {
args: { focusLoop: false },
...Default,
args: { ...Default.args, focusLoop: false },
};

export const AllowToggle: Story = {
args: { allowToggle: true },
...Default,
args: { ...Default.args, allowToggle: true },
};

export const DefaultFirstIdToggle: Story = {
args: { shouldSelectFirstId: true, allowToggle: true },
...Default,
args: { ...Default.args, shouldSelectFirstId: true, allowToggle: true },
};

export const SelectOnMoveToggle: Story = {
args: { selectOnMove: true, allowToggle: true },
...Default,
args: { ...Default.args, selectOnMove: true, allowToggle: true },
};
6 changes: 4 additions & 2 deletions src/accordion/stories/AccordionMultiple.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import {
useAccordionState,
} from "../../index";

export const AccordionMultiple: React.FC<AccordionStateProps> = props => {
const state = useAccordionState({ allowMultiple: true, ...props });
export type AccordionMultipleProps = AccordionStateProps;

export const AccordionMultiple: React.FC<AccordionMultipleProps> = props => {
const state = useAccordionState(props);

return (
<Accordion state={state}>
Expand Down
Loading

0 comments on commit 09a710b

Please sign in to comment.