diff --git a/packages/sdk-components-react-radix/src/dialog.template.tsx b/packages/sdk-components-react-radix/src/dialog.template.tsx
new file mode 100644
index 0000000000..0dff771581
--- /dev/null
+++ b/packages/sdk-components-react-radix/src/dialog.template.tsx
@@ -0,0 +1,151 @@
+import { LargeXIcon } from "@webstudio-is/icons/svg";
+import {
+ type TemplateMeta,
+ $,
+ css,
+ PlaceholderValue,
+} from "@webstudio-is/template";
+import { radix } from "./shared/proxy";
+import {
+ blur,
+ borderRadius,
+ borderWidth,
+ boxShadow,
+ colors,
+ fontSize,
+ fontSizeLineHeight,
+ height,
+ letterSpacing,
+ lineHeight,
+ maxWidth,
+ opacity,
+ spacing,
+ width,
+ zIndex,
+} from "./shared/theme";
+import { getButtonStyle } from "./shared/styles";
+
+export const meta: TemplateMeta = {
+ category: "radix",
+ description:
+ "Displays content with an overlay that covers the window, triggered by a button. Clicking the overlay will close the dialog.",
+ order: 4,
+ template: (
+
+
+ <$.Button ws:style={getButtonStyle("outline")}>
+ {new PlaceholderValue("Button")}
+ $.Button>
+
+
+
+ <$.Box
+ ws:label="Dialog Header"
+ ws:style={css`
+ display: flex;
+ flex-direction: column;
+ gap: ${spacing[2]};
+ `}
+ >
+
+ {new PlaceholderValue("Dialog Title you can edit")}
+
+
+ {new PlaceholderValue("Dialog description text you can edit")}
+
+ $.Box>
+ <$.Text>{new PlaceholderValue("The text you can edit")}$.Text>
+
+ <$.HtmlEmbed ws:label="Close Icon" code={LargeXIcon} />
+
+
+
+
+ ),
+};
diff --git a/packages/sdk-components-react-radix/src/dialog.ws.ts b/packages/sdk-components-react-radix/src/dialog.ws.ts
index 4e9cf7935d..dba3fa1372 100644
--- a/packages/sdk-components-react-radix/src/dialog.ws.ts
+++ b/packages/sdk-components-react-radix/src/dialog.ws.ts
@@ -6,7 +6,6 @@ import {
HeadingIcon,
TextIcon,
ButtonElementIcon,
- LargeXIcon,
} from "@webstudio-is/icons/svg";
import {
defaultStates,
@@ -15,7 +14,6 @@ import {
type WsComponentPropsMeta,
} from "@webstudio-is/react-sdk";
import { div, button, h2, p } from "@webstudio-is/sdk/normalize.css";
-import * as tc from "./theme/tailwind-classes";
import {
propsDialog,
propsDialogContent,
@@ -25,7 +23,7 @@ import {
propsDialogTitle,
propsDialogDescription,
} from "./__generated__/dialog.props";
-import { buttonReset, getButtonStyles } from "./theme/styles";
+import { buttonReset } from "./theme/styles";
const presetStyle = {
div,
@@ -41,7 +39,6 @@ const descriptionPresetStyle = {
// @todo add [data-state] to button and link
export const metaDialogTrigger: WsComponentMeta = {
- category: "hidden",
type: "container",
icon: TriggerIcon,
stylable: false,
@@ -52,7 +49,6 @@ export const metaDialogTrigger: WsComponentMeta = {
};
export const metaDialogOverlay: WsComponentMeta = {
- category: "hidden",
type: "container",
presetStyle,
icon: OverlayIcon,
@@ -69,7 +65,6 @@ export const metaDialogOverlay: WsComponentMeta = {
};
export const metaDialogContent: WsComponentMeta = {
- category: "hidden",
type: "container",
presetStyle,
icon: ContentIcon,
@@ -98,7 +93,6 @@ export const metaDialogContent: WsComponentMeta = {
};
export const metaDialogTitle: WsComponentMeta = {
- category: "hidden",
type: "container",
presetStyle: titlePresetStyle,
icon: HeadingIcon,
@@ -109,7 +103,6 @@ export const metaDialogTitle: WsComponentMeta = {
};
export const metaDialogDescription: WsComponentMeta = {
- category: "hidden",
type: "container",
presetStyle: descriptionPresetStyle,
icon: TextIcon,
@@ -120,7 +113,6 @@ export const metaDialogDescription: WsComponentMeta = {
};
export const metaDialogClose: WsComponentMeta = {
- category: "hidden",
type: "container",
presetStyle: {
button: [buttonReset, button].flat(),
@@ -143,8 +135,6 @@ export const metaDialogClose: WsComponentMeta = {
* Copyright (c) 2023 shadcn
**/
export const metaDialog: WsComponentMeta = {
- category: "radix",
- order: 4,
type: "container",
constraints: [
{
@@ -158,177 +148,6 @@ export const metaDialog: WsComponentMeta = {
],
icon: DialogIcon,
stylable: false,
- description:
- "Displays content with an overlay that covers the window, triggered by a button. Clicking the overlay will close the dialog.",
- template: [
- {
- type: "instance",
- component: "Dialog",
- children: [
- {
- type: "instance",
- component: "DialogTrigger",
- children: [
- {
- type: "instance",
- component: "Button",
- styles: getButtonStyles("outline"),
- children: [{ type: "text", value: "Button", placeholder: true }],
- },
- ],
- },
- {
- type: "instance",
- component: "DialogOverlay",
- /**
- * fixed inset-0 z-50 bg-background/80 backdrop-blur-sm
- * flex
- **/
- styles: [
- tc.fixed(),
- tc.inset(0),
- tc.z(50),
- tc.bg("background", 80),
- tc.backdropBlur("sm"),
- // To allow positioning Content
- tc.flex(),
- tc.overflow("auto"),
- ].flat(),
- children: [
- {
- type: "instance",
- component: "DialogContent",
- /**
- * fixed w-full z-50
- * grid gap-4 max-w-lg
- * m-auto
- * border bg-background p-6 shadow-lg
- **/
- styles: [
- tc.w("full"),
- tc.z(50),
- tc.flex(),
- tc.flex("col"),
- tc.gap(4),
- tc.m("auto"),
- tc.maxW("lg"),
- tc.border(),
- tc.bg("background"),
- tc.p(6),
- tc.shadow("lg"),
- tc.relative(),
- ].flat(),
- children: [
- {
- type: "instance",
- component: "Box",
- label: "Dialog Header",
- styles: [tc.flex(), tc.flex("col"), tc.gap(1)].flat(),
- children: [
- {
- type: "instance",
- component: "DialogTitle",
- /**
- * text-lg leading-none tracking-tight
- **/
- styles: [
- tc.my(0),
- tc.leading("none"),
- tc.text("lg"),
- tc.tracking("tight"),
- ].flat(),
- children: [
- {
- type: "text",
- value: "Dialog Title you can edit",
- placeholder: true,
- },
- ],
- },
- {
- type: "instance",
- component: "DialogDescription",
- /**
- * text-sm text-muted-foreground
- **/
- styles: [
- tc.my(0),
- tc.text("sm"),
- tc.text("mutedForeground"),
- ].flat(),
- children: [
- {
- type: "text",
- value: "Dialog description text you can edit",
- placeholder: true,
- },
- ],
- },
- ],
- },
-
- {
- type: "instance",
- component: "Text",
- children: [
- {
- type: "text",
- value: "The text you can edit",
- placeholder: true,
- },
- ],
- },
-
- {
- type: "instance",
- component: "DialogClose",
- /**
- * absolute right-4 top-4
- * rounded-sm opacity-70
- * ring-offset-background
- * hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2
- * flex items-center justify-center h-4 w-4
- **/
- styles: [
- tc.absolute(),
- tc.right(4),
- tc.top(4),
- tc.rounded("sm"),
- tc.opacity(70),
- tc.flex(),
- tc.items("center"),
- tc.justify("center"),
- tc.h(4),
- tc.w(4),
- tc.border(0),
- tc.bg("transparent"),
- tc.outline("none"),
- tc.hover(tc.opacity(100)),
- tc.focus(tc.ring("ring", 2, "background", 2)),
- ].flat(),
- children: [
- {
- type: "instance",
- component: "HtmlEmbed",
- label: "Close Icon",
- props: [
- {
- type: "string",
- name: "code",
- value: LargeXIcon,
- },
- ],
- children: [],
- },
- ],
- },
- ],
- },
- ],
- },
- ],
- },
- ],
};
export const propsMetaDialog: WsComponentPropsMeta = {
diff --git a/packages/sdk-components-react-radix/src/label.template.tsx b/packages/sdk-components-react-radix/src/label.template.tsx
index eb976e04bd..c78a7bee7c 100644
--- a/packages/sdk-components-react-radix/src/label.template.tsx
+++ b/packages/sdk-components-react-radix/src/label.template.tsx
@@ -6,6 +6,14 @@ import {
import { radix } from "./shared/proxy";
import { fontSize, lineHeight, weights } from "./shared/theme";
+/**
+ * Styles source without animations:
+ * https://github.com/shadcn-ui/ui/blob/main/apps/www/registry/default/ui/label.tsx
+ *
+ * Attributions
+ * MIT License
+ * Copyright (c) 2023 shadcn
+ **/
export const meta: TemplateMeta = {
category: "radix",
description:
diff --git a/packages/sdk-components-react-radix/src/metas.ts b/packages/sdk-components-react-radix/src/metas.ts
index 187cf80514..26ffef7d38 100644
--- a/packages/sdk-components-react-radix/src/metas.ts
+++ b/packages/sdk-components-react-radix/src/metas.ts
@@ -12,7 +12,6 @@ export {
metaDialogTitle as DialogTitle,
metaDialogDescription as DialogDescription,
} from "./dialog.ws";
-export { meta as Sheet } from "./sheet.ws";
export {
metaPopover as Popover,
metaPopoverTrigger as PopoverTrigger,
diff --git a/packages/sdk-components-react-radix/src/shared/styles.ts b/packages/sdk-components-react-radix/src/shared/styles.ts
new file mode 100644
index 0000000000..2b7c334011
--- /dev/null
+++ b/packages/sdk-components-react-radix/src/shared/styles.ts
@@ -0,0 +1,93 @@
+import { css, type TemplateStyleDecl } from "@webstudio-is/template";
+import {
+ borderRadius,
+ borderWidth,
+ boxShadow,
+ colors,
+ fontSize,
+ fontSizeLineHeight,
+ height,
+ opacity,
+ spacing,
+ weights,
+} from "./theme";
+
+// ghost icon button
+// 'inline-flex items-center justify-center rounded-md text-sm font-medium
+// ring-offset-background transition-colors
+// focus-visible:outline-none focus-visible:ring-2
+// focus-visible:ring-ring focus-visible:ring-offset-2
+
+// disabled:pointer-events-none disabled:opacity-50'
+const buttonStyle = css`
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ background-color: transparent;
+ border: 0 solid ${colors.border};
+ border-radius: ${borderRadius.md};
+ font-size: ${fontSize.sm};
+ line-height: ${fontSizeLineHeight.sm};
+ font-weight: ${weights.medium};
+ &:focus-visible {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ box-shadow: ${boxShadow.ring};
+ }
+ &:disabled {
+ pointer-events: none;
+ opacity: ${opacity[50]};
+ }
+`;
+
+// hover:bg-accent hover:text-accent-foreground
+const ghostButtonStyle = css`
+ &:hover {
+ background-color: ${colors.accent};
+ color: ${colors.accentForeground};
+ }
+`;
+
+// border border-input bg-background hover:bg-accent hover:text-accent-foreground
+const outlineButtonStyle = css`
+ border: ${borderWidth.DEFAULT} solid ${colors.input};
+ background-color: ${colors.background};
+ &:hover {
+ background-color: ${colors.accent};
+ color: ${colors.accentForeground};
+ }
+`;
+
+// h-10 px-4 py-2
+const defaultButtonStyle = css`
+ height: ${height[10]};
+ padding: ${spacing[2]} ${spacing[4]};
+`;
+
+// Set explicit paddings for IOS Safari to prevent the icon from collapsing
+// h-10 w-10
+const iconButtonStyle = css`
+ height: ${spacing[10]};
+ width: ${spacing[10]};
+ padding: ${spacing[0]} ${spacing[1.5]};
+`;
+
+export const getButtonStyle = (
+ variant: "outline" | "ghost",
+ size: "default" | /*"sm" |*/ "icon" = "default"
+) => {
+ const style: TemplateStyleDecl[] = [...buttonStyle];
+ if (variant === "ghost") {
+ style.push(...ghostButtonStyle);
+ }
+ if (variant === "outline") {
+ style.push(...outlineButtonStyle);
+ }
+ if (size === "default") {
+ style.push(...defaultButtonStyle);
+ }
+ if (size === "icon") {
+ style.push(...iconButtonStyle);
+ }
+ return style;
+};
diff --git a/packages/sdk-components-react-radix/src/shared/theme.ts b/packages/sdk-components-react-radix/src/shared/theme.ts
index 235b868f32..5deb02ff65 100644
--- a/packages/sdk-components-react-radix/src/shared/theme.ts
+++ b/packages/sdk-components-react-radix/src/shared/theme.ts
@@ -59,6 +59,15 @@ export const weights = {
black: "900",
} as const;
+export const letterSpacing = {
+ tighter: "-0.05em",
+ tight: "-0.025em",
+ normal: "0em",
+ wide: "0.025em",
+ wider: "0.05em",
+ widest: "0.1em",
+} as const;
+
export const spacing = {
"0": "0px",
"1": "0.25rem",
@@ -97,6 +106,11 @@ export const spacing = {
"3.5": "0.875rem",
} as const;
+export const width = {
+ ...spacing,
+ full: "100%",
+} as const;
+
export const height = {
...spacing,
auto: "auto",
@@ -122,6 +136,34 @@ export const height = {
fit: "fit-content",
} as const;
+export const maxWidth = {
+ "0": "0rem",
+ xs: "20rem",
+ sm: "24rem",
+ md: "28rem",
+ lg: "32rem",
+ xl: "36rem",
+ "2xl": "42rem",
+ "3xl": "48rem",
+ "4xl": "56rem",
+ "5xl": "64rem",
+ "6xl": "72rem",
+ "7xl": "80rem",
+ full: "100%",
+ min: "min-content",
+ max: "max-content",
+ fit: "fit-content",
+ prose: "65ch",
+} as const;
+
+export const borderWidth = {
+ "0": "0px",
+ "2": "2px",
+ "4": "4px",
+ "8": "8px",
+ DEFAULT: "1px",
+};
+
export const borderRadius = {
none: "0px",
sm: "0.125rem",
@@ -212,3 +254,24 @@ export const boxShadow = {
`0 0 0 ${ringOffsetWidth[2]} ${colors.background}, ` +
`0 0 0 calc(${ringWidth[2]} + ${ringOffsetWidth[2]}) ${colors.ring}`,
} as const;
+
+export const zIndex = {
+ "0": "0",
+ "10": "10",
+ "20": "20",
+ "30": "30",
+ "40": "40",
+ "50": "50",
+} as const;
+
+export const blur = {
+ sm: "blur(0 1px 2px 0 rgb(0 0 0 / 0.05))",
+ DEFAULT:
+ "blur(0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1))",
+ md: "blur(0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1))",
+ lg: "blur(0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1))",
+ xl: "blur(0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1))",
+ "2xl": "blur(0 25px 50px -12px rgb(0 0 0 / 0.25))",
+ inner: "blur(inset 0 2px 4px 0 rgb(0 0 0 / 0.05))",
+ none: "blur(none)",
+};
diff --git a/packages/sdk-components-react-radix/src/sheet.template.tsx b/packages/sdk-components-react-radix/src/sheet.template.tsx
new file mode 100644
index 0000000000..dc44c7c687
--- /dev/null
+++ b/packages/sdk-components-react-radix/src/sheet.template.tsx
@@ -0,0 +1,169 @@
+import { LargeXIcon, MenuIcon } from "@webstudio-is/icons/svg";
+import {
+ type TemplateMeta,
+ $,
+ css,
+ PlaceholderValue,
+} from "@webstudio-is/template";
+import { radix } from "./shared/proxy";
+import {
+ blur,
+ borderRadius,
+ borderWidth,
+ boxShadow,
+ colors,
+ fontSize,
+ fontSizeLineHeight,
+ height,
+ letterSpacing,
+ lineHeight,
+ maxWidth,
+ opacity,
+ spacing,
+ width,
+ zIndex,
+} from "./shared/theme";
+import { getButtonStyle } from "./shared/styles";
+
+/**
+ * Styles source without animations:
+ * https://github.com/shadcn-ui/ui/blob/main/apps/www/registry/default/ui/sheet.tsx
+ *
+ * Attributions
+ * MIT License
+ * Copyright (c) 2023 shadcn
+ **/
+export const meta: TemplateMeta = {
+ category: "radix",
+ icon: MenuIcon,
+ description:
+ "Displays content in a menu that slides out from the side of the screen, triggered by a button. Use this component for a typical mobile hamburger menu.",
+ order: 1,
+ template: (
+
+
+ <$.Button ws:style={getButtonStyle("ghost", "icon")}>
+ <$.HtmlEmbed ws:label="Hamburger Menu Svg" code={MenuIcon} />
+ $.Button>
+
+
+
+ <$.Box ws:label="Navigation" tag="nav" role="navigation">
+ <$.Box
+ ws:label="Sheet Header"
+ ws:style={css`
+ display: flex;
+ flex-direction: column;
+ gap: ${spacing[2]};
+ `}
+ >
+
+ {new PlaceholderValue("Sheet Title")}
+
+
+ {new PlaceholderValue("Sheet description text you can edit")}
+
+ $.Box>
+ <$.Text>{new PlaceholderValue("The text you can edit")}$.Text>
+ $.Box>
+
+ <$.HtmlEmbed ws:label="Close Icon" code={LargeXIcon} />
+
+
+
+
+ ),
+};
diff --git a/packages/sdk-components-react-radix/src/sheet.ws.ts b/packages/sdk-components-react-radix/src/sheet.ws.ts
deleted file mode 100644
index 6503b59771..0000000000
--- a/packages/sdk-components-react-radix/src/sheet.ws.ts
+++ /dev/null
@@ -1,226 +0,0 @@
-import { MenuIcon, LargeXIcon } from "@webstudio-is/icons/svg";
-import type { WsComponentMeta } from "@webstudio-is/react-sdk";
-import * as tc from "./theme/tailwind-classes";
-import { getButtonStyles } from "./theme/styles";
-
-/**
- * Styles source without animations:
- * https://github.com/shadcn-ui/ui/blob/main/apps/www/registry/default/ui/sheet.tsx
- *
- * Attributions
- * MIT License
- * Copyright (c) 2023 shadcn
- **/
-export const meta: WsComponentMeta = {
- category: "radix",
- order: 1,
- type: "container",
- icon: MenuIcon,
- stylable: false,
- description:
- "Displays content in a menu that slides out from the side of the screen, triggered by a button. Use this component for a typical mobile hamburger menu.",
- template: [
- {
- type: "instance",
- component: "Dialog",
- label: "Sheet",
- props: [],
- children: [
- {
- type: "instance",
- component: "DialogTrigger",
- label: "Sheet Trigger",
- children: [
- {
- type: "instance",
- component: "Button",
- styles: getButtonStyles("ghost", "icon"),
- children: [
- {
- type: "instance",
- component: "HtmlEmbed",
- label: "Hamburger Menu Svg",
- props: [
- {
- type: "string",
- name: "code",
- value: MenuIcon,
- },
- ],
- children: [],
- },
- ],
- },
- ],
- },
- {
- type: "instance",
- component: "DialogOverlay",
- label: "Sheet Overlay",
- /**
- * fixed inset-0 z-50 bg-background/80 backdrop-blur-sm
- * flex
- **/
- styles: [
- tc.fixed(),
- tc.inset(0),
- tc.z(50),
- tc.bg("background", 80),
- tc.backdropBlur("sm"),
- // To allow positioning Content
- tc.flex(),
- tc.flex("col"),
- tc.overflow("auto"),
- ].flat(),
- children: [
- {
- type: "instance",
- component: "DialogContent",
- label: "Sheet Content",
- /**
- * fixed w-full z-50
- * grid gap-4 max-w-lg
- * m-auto
- * border bg-background p-6 shadow-lg
- **/
- styles: [
- tc.w("full"),
- tc.z(50),
- tc.flex(),
- tc.flex("col"),
- tc.gap(4),
- tc.border(),
- tc.bg("background"),
- tc.p(6),
- tc.shadow("lg"),
- tc.relative(),
- // side=left
- tc.mr("auto"),
- tc.maxW("sm"),
- tc.grow(),
- ].flat(),
- children: [
- {
- type: "instance",
- component: "Box",
- label: "Navigation",
- props: [
- { name: "tag", type: "string", value: "nav" },
- { name: "role", type: "string", value: "navigation" },
- ],
- children: [
- {
- type: "instance",
- component: "Box",
- label: "Sheet Header",
- styles: [tc.flex(), tc.flex("col"), tc.gap(1)].flat(),
- children: [
- {
- type: "instance",
- component: "DialogTitle",
- label: "Sheet Title",
- /**
- * text-lg leading-none tracking-tight
- **/
- styles: [
- tc.my(0),
- tc.leading("none"),
- tc.text("lg"),
- tc.tracking("tight"),
- ].flat(),
- children: [
- {
- type: "text",
- value: "Sheet Title",
- placeholder: true,
- },
- ],
- },
- {
- type: "instance",
- component: "DialogDescription",
- label: "Sheet Description",
- /**
- * text-sm text-muted-foreground
- **/
- styles: [
- tc.my(0),
- tc.text("sm"),
- tc.text("mutedForeground"),
- ].flat(),
- children: [
- {
- type: "text",
- value: "Sheet description text you can edit",
- placeholder: true,
- },
- ],
- },
- ],
- },
-
- {
- type: "instance",
- component: "Text",
- children: [
- {
- type: "text",
- value: "The text you can edit",
- placeholder: true,
- },
- ],
- },
- ],
- },
- {
- type: "instance",
- component: "DialogClose",
- label: "Close Button",
- /**
- * absolute right-4 top-4
- * rounded-sm opacity-70
- * ring-offset-background
- * hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2
- * flex items-center justify-center h-4 w-4
- **/
- styles: [
- tc.absolute(),
- tc.right(4),
- tc.top(4),
- tc.rounded("sm"),
- tc.opacity(70),
- tc.flex(),
- tc.items("center"),
- tc.justify("center"),
- tc.h(4),
- tc.w(4),
- tc.border(0),
- tc.bg("transparent"),
- tc.outline("none"),
- tc.hover(tc.opacity(100)),
- tc.focus(tc.ring("ring", 2, "background", 2)),
- ].flat(),
- children: [
- {
- type: "instance",
- component: "HtmlEmbed",
- label: "Close Icon",
- props: [
- {
- type: "string",
- name: "code",
- value: LargeXIcon,
- },
- ],
- children: [],
- },
- ],
- },
- ],
- },
- ],
- },
- ],
- },
- ],
-};
diff --git a/packages/sdk-components-react-radix/src/tabs.template.tsx b/packages/sdk-components-react-radix/src/tabs.template.tsx
index 91ae25380b..e54b44c75e 100644
--- a/packages/sdk-components-react-radix/src/tabs.template.tsx
+++ b/packages/sdk-components-react-radix/src/tabs.template.tsx
@@ -43,7 +43,8 @@ const tabsTriggerStyle = css`
font-weight: ${weights.medium};
transition: ${transition.all};
&:focus-visible {
- outline: none;
+ outline: 2px solid transparent;
+ outline-offset: 2px;
box-shadow: ${boxShadow.ring};
}
&:disabled {
diff --git a/packages/sdk-components-react-radix/src/templates.ts b/packages/sdk-components-react-radix/src/templates.ts
index ad138002ec..d1a9f48e33 100644
--- a/packages/sdk-components-react-radix/src/templates.ts
+++ b/packages/sdk-components-react-radix/src/templates.ts
@@ -1,2 +1,4 @@
export { meta as Label } from "./label.template";
export { meta as Tabs } from "./tabs.template";
+export { meta as Sheet } from "./sheet.template";
+export { meta as Dialog } from "./dialog.template";