Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/fluffy-ways-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"xmlui-playground": patch
"xmlui": patch
---

refactor: xmlui-playground - design update
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@use "xmlui/themes.scss" as themes;

.sectionTitle {
width: 100%;
padding-left: themes.$space-3;
padding-right: themes.$space-3;
font-size: themes.$space-3_5;
}
124 changes: 53 additions & 71 deletions packages/xmlui-playground/src/playground/CodeSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import { forwardRef, useMemo, useState } from "react";
import * as RadixSelect from "@radix-ui/react-select";
import selectStyles from "./Select.module.scss";
import { useMemo } from "react";
import { usePlayground } from "../hooks/usePlayground";
import { contentChanged } from "../state/store";
import { useTheme, Button, type CompoundComponentDef, Icon, type ThemeDefinition } from "xmlui";

export const SelectItem = forwardRef(({ children, className, ...props }: any, forwardedRef) => {
return (
<RadixSelect.Item className={selectStyles.RadixMenuItem} {...props} ref={forwardedRef}>
<RadixSelect.ItemText>{children}</RadixSelect.ItemText>
</RadixSelect.Item>
);
});

SelectItem.displayName = "SelectItem";
import {
type CompoundComponentDef,
type ThemeDefinition,
DropdownMenu,
Icon,
MenuItem,
Text,
} from "xmlui";
import styles from "./CodeSelector.module.scss";

export const CodeSelector = () => {
const { appDescription, options, dispatch } = usePlayground();
const [open, setOpen] = useState(false);
const { root } = useTheme();

const selectedValue = useMemo(() => {
let content = "";
Expand All @@ -42,60 +36,48 @@ export const CodeSelector = () => {
}, [appDescription.components, appDescription.config?.themes, options.content]);

return (
<RadixSelect.Root
open={open}
onOpenChange={(open) => setOpen(open)}
value={options.content}
onValueChange={(value) => dispatch(contentChanged(value))}
>
<RadixSelect.Trigger aria-label="component">
<Button themeColor="primary" variant="ghost">
<RadixSelect.Value>{selectedValue}</RadixSelect.Value>
<RadixSelect.Icon className={selectStyles.SelectIcon}>
{open ? <Icon name="chevronup" /> : <Icon name="chevrondown" />}
</RadixSelect.Icon>
</Button>
</RadixSelect.Trigger>
<RadixSelect.Portal container={root}>
<RadixSelect.Content
className={selectStyles.RadixMenuContent}
side="bottom"
align="start"
position="popper"
>
<RadixSelect.Viewport>
<RadixSelect.Group>
<SelectItem value="app" key="app">
Main.xmlui
</SelectItem>
</RadixSelect.Group>
{appDescription.config?.themes?.length > 0 && (
<RadixSelect.Group>
<RadixSelect.Label className={selectStyles.SelectLabel}>Themes</RadixSelect.Label>
{appDescription.config?.themes?.map((theme: ThemeDefinition, index: number) => (
<SelectItem value={theme.id} key={index}>
{`${theme.id}.json`}
</SelectItem>
))}
</RadixSelect.Group>
)}
{appDescription.components?.length > 0 && (
<RadixSelect.Group>
<RadixSelect.Label className={selectStyles.SelectLabel}>
Components
</RadixSelect.Label>
{appDescription.components?.map(
(component: CompoundComponentDef, index: number) => (
<SelectItem value={component.name} key={index}>
{`${component.name}.xmlui`}
</SelectItem>
),
)}
</RadixSelect.Group>
)}
</RadixSelect.Viewport>
</RadixSelect.Content>
</RadixSelect.Portal>
</RadixSelect.Root>
<DropdownMenu label={selectedValue}>
<MenuItem
iconPosition="end"
icon={"app" === options.content ? <Icon name="checkmark" /> : undefined}
key={"app"}
label={"Main.xmlui"}
onClick={() => dispatch(contentChanged("app"))}
/>

{appDescription.config?.themes?.length > 0 && (
<>
<Text className={styles.sectionTitle} variant="strong">
Themes
</Text>
{appDescription.config?.themes?.map((theme: ThemeDefinition, index: number) => (
<MenuItem
iconPosition="end"
icon={theme.id === options.content ? <Icon name="checkmark" /> : undefined}
key={index}
label={`${theme.id}.json`}
onClick={() => dispatch(contentChanged(theme.id))}
/>
))}
</>
)}

{appDescription.components?.length > 0 && (
<>
<Text className={styles.sectionTitle} variant="strong">
Components
</Text>
{appDescription.components?.map((component: CompoundComponentDef, index: number) => (
<MenuItem
iconPosition="end"
icon={component.name === options.content ? <Icon name="checkmark" /> : undefined}
key={index}
label={`${component.name}.xmlui`}
onClick={() => dispatch(contentChanged(component.name))}
/>
))}
</>
)}
</DropdownMenu>
);
};
1 change: 1 addition & 0 deletions packages/xmlui-playground/src/playground/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { editorStatusChanged, textChanged } from "../state/store";
import { startTransition, useCallback, useEffect, useState } from "react";
import { usePlayground } from "../hooks/usePlayground";
import { Editor as XMLUIEditor } from "xmlui-devtools";
import { overflows } from "xmlui/testing";

export const Editor = () => {
const { text, dispatch, options } = usePlayground();
Expand Down
5 changes: 3 additions & 2 deletions packages/xmlui-playground/src/playground/Header.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
gap: .2rem;
}

.button {
padding: 0.5rem 1rem;
.separator {
height: 20px;
min-height: auto;
}
40 changes: 20 additions & 20 deletions packages/xmlui-playground/src/playground/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ import classnames from "classnames";
import { RxOpenInNewWindow, RxDownload, RxShare2 } from "react-icons/rx";
import { LiaUndoAltSolid } from "react-icons/lia";
import { usePlayground } from "../hooks/usePlayground";
import { resetApp } from "../state/store";
import { resetApp, toneChanged } from "../state/store";
import { handleDownloadZip } from "../utils/helpers";
import { createQueryString } from "./utils";
import { Box } from "./Box";
import { Tooltip } from "./Tooltip";
import ConfirmationDialog from "./ConfirmationDialog";
import { ThemeSwitcher } from "./ThemeSwitcher";
import { CodeSelector } from "./CodeSelector";
import { Button, Text, Logo } from "xmlui";
import { ToneSwitcher } from "./ToneSwitcher";
import { Button, Text, Logo, Tooltip } from "xmlui";
import { ToneSwitch, ContentSeparator } from "xmlui";
import { useToast } from "../hooks/useToast";

export const Header = ({ standalone = false }: { standalone?: boolean }) => {
Expand Down Expand Up @@ -84,27 +83,18 @@ export const Header = ({ standalone = false }: { standalone?: boolean }) => {
{!options.previewMode && standalone && <CodeSelector />}
</div>
<Text>{appDescription.config?.name}</Text>
<div style={{ display: "flex", alignItems: "center" }}>
<div style={{ display: "flex", alignItems: "center", gap: "1rem" }}>
{standalone && (
<>
{!options.fixedTheme && (
<Tooltip label="Change tone">
<ToneSwitcher />
</Tooltip>
)}
{!options.fixedTheme &&
appDescription.availableThemes &&
appDescription.availableThemes.length > 1 && (
<Tooltip label="Change theme">
<ThemeSwitcher />
</Tooltip>
)}
appDescription.availableThemes.length > 1 && <ThemeSwitcher />}
</>
)}
{!options.previewMode && show && (
<>
{!standalone && (
<Tooltip label="View and edit in new full-width window">
<Tooltip text="View and edit in new full-width window">
<Button variant="ghost" onClick={() => openStandaloneApp(false)}>
<RxOpenInNewWindow />
</Button>
Expand All @@ -122,7 +112,7 @@ export const Header = ({ standalone = false }: { standalone?: boolean }) => {
confirmText="Confirm"
cancelText="Cancel"
/>
<Tooltip label="Reset the app">
<Tooltip text="Reset the app">
<Button
variant="ghost"
onClick={() => {
Expand All @@ -140,21 +130,31 @@ export const Header = ({ standalone = false }: { standalone?: boolean }) => {
)}
{standalone && (
<>
<Tooltip label="Share this app">
<ContentSeparator className={styles.separator} orientation="vertical" size={1} />

<Tooltip text="Share this app">
<Button variant="ghost" onClick={() => share()}>
<RxShare2 />
</Button>
</Tooltip>
<Tooltip label="Preview in fullscreen">
<Tooltip text="Preview in fullscreen">
<Button variant="ghost" onClick={() => openStandaloneApp()}>
<RxOpenInNewWindow height={24} width={24} />
</Button>
</Tooltip>
<Tooltip label="Download app">
<Tooltip text="Download app">
<Button variant="ghost" onClick={() => download()}>
<RxDownload height={24} width={24} />
</Button>
</Tooltip>

<ContentSeparator className={styles.separator} orientation="vertical" size={1} />

{!options.fixedTheme && (
<Tooltip text="Change tone">
<ToneSwitch onChange={(tone) => dispatch(toneChanged(tone))} />
</Tooltip>
)}
</>
)}
</div>
Expand Down
10 changes: 0 additions & 10 deletions packages/xmlui-playground/src/playground/Preview.module.scss

This file was deleted.

1 change: 1 addition & 0 deletions packages/xmlui-playground/src/playground/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export function Preview() {

return (
<NestedApp
withSplashScreen={true}
app={appDescription.app}
activeTone={options.activeTone}
activeTheme={options.activeTheme}
Expand Down
Loading