diff --git a/packages/tui-components-svelte/README.md b/packages/tui-components-svelte/README.md index 6e1a564..c1222b5 100644 --- a/packages/tui-components-svelte/README.md +++ b/packages/tui-components-svelte/README.md @@ -2,3 +2,15 @@ This is a component and module library for building user interfaces and features. It exports many base ui elements like buttons, switches, etc. But also exports modules like media or call that allow you to easily build such features into your Svelte app. + +## Todos + +### `modals` + +- [ ] Darken+Blur background transition +- [ ] `onClose` handler with if check possibility and modal to confirm possibility +- [ ] remove `data`, it should not be handled by this library + +### `tabs` + +- [ ] Handle support for Components+Props diff --git a/packages/tui-components-svelte/package.json b/packages/tui-components-svelte/package.json index 2f5327e..75de64d 100644 --- a/packages/tui-components-svelte/package.json +++ b/packages/tui-components-svelte/package.json @@ -1,6 +1,6 @@ { "name": "@timephy/tui-components-svelte", - "version": "0.0.26", + "version": "0.0.27", "description": "", "homepage": "https://github.com/timephy/tui/tree/main/tui-components-svelte#readme", "scripts": { @@ -109,6 +109,7 @@ "types": "./dist/ui/Icon.svelte.d.ts", "svelte": "./dist/ui/Icon.svelte" }, + "./tabs": "./dist/tabs/index.js", "./tabs/TabViewController.svelte": { "types": "./dist/tabs/TabViewController.svelte.d.ts", "svelte": "./dist/tabs/TabViewController.svelte" @@ -116,6 +117,15 @@ "./tabs/TabView.svelte": { "types": "./dist/tabs/TabView.svelte.d.ts", "svelte": "./dist/tabs/TabView.svelte" + }, + "./modals": "./dist/modals/index.js", + "./modals/ModalViewController.svelte": { + "types": "./dist/modals/ModalViewController.svelte.d.ts", + "svelte": "./dist/modals/ModalViewController.svelte" + }, + "./modals/ModalView.svelte": { + "types": "./dist/modals/ModalView.svelte.d.ts", + "svelte": "./dist/modals/ModalView.svelte" } }, "author": "", diff --git a/packages/tui-components-svelte/src/lib/modal/ModalView.svelte b/packages/tui-components-svelte/src/lib/modal/ModalView.svelte deleted file mode 100644 index 5a42849..0000000 --- a/packages/tui-components-svelte/src/lib/modal/ModalView.svelte +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - -
e.stopPropagation()} -> - {@render children()} -
diff --git a/packages/tui-components-svelte/src/lib/modal/ModalViewController.svelte b/packages/tui-components-svelte/src/lib/modal/ModalViewController.svelte deleted file mode 100644 index e552d55..0000000 --- a/packages/tui-components-svelte/src/lib/modal/ModalViewController.svelte +++ /dev/null @@ -1,98 +0,0 @@ - - - - -
- - {#each modals as modal, i (modal.id)} - MODALVC.remove(modal.id)} - > - {#if modal.view instanceof Function} - {@render modal.view()} - {:else} - - {/if} - - {/each} - - - {@render children()} -
diff --git a/packages/tui-components-svelte/src/lib/modals/ModalView.svelte b/packages/tui-components-svelte/src/lib/modals/ModalView.svelte new file mode 100644 index 0000000..9906eba --- /dev/null +++ b/packages/tui-components-svelte/src/lib/modals/ModalView.svelte @@ -0,0 +1,72 @@ + + + + +
e.stopPropagation()} +> + {@render children()} +
diff --git a/packages/tui-components-svelte/src/lib/modals/ModalViewController.svelte b/packages/tui-components-svelte/src/lib/modals/ModalViewController.svelte new file mode 100644 index 0000000..8340c96 --- /dev/null +++ b/packages/tui-components-svelte/src/lib/modals/ModalViewController.svelte @@ -0,0 +1,149 @@ + + + + +
+ + {#each modals as modal, i (modal.id)} + MODAL_C.remove(modal.id)} + > + {#if modal.view instanceof Function} + {@render modal.view()} + {:else} + + {/if} + + {/each} + + + {@render children()} +
diff --git a/packages/tui-components-svelte/src/lib/modals/index.ts b/packages/tui-components-svelte/src/lib/modals/index.ts new file mode 100644 index 0000000..451c497 --- /dev/null +++ b/packages/tui-components-svelte/src/lib/modals/index.ts @@ -0,0 +1,51 @@ +import { getContext, type Snippet } from "svelte" +import { MODAL_KEY, MODAL_CONTROLLER_KEY, type ComponentWithProps } from "./internal" + +export type ModalOptions = { + id?: string +} + +/** The context object available through `getModalController()` to add/remove modals. */ +export type ModalController = { + push>(view: Snippet | ComponentWithProps, options?: ModalOptions): void + pop(): void + popAll(): void + remove(id: string): void + readonly count: number +} + +/** + * Call this function from a child of `ModalController` to get the ModalControllerContext. + */ +export function getModalController() { + const context = getContext(MODAL_CONTROLLER_KEY) + if (context === undefined) throw new Error("No ModalViewControllerContext found") + return context as ModalController +} + +/* ================================================================================================================== */ + +/** The context object available through `getModal()` to control the current modal. */ +export type Modal = { + /** The identifier of the modal. */ + readonly id: string + /** If the modal is currently the top modal and therefore visible. */ + readonly topMost: boolean + /** if the modal is the bottom most modal. */ + readonly bottomMost: boolean + /** Close the modal. */ + close(): void + /** Whether the modal is fullscreen. */ + fullscreen: boolean + /** Whether the modal should close when the escape key is pressed. */ + escClose: boolean +} + +/** + * Call this function from a child of `Modal` to get the ModalContext. + */ +export function getModal() { + const context = getContext(MODAL_KEY) + if (context === undefined) throw new Error("No ModalContext found") + return context as Modal +} diff --git a/packages/tui-components-svelte/src/lib/modals/internal.ts b/packages/tui-components-svelte/src/lib/modals/internal.ts new file mode 100644 index 0000000..fea3296 --- /dev/null +++ b/packages/tui-components-svelte/src/lib/modals/internal.ts @@ -0,0 +1,9 @@ +import type { Component } from "svelte" + +export const MODAL_CONTROLLER_KEY = "timui.ModalController" +export const MODAL_KEY = "timui.Modal" + +export type ComponentWithProps> = { + component: Component + props: Props +} diff --git a/packages/tui-components-svelte/src/lib/tabs/TabView.svelte b/packages/tui-components-svelte/src/lib/tabs/TabView.svelte index 3fd5270..1bcd693 100644 --- a/packages/tui-components-svelte/src/lib/tabs/TabView.svelte +++ b/packages/tui-components-svelte/src/lib/tabs/TabView.svelte @@ -6,34 +6,10 @@ - It provides a context to its children to allow them to interact with the tab. --> - -
diff --git a/packages/tui-components-svelte/src/lib/tabs/TabViewController.svelte b/packages/tui-components-svelte/src/lib/tabs/TabViewController.svelte index 52b4fff..990efb1 100644 --- a/packages/tui-components-svelte/src/lib/tabs/TabViewController.svelte +++ b/packages/tui-components-svelte/src/lib/tabs/TabViewController.svelte @@ -2,28 +2,60 @@ @component A TabViewController is a component that manages multiple tabs and their views. - - It displays the views of the tabs based on the selected tab. - - It makes the view scrollable, so that the tab bar is always visible. - - It provides a tab bar to switch between tabs. - ## Layout + @example + ```svelte + + + + ``` + + And then inside a tab view: + + ```svelte + + ``` --> - - - -
-

Header

-

id: {MODAL.id}

-

showing: {MODAL.topMost}

-

fullscreen: {MODAL.viewOptions.fullscreen}

-

escClose: {MODAL.viewOptions.escClose}

-

title: {MODAL.dict.title}

-
diff --git a/packages/tui-components-svelte/src/routes/modalVC/+layout.svelte b/packages/tui-components-svelte/src/routes/modals/+layout.svelte similarity index 74% rename from packages/tui-components-svelte/src/routes/modalVC/+layout.svelte rename to packages/tui-components-svelte/src/routes/modals/+layout.svelte index 4b7a544..c14781a 100644 --- a/packages/tui-components-svelte/src/routes/modalVC/+layout.svelte +++ b/packages/tui-components-svelte/src/routes/modals/+layout.svelte @@ -1,5 +1,5 @@ {#snippet A()} diff --git a/packages/tui-components-svelte/src/routes/modals/Header.svelte b/packages/tui-components-svelte/src/routes/modals/Header.svelte new file mode 100644 index 0000000..3957b1a --- /dev/null +++ b/packages/tui-components-svelte/src/routes/modals/Header.svelte @@ -0,0 +1,15 @@ + + + + +
+

Header

+

id: {MODAL.id}

+

showing: {MODAL.topMost}

+

fullscreen: {MODAL.fullscreen}

+

escClose: {MODAL.escClose}

+
diff --git a/packages/tui-components-svelte/src/routes/modalVC/ModalFullscreen.svelte b/packages/tui-components-svelte/src/routes/modals/ModalFullscreen.svelte similarity index 61% rename from packages/tui-components-svelte/src/routes/modalVC/ModalFullscreen.svelte rename to packages/tui-components-svelte/src/routes/modals/ModalFullscreen.svelte index c0c8f0d..1834017 100644 --- a/packages/tui-components-svelte/src/routes/modalVC/ModalFullscreen.svelte +++ b/packages/tui-components-svelte/src/routes/modals/ModalFullscreen.svelte @@ -2,7 +2,7 @@ import type { Snippet } from "svelte" import Header from "./Header.svelte" import Actions from "./Actions.svelte" - import { getModalContext } from "$lib/modal/ModalView.svelte" + import { getModal } from "$lib/modals" const { children, @@ -10,11 +10,9 @@ children: Snippet } = $props() - const MODAL = getModalContext() - MODAL.viewOptions.fullscreen = true - MODAL.viewOptions.escClose = false - - MODAL.dict.title = "Fullscreen" + const MODAL = getModal() + MODAL.fullscreen = true + MODAL.escClose = false
diff --git a/packages/tui-components-svelte/src/routes/modalVC/ModalSmall.svelte b/packages/tui-components-svelte/src/routes/modals/ModalSmall.svelte similarity index 63% rename from packages/tui-components-svelte/src/routes/modalVC/ModalSmall.svelte rename to packages/tui-components-svelte/src/routes/modals/ModalSmall.svelte index a0daed2..85daa02 100644 --- a/packages/tui-components-svelte/src/routes/modalVC/ModalSmall.svelte +++ b/packages/tui-components-svelte/src/routes/modals/ModalSmall.svelte @@ -2,7 +2,7 @@ import type { Snippet } from "svelte" import Header from "./Header.svelte" import Actions from "./Actions.svelte" - import { getModalContext } from "$lib/modal/ModalView.svelte" + import { getModal } from "$lib/modals" const { children, @@ -12,7 +12,7 @@ a: number } = $props() - const MODAL = getModalContext<{ title: string }>() + const MODAL = getModal()
@@ -21,9 +21,8 @@ - import { getTabContext } from "$lib/tabs/TabView.svelte" + import { getTab } from "$lib/tabs" - const tab = getTabContext() + const tab = getTab() let i = $state(0)