diff --git a/frontend/__tests__/components/common/Conditional.spec.tsx b/frontend/__tests__/components/common/Conditional.spec.tsx deleted file mode 100644 index 267cdf13dfc8..000000000000 --- a/frontend/__tests__/components/common/Conditional.spec.tsx +++ /dev/null @@ -1,214 +0,0 @@ -import { cleanup, render, screen } from "@solidjs/testing-library"; -import { createSignal } from "solid-js"; -import { afterEach, describe, expect, it } from "vitest"; - -import { Conditional } from "../../../src/ts/components/common/Conditional"; - -describe("Conditional", () => { - afterEach(() => { - cleanup(); - }); - - describe("static rendering", () => { - it("renders then when if is true", () => { - render(() => then content} />); - - expect(screen.getByText("then content")).toBeInTheDocument(); - }); - - it("renders then when if is a truthy object", () => { - render(() => ( - then content} /> - )); - - expect(screen.getByText("then content")).toBeInTheDocument(); - }); - - it("renders then when if is a truthy string", () => { - render(() => then content} />); - - expect(screen.getByText("then content")).toBeInTheDocument(); - }); - - it("renders else fallback when if is false", () => { - render(() => ( - then content} - else={
else content
} - /> - )); - - expect(screen.queryByText("then content")).not.toBeInTheDocument(); - expect(screen.getByText("else content")).toBeInTheDocument(); - }); - - it("renders else fallback when if is null", () => { - render(() => ( - then content} - else={
else content
} - /> - )); - - expect(screen.queryByText("then content")).not.toBeInTheDocument(); - expect(screen.getByText("else content")).toBeInTheDocument(); - }); - - it("renders else fallback when if is undefined", () => { - render(() => ( - then content} - else={
else content
} - /> - )); - - expect(screen.queryByText("then content")).not.toBeInTheDocument(); - expect(screen.getByText("else content")).toBeInTheDocument(); - }); - - it("renders else fallback when if is 0", () => { - render(() => ( - then content} - else={
else content
} - /> - )); - - expect(screen.queryByText("then content")).not.toBeInTheDocument(); - expect(screen.getByText("else content")).toBeInTheDocument(); - }); - - it("renders nothing when if is falsy and else is not provided", () => { - const { container } = render(() => ( - then content} /> - )); - - expect(screen.queryByText("then content")).not.toBeInTheDocument(); - expect(container.firstChild).toBeNull(); - }); - }); - - describe("then as function", () => { - it("passes the truthy value to then function", () => { - const obj: { label: string } | null = { label: "hello" }; - render(() => ( -
{value().label}
} /> - )); - - expect(screen.getByText("hello")).toBeInTheDocument(); - }); - - it("does not call then function when if is falsy", () => { - const obj: { label: string } | null = null; - render(() => ( - then content} - else={
else content
} - /> - )); - - expect(screen.queryByText("then content")).not.toBeInTheDocument(); - expect(screen.getByText("else content")).toBeInTheDocument(); - }); - }); - - describe("reactivity", () => { - it("switches from else to then when if becomes truthy", async () => { - const [condition, setCondition] = createSignal(false); - - render(() => ( - then content} - else={
else content
} - /> - )); - - expect(screen.queryByText("then content")).not.toBeInTheDocument(); - expect(screen.getByText("else content")).toBeInTheDocument(); - - setCondition(true); - - expect(screen.getByText("then content")).toBeInTheDocument(); - expect(screen.queryByText("else content")).not.toBeInTheDocument(); - }); - - it("switches from then to else when if becomes falsy", async () => { - const [condition, setCondition] = createSignal(true); - - render(() => ( - then content} - else={
else content
} - /> - )); - - expect(screen.getByText("then content")).toBeInTheDocument(); - - setCondition(false); - - expect(screen.queryByText("then content")).not.toBeInTheDocument(); - expect(screen.getByText("else content")).toBeInTheDocument(); - }); - - it("then JSXElement updates reactively when inner signal changes", async () => { - const [label, setLabel] = createSignal("initial"); - - render(() => {label()}} />); - - expect(screen.getByText("initial")).toBeInTheDocument(); - - setLabel("updated"); - - expect(screen.getByText("updated")).toBeInTheDocument(); - }); - - it("then JSXElement updates reactively when if changes from a signal", async () => { - const [data, setData] = createSignal(undefined); - - render(() => ( - {data()}} - else={
no data
} - /> - )); - - expect(screen.getByText("no data")).toBeInTheDocument(); - expect(screen.queryByTestId("content")).not.toBeInTheDocument(); - - setData("resolved"); - - expect(screen.getByTestId("content")).toHaveTextContent("resolved"); - expect(screen.queryByText("no data")).not.toBeInTheDocument(); - }); - - it("then function value accessor tracks reactive if", () => { - const [data, setData] = createSignal<{ name: string } | null>(null); - - render(() => ( -
{value().name}
} - else={
no data
} - /> - )); - - expect(screen.getByText("no data")).toBeInTheDocument(); - - setData({ name: "Alice" }); - - expect(screen.getByTestId("content")).toHaveTextContent("Alice"); - - setData({ name: "Bob" }); - - expect(screen.getByTestId("content")).toHaveTextContent("Bob"); - }); - }); -}); diff --git a/frontend/__tests__/components/common/anime/AnimeConditional.spec.tsx b/frontend/__tests__/components/common/anime/AnimeConditional.spec.tsx deleted file mode 100644 index a120611baebf..000000000000 --- a/frontend/__tests__/components/common/anime/AnimeConditional.spec.tsx +++ /dev/null @@ -1,230 +0,0 @@ -import { cleanup, render, screen } from "@solidjs/testing-library"; -import { createSignal } from "solid-js"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; - -const { mockAnimate } = vi.hoisted(() => ({ - mockAnimate: vi.fn().mockImplementation(() => ({ - pause: vi.fn(), - then: vi.fn((cb: () => void) => { - cb(); - return Promise.resolve(); - }), - })), -})); - -vi.mock("animejs", () => ({ - animate: mockAnimate, -})); - -vi.mock("../../../../src/ts/utils/misc", () => ({ - applyReducedMotion: vi.fn((duration: number) => duration), -})); - -import { AnimeConditional } from "../../../../src/ts/components/common/anime/AnimeConditional"; - -describe("AnimeConditional", () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - - afterEach(() => { - cleanup(); - }); - - it("renders `then` content when `if` is truthy", () => { - render(() => ( - then} - else={
else
} - /> - )); - - expect(screen.getByTestId("then-content")).toBeInTheDocument(); - expect(screen.queryByTestId("else-content")).not.toBeInTheDocument(); - }); - - it("renders `else` content when `if` is falsy", () => { - render(() => ( - then} - else={
else
} - /> - )); - - expect(screen.queryByTestId("then-content")).not.toBeInTheDocument(); - expect(screen.getByTestId("else-content")).toBeInTheDocument(); - }); - - it("renders `else` content when `if` is null", () => { - render(() => ( - then} - else={
else
} - /> - )); - - expect(screen.queryByTestId("then-content")).not.toBeInTheDocument(); - expect(screen.getByTestId("else-content")).toBeInTheDocument(); - }); - - it("switches reactively from `then` to `else`", () => { - const [condition, setCondition] = createSignal(true); - - render(() => ( - then} - else={
else
} - /> - )); - - expect(screen.getByTestId("then-content")).toBeInTheDocument(); - - setCondition(false); - - expect(screen.queryByTestId("then-content")).not.toBeInTheDocument(); - expect(screen.getByTestId("else-content")).toBeInTheDocument(); - }); - - it("switches reactively from `else` to `then`", () => { - const [condition, setCondition] = createSignal(false); - - render(() => ( - then} - else={
else
} - /> - )); - - expect(screen.getByTestId("else-content")).toBeInTheDocument(); - - setCondition(true); - - expect(screen.getByTestId("then-content")).toBeInTheDocument(); - expect(screen.queryByTestId("else-content")).not.toBeInTheDocument(); - }); - - it("supports `then` as a function and passes the truthy value", () => { - const obj = { label: "hello" }; - render(() => ( -
{value().label}
} - /> - )); - - expect(screen.getByTestId("fn-content")).toHaveTextContent("hello"); - }); - - it("does not throw without `else` prop", () => { - expect(() => { - render(() => ( - then} - /> - )); - }).not.toThrow(); - - expect(screen.getByTestId("then-content")).toBeInTheDocument(); - }); - - it("does not throw on mount/unmount", () => { - const [show, setShow] = createSignal(true); - - expect(() => { - render(() => ( - then} - else={
else
} - /> - )); - }).not.toThrow(); - - expect(() => setShow(false)).not.toThrow(); - expect(() => setShow(true)).not.toThrow(); - }); - - describe("default animations (opacity fade)", () => { - it("applies default opacity animate on `then` branch", () => { - render(() => then} />); - - expect(mockAnimate).toHaveBeenCalledWith( - expect.any(HTMLElement), - expect.objectContaining({ opacity: 1, duration: 125 }), - ); - }); - - it("applies default opacity initial state on `then` branch", () => { - render(() => then} />); - - // Initial call: opacity:0 with duration:0 - expect(mockAnimate).toHaveBeenCalledWith( - expect.any(HTMLElement), - expect.objectContaining({ opacity: 0, duration: 0 }), - ); - }); - }); - - describe("custom animeProps", () => { - it("uses custom animate params when animeProps provided", () => { - render(() => ( - then} - animeProps={{ - initial: { opacity: 0, translateY: -10 }, - animate: { opacity: 1, translateY: 0, duration: 400 }, - exit: { opacity: 0, translateY: -10, duration: 200 }, - }} - /> - )); - - expect(mockAnimate).toHaveBeenCalledWith( - expect.any(HTMLElement), - expect.objectContaining({ opacity: 1, translateY: 0, duration: 400 }), - ); - }); - - it("uses custom initial state when animeProps provided", () => { - render(() => ( - then} - animeProps={{ - initial: { opacity: 0, translateY: -10 }, - animate: { opacity: 1, translateY: 0, duration: 400 }, - }} - /> - )); - - // Initial state applied with duration:0 - expect(mockAnimate).toHaveBeenCalledWith( - expect.any(HTMLElement), - expect.objectContaining({ opacity: 0, translateY: -10, duration: 0 }), - ); - }); - }); - - it("exitBeforeEnter prop does not throw on condition change", () => { - const [cond, setCond] = createSignal(true); - - expect(() => { - render(() => ( - then} - else={
else
} - /> - )); - }).not.toThrow(); - - expect(() => setCond(false)).not.toThrow(); - }); -}); diff --git a/frontend/src/ts/components/common/AsyncContent.tsx b/frontend/src/ts/components/common/AsyncContent.tsx index 45c65fbab2b3..4890f7635bd2 100644 --- a/frontend/src/ts/components/common/AsyncContent.tsx +++ b/frontend/src/ts/components/common/AsyncContent.tsx @@ -12,7 +12,6 @@ import { import { showErrorNotification } from "../../states/notifications"; import { createErrorMessage } from "../../utils/error"; import { typedKeys } from "../../utils/misc"; -import { Conditional } from "./Conditional"; import { LoadingCircle } from "./LoadingCircle"; type AsyncEntry = { @@ -154,15 +153,16 @@ export default function AsyncContent( {loader()} - {props.children(value())}} - else={ + {props.children(value())} } - /> + > + {props.children(value())} + } > diff --git a/frontend/src/ts/components/common/Button.tsx b/frontend/src/ts/components/common/Button.tsx index 6527f74c9643..4510ee5e90dc 100644 --- a/frontend/src/ts/components/common/Button.tsx +++ b/frontend/src/ts/components/common/Button.tsx @@ -2,7 +2,6 @@ import { JSXElement, Show } from "solid-js"; import { cn } from "../../utils/cn"; import { BalloonProps, buildBalloonHtmlProperties } from "./Balloon"; -import { Conditional } from "./Conditional"; import { Fa, FaProps } from "./Fa"; type BaseProps = { @@ -80,35 +79,9 @@ export function Button(props: ButtonProps | AnchorProps): JSXElement { }; return ( - props.onClick?.(e)} - onMouseEnter={(e) => props.onMouseEnter?.(e)} - onMouseLeave={(e) => props.onMouseLeave?.(e)} - data-ui-variant={variant()} - data-ui-element="button" - {...props.dataset} - > - {content} - - } - else={ + } - /> + > + props.onClick?.(e)} + onMouseEnter={(e) => props.onMouseEnter?.(e)} + onMouseLeave={(e) => props.onMouseLeave?.(e)} + data-ui-variant={variant()} + data-ui-element="button" + {...props.dataset} + > + {content} + + ); } diff --git a/frontend/src/ts/components/common/Conditional.tsx b/frontend/src/ts/components/common/Conditional.tsx deleted file mode 100644 index ad315aa59acd..000000000000 --- a/frontend/src/ts/components/common/Conditional.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Accessor, JSXElement, Show } from "solid-js"; - -export function Conditional(props: { - if: T; - then: JSXElement | ((value: Accessor>) => JSXElement); - else?: JSXElement; -}): JSXElement { - return ( - - {typeof props.then === "function" - ? props.then - : () => props.then as JSXElement} - - ); -} diff --git a/frontend/src/ts/components/common/DiscordAvatar.tsx b/frontend/src/ts/components/common/DiscordAvatar.tsx index 28dc30d0ee7b..501ccac673f7 100644 --- a/frontend/src/ts/components/common/DiscordAvatar.tsx +++ b/frontend/src/ts/components/common/DiscordAvatar.tsx @@ -2,7 +2,6 @@ import { createSignal, JSXElement, Show } from "solid-js"; import { createStore } from "solid-js/store"; import { cn } from "../../utils/cn"; -import { Conditional } from "./Conditional"; import { LoadingCircle } from "./LoadingCircle"; //cache successful and missing avatars @@ -59,33 +58,27 @@ export function DiscordAvatar(props: { props.class, )} > - - - - - { - setAvatar(cacheKey(), true); - setShowSpinner(false); - }} - onError={() => { - setAvatar(cacheKey(), false); - setShowSpinner(false); - }} - /> - - } - else={fallback()} - /> + + + + + { + setAvatar(cacheKey(), true); + setShowSpinner(false); + }} + onError={() => { + setAvatar(cacheKey(), false); + setShowSpinner(false); + }} + /> + ); } diff --git a/frontend/src/ts/components/common/LoadingCircle.tsx b/frontend/src/ts/components/common/LoadingCircle.tsx index 5d7ac78fca05..6feaddb8a38a 100644 --- a/frontend/src/ts/components/common/LoadingCircle.tsx +++ b/frontend/src/ts/components/common/LoadingCircle.tsx @@ -1,7 +1,6 @@ -import { JSXElement } from "solid-js"; +import { JSXElement, Show } from "solid-js"; import { cn } from "../../utils/cn"; -import { Conditional } from "./Conditional"; import { Fa } from "./Fa"; export function LoadingCircle(props: { @@ -10,24 +9,9 @@ export function LoadingCircle(props: { class?: string; }): JSXElement { return ( - - - - } - else={ + } - /> + > +
+ +
+
); } diff --git a/frontend/src/ts/components/common/Separator.tsx b/frontend/src/ts/components/common/Separator.tsx index 4e0594b83c9e..ddb4caa10bbf 100644 --- a/frontend/src/ts/components/common/Separator.tsx +++ b/frontend/src/ts/components/common/Separator.tsx @@ -1,7 +1,6 @@ -import { JSXElement } from "solid-js"; +import { JSXElement, Show } from "solid-js"; import { cn } from "../../utils/cn"; -import { Conditional } from "./Conditional"; export function Separator(props: { class?: string; @@ -9,40 +8,39 @@ export function Separator(props: { text?: string; }): JSXElement { return ( - -
-
{props.text}
-
- + > } - else={ + > +
- } - /> +
{props.text}
+
+
+ ); } diff --git a/frontend/src/ts/components/common/User.tsx b/frontend/src/ts/components/common/User.tsx index d5b57acde2e1..ebb53d6c25af 100644 --- a/frontend/src/ts/components/common/User.tsx +++ b/frontend/src/ts/components/common/User.tsx @@ -8,9 +8,9 @@ import { UserFlagOptions, } from "../../controllers/user-flag-controller"; import { cn } from "../../utils/cn"; -import { Anime, AnimeConditional } from "./anime"; +import { Anime } from "./anime"; +import { AnimePresence } from "./anime/AnimePresence"; import { Button } from "./Button"; -import { Conditional } from "./Conditional"; import { DiscordAvatar } from "./DiscordAvatar"; import { Fa } from "./Fa"; import { NotificationBubble } from "./NotificationBubble"; @@ -85,23 +85,37 @@ export function User(props: Props): JSXElement { class="z-2 m-0.5" />
- } - else={ - - } - /> + + + + + } + > + + + + +
@@ -110,19 +124,15 @@ export function User(props: Props): JSXElement { "hidden sm:block": props.hideNameOnSmallScreens, })} > - - } - else={props.user.name} - /> + + - ( - <> -
{ - if (isCoarse()) { - if (e.target instanceof HTMLAnchorElement) { - if (e.target.dataset["navItem"] === "account") { - e.preventDefault(); - e.stopPropagation(); - } - setAccountMenuOpen((prev) => !prev); - } - } - }} + + + + + - - { - // if (isCoarse()) { - // setAccountMenuOpen(false); - // } - // }} - /> -
-
- -
- - )} - else={ - - } - /> + > + + ); diff --git a/frontend/src/ts/components/layout/overlays/Notifications.tsx b/frontend/src/ts/components/layout/overlays/Notifications.tsx index 425e6ee8518d..2ecc6f4a039c 100644 --- a/frontend/src/ts/components/layout/overlays/Notifications.tsx +++ b/frontend/src/ts/components/layout/overlays/Notifications.tsx @@ -1,5 +1,5 @@ import { AnimationParams } from "animejs"; -import { For, JSXElement } from "solid-js"; +import { For, JSXElement, Show } from "solid-js"; import { getGlobalOffsetTop, getIsScreenshotting } from "../../../states/core"; import { @@ -13,7 +13,6 @@ import { cn } from "../../../utils/cn"; import { Anime } from "../../common/anime/Anime"; import { AnimePresence } from "../../common/anime/AnimePresence"; import { AnimeShow } from "../../common/anime/AnimeShow"; -import { Conditional } from "../../common/Conditional"; import { Fa, FaProps } from "../../common/Fa"; const levelConfig = { @@ -97,12 +96,13 @@ function NotificationItem(props: { notification: Notification }): JSXElement { {title()} - } - else={
{props.notification.message}
} - /> + {props.notification.message}} + > + {/* oxlint-disable-next-line solid/no-innerhtml */} +
+
diff --git a/frontend/src/ts/components/pages/leaderboard/Table.tsx b/frontend/src/ts/components/pages/leaderboard/Table.tsx index 27c1d8cb8b68..a3301a5600e6 100644 --- a/frontend/src/ts/components/pages/leaderboard/Table.tsx +++ b/frontend/src/ts/components/pages/leaderboard/Table.tsx @@ -5,7 +5,7 @@ import { import { createColumnHelper } from "@tanstack/solid-table"; import { format as dateFormat } from "date-fns/format"; import { formatDistanceToNow } from "date-fns/formatDistanceToNow"; -import { Accessor, createMemo, JSXElement } from "solid-js"; +import { Accessor, createMemo, JSXElement, Show } from "solid-js"; import { getConfig } from "../../../config/store"; import { isFriend } from "../../../db"; @@ -17,7 +17,6 @@ import { secondsToString } from "../../../utils/date-and-time"; import { qs } from "../../../utils/dom"; import { Formatting } from "../../../utils/format"; import { abbreviateNumber } from "../../../utils/numbers"; -import { Conditional } from "../../common/Conditional"; import { Fa } from "../../common/Fa"; import { User } from "../../common/User"; import { DataTable, DataTableColumnDef } from "../../ui/table/DataTable"; @@ -99,19 +98,9 @@ export function Table( ); return ( - , - }} - /> - } - else={ + } - /> + > + , + }} + /> + ); } diff --git a/frontend/src/ts/components/pages/leaderboard/UserRank.tsx b/frontend/src/ts/components/pages/leaderboard/UserRank.tsx index 77ab276bea08..2143df9a5caa 100644 --- a/frontend/src/ts/components/pages/leaderboard/UserRank.tsx +++ b/frontend/src/ts/components/pages/leaderboard/UserRank.tsx @@ -7,7 +7,6 @@ import { createMemo, JSXElement, Match, Show, Switch } from "solid-js"; import { getConfig } from "../../../config/store"; import { Formatting } from "../../../utils/format"; -import { Conditional } from "../../common/Conditional"; import { Fa } from "../../common/Fa"; import { LoadingCircle } from "../../common/LoadingCircle"; import { Table, TableEntry } from "./Table"; @@ -75,18 +74,9 @@ export function UserRank(props: { when={props.data !== undefined && props.total !== undefined} fallback={} > - - } - else={ + @@ -120,7 +110,15 @@ export function UserRank(props: { } - /> + > + + ); diff --git a/frontend/src/ts/components/pages/login/LoginPage.tsx b/frontend/src/ts/components/pages/login/LoginPage.tsx index 13c37430805f..6e3c5f248bf9 100644 --- a/frontend/src/ts/components/pages/login/LoginPage.tsx +++ b/frontend/src/ts/components/pages/login/LoginPage.tsx @@ -4,7 +4,6 @@ import { JSXElement, Show } from "solid-js"; import { getServerConfigurationQueryOptions } from "../../../queries/server-configuration"; import { getActivePage } from "../../../states/core"; import { getLoginPageInputsEnabled } from "../../../states/login"; -import { Conditional } from "../../common/Conditional"; import { Login } from "./Login"; import { Register } from "./Register"; @@ -22,22 +21,21 @@ export function LoginPage(): JSXElement { - -

- Login/Signup is disabled or the server is down/under maintenance. -

- - } - else={ + } - /> + > +
+

+ Login/Signup is disabled or the server is down/under maintenance. +

+
+
); } diff --git a/frontend/src/ts/components/pages/profile/UserDetails.tsx b/frontend/src/ts/components/pages/profile/UserDetails.tsx index 6bf7746ea68d..6dd15828a218 100644 --- a/frontend/src/ts/components/pages/profile/UserDetails.tsx +++ b/frontend/src/ts/components/pages/profile/UserDetails.tsx @@ -33,7 +33,6 @@ import { AutoShrink } from "../../common/AutoShrink"; import { Balloon, BalloonProps } from "../../common/Balloon"; import { Bar } from "../../common/Bar"; import { Button } from "../../common/Button"; -import { Conditional } from "../../common/Conditional"; import { DiscordAvatar } from "../../common/DiscordAvatar"; import { UserBadge } from "../../common/UserBadge"; import { UserFlags } from "../../common/UserFlags"; @@ -135,47 +134,9 @@ function ActionButtons(props: { }; return ( - - - - } - else={ + ( } - /> + > + + + + )} diff --git a/frontend/storybook/stories/AnimeConditional.stories.tsx b/frontend/storybook/stories/AnimeConditional.stories.tsx deleted file mode 100644 index 66d758fca8bc..000000000000 --- a/frontend/storybook/stories/AnimeConditional.stories.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import preview from "#.storybook/preview"; -import { Accessor, Component, createSignal, JSXElement } from "solid-js"; - -import { AnimeConditional } from "../../src/ts/components/common/anime/AnimeConditional"; - -type AnimeConditionalProps = { - if: boolean; - then: JSXElement | ((value: Accessor>) => JSXElement); - else?: JSXElement; - exitBeforeEnter?: boolean; -}; - -const meta = preview.meta({ - title: "Common/Anime/AnimeConditional", - component: AnimeConditional as Component, - parameters: { - layout: "centered", - }, - tags: ["autodocs"], - argTypes: { - if: { control: "boolean" }, - exitBeforeEnter: { control: "boolean" }, - }, -}); - -export const Default = meta.story({ - args: { - if: true, - exitBeforeEnter: true, - then: ( -
- Condition is true -
- ), - else: ( -
- Condition is false -
- ), - }, -}); - -export const InteractiveToggle = meta.story({ - render: () => { - const [show, setShow] = createSignal(true); - return ( -
- - - Condition is true -
- } - else={ -
- Condition is false -
- } - /> - - ); - }, -}); diff --git a/frontend/storybook/stories/Conditional.stories.tsx b/frontend/storybook/stories/Conditional.stories.tsx deleted file mode 100644 index eae8fdb4cd7d..000000000000 --- a/frontend/storybook/stories/Conditional.stories.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import preview from "#.storybook/preview"; -import { Component, JSXElement } from "solid-js"; - -import { Conditional } from "../../src/ts/components/common/Conditional"; - -type ConditionalProps = { - if: boolean; - then: JSXElement; - else?: JSXElement; -}; - -const meta = preview.meta({ - title: "Common/Conditional", - component: Conditional as Component, - parameters: { - layout: "centered", - }, - tags: ["autodocs"], - argTypes: { - if: { control: "boolean" }, - }, -}); - -export const Truthy = meta.story({ - args: { - if: true, - then:
Condition is true
, - else:
Condition is false
, - }, -}); - -export const Falsy = meta.story({ - args: { - if: false, - then:
Condition is true
, - else:
Condition is false
, - }, -}); - -export const NoFallback = meta.story({ - args: { - if: true, - then:
Visible content
, - }, -}); - -export const FalsyNoFallback = meta.story({ - args: { - if: false, - then:
Hidden content
, - }, -});