diff --git a/demo/DemoApp.tsx b/demo/DemoApp.tsx
index 737497e..7cf3f6d 100644
--- a/demo/DemoApp.tsx
+++ b/demo/DemoApp.tsx
@@ -26,10 +26,13 @@ import {ToggleSwitch} from "../src/Components/Forms/ToggleSwitch";
import {Step, Steps} from "../src/Components/Steps/Steps";
import {AsyncPaginate, AutoPaginate, Paginate} from "../src/Components/Pagination/Paginate";
import {useCurtains} from "../src/Components/Curtains/Curtains";
+import {Subapp, useSubapps} from "../src/Components/Subapps/Subapps";
+import {DemoSubapp} from "./DemoSubapp";
export function DemoApp()
{
const curtains = useCurtains();
+ const subapps = useSubapps();
const [datetime, setDatetime] = useState(null);
@@ -452,7 +455,24 @@ export function DemoApp()
Subapps
-
+
+
+ { subapps.open() }}>
+ Complex subapp with component
+
Modals
diff --git a/demo/DemoSubapp.tsx b/demo/DemoSubapp.tsx
new file mode 100644
index 0000000..d42b2a2
--- /dev/null
+++ b/demo/DemoSubapp.tsx
@@ -0,0 +1,24 @@
+import React from "react";
+import {Subapp, useSubapp} from "../src/Components/Subapps/Subapps";
+import {Card} from "../src/Components/Card";
+
+/**
+ * A demo Subapp component.
+ */
+export function DemoSubapp()
+{
+ // Get subapp close function.
+ const {uuid, close} = useSubapp();
+
+ return (
+
+
+ This is a complex subapp.
+
+ UUID : {uuid}
+
+ Close the subapp
+
+
+ );
+}
diff --git a/src/Components/Subapps/Subapps.tsx b/src/Components/Subapps/Subapps.tsx
new file mode 100644
index 0000000..4e9d67c
--- /dev/null
+++ b/src/Components/Subapps/Subapps.tsx
@@ -0,0 +1,51 @@
+import React from "react";
+import {X} from "@phosphor-icons/react";
+import {useCurtain, useCurtains} from "../Curtains/Curtains";
+
+/**
+ * More natural name of useCurtains for subapps.
+ * @see useCurtains
+ */
+export const useSubapps = useCurtains;
+
+/**
+ * More natural name of useCurtain for subapps.
+ * @see useCurtain
+ */
+export const useSubapp = useCurtain;
+
+/**
+ * Subapp main component.
+ */
+export function Subapp({title, closable, children}: React.PropsWithChildren<{
+ /**
+ * Subapp title.
+ */
+ title?: string;
+
+ /**
+ * Can disable close button.
+ */
+ closable?: boolean;
+}>)
+{
+ // Subapp is closable by default.
+ closable = closable !== undefined ? closable : true;
+
+ // Subapp state.
+ const {close} = useSubapp();
+
+ return (
+
+
+
+
+ {children}
+
+
+ );
+}
diff --git a/src/styles/_components.less b/src/styles/_components.less
index 6ea1588..ed1675a 100644
--- a/src/styles/_components.less
+++ b/src/styles/_components.less
@@ -15,4 +15,5 @@
@import "components/_select";
@import "components/_steps";
@import "components/_steps-counter";
+@import "components/_subapp";
@import "components/_table";
diff --git a/src/styles/components/_subapp.less b/src/styles/components/_subapp.less
new file mode 100644
index 0000000..246bf55
--- /dev/null
+++ b/src/styles/components/_subapp.less
@@ -0,0 +1,69 @@
+
+@subapp-margin: 1.5em;
+
+.curtain > .subapp
+{
+ position: absolute;
+ top: @subapp-margin;
+ left: @subapp-margin;
+
+ width: calc(100% - (2 * @subapp-margin));
+ height: calc(100% - (2 * @subapp-margin));
+ border-radius: 0.25em;
+ box-sizing: border-box;
+
+ background: var(--background);
+
+ overflow: auto;
+
+ > header
+ {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+
+ > h1
+ {
+ flex: 1;
+ margin: auto;
+ padding: 1em 1em;
+
+ font-size: 1.66em;
+ font-weight: 650;
+ }
+
+ > .close
+ {
+ transition: opacity 0.2s ease;
+
+ width: 3em;
+ height: 3em;
+ margin: auto 1em;
+ padding: 0;
+ border-radius: 2em;
+
+ box-shadow: 0 0 0 0 transparent;
+ outline: none;
+ border: none;
+ background: none;
+ color: var(--foreground-lightest);
+
+ opacity: 0.6;
+
+ &:hover
+ {
+ opacity: 1;
+ }
+
+ &:disabled
+ {
+ opacity: 0.33;
+ }
+ }
+ }
+
+ > main
+ {
+ padding: 1em;
+ }
+}