diff --git a/ivette/src/ivette/display.tsx b/ivette/src/ivette/display.tsx index e5b3cb3744e0e634ac33646c8436309f40145000..dd6567a987604f4c9bd58940d7e9d3ae3dfdc600 100644 --- a/ivette/src/ivette/display.tsx +++ b/ivette/src/ivette/display.tsx @@ -20,9 +20,9 @@ /* */ /* ************************************************************************ */ -/* --------------------------------------------------------------------------*/ -/* --- Display Interaction ---*/ -/* --------------------------------------------------------------------------*/ +/* -------------------------------------------------------------------------- */ +/* --- Display Interaction --- */ +/* -------------------------------------------------------------------------- */ /** @packageDocumentation @@ -30,7 +30,7 @@ */ import React from 'react'; -import { VIEW, COMPONENT } from 'ivette'; +import { VIEW, COMPONENT, LayoutPosition } from 'ivette'; import * as State from './state'; import * as Laboratory from './laboratory'; @@ -44,7 +44,7 @@ export interface ItemProps { */ export function ViemItem(props: ItemProps): JSX.Element | null { const { id, selected=false } = props; - const view = State.useElement(VIEW,id); + const view = State.useElement(VIEW, id); const state = Laboratory.useState(); if (!view) return null; const status = Laboratory.getViewStatus(state, id); @@ -62,7 +62,7 @@ export function ViemItem(props: ItemProps): JSX.Element | null { */ export function ComponentItem(props: ItemProps): JSX.Element | null { const { id, selected=false } = props; - const comp = State.useElement(COMPONENT,id); + const comp = State.useElement(COMPONENT, id); const state = Laboratory.useState(); if (!comp) return null; const status = Laboratory.getComponentStatus(state, id); @@ -75,11 +75,54 @@ export function ComponentItem(props: ItemProps): JSX.Element | null { ); } +export interface GroupItemsProps { + id: string; + selected?: string; +} + /** A bundle of sidebar items for controlling an Ivette group of components. */ -export function GroupSection(props: ItemProps): JSX.Element | null { - return <>{props.id}</>; +export function GroupItems(props: GroupItemsProps): JSX.Element | null { + const items = + State.useElements(COMPONENT) + .filter(Laboratory.inGroup(props)) + .map(({ id }) => ( + <ComponentItem + key={id} + id={id} + selected={id === props.selected} /> + )); + return <>{items}</>; +} + +/** Switch display to specified view. */ +export function switchToView(id: string): void { + const view = VIEW.getElement(id); + if (view) Laboratory.applyView(view); +} + +/** Show component. */ +export function showComponent(id: string, at?: LayoutPosition): void +{ + const comp = COMPONENT.getElement(id); + if (comp) Laboratory.applyComponent(comp, at); +} + +/** Dock component. */ +export function dockComponent(id: string, at?: LayoutPosition): void +{ + const comp = COMPONENT.getElement(id); + if (comp) Laboratory.dockComponent(comp, at); +} + +/** Component Status Hook. */ +export function useComponentStatus( + id: string | undefined +): Laboratory.ComponentStatus +{ + const state = Laboratory.useState(); + return Laboratory.getComponentStatus(state, id ?? ''); } -/* --------------------------------------------------------------------------*/ +/* -------------------------------------------------------------------------- */ diff --git a/ivette/src/ivette/laboratory.tsx b/ivette/src/ivette/laboratory.tsx index 9515e8c2561b5d83e774d5927728d95e2a430abf..a4674a420e3a12dc7df763ea2cce645a14818d3d 100644 --- a/ivette/src/ivette/laboratory.tsx +++ b/ivette/src/ivette/laboratory.tsx @@ -475,7 +475,7 @@ function restoreDefault(key: tabKey): void { } } -function applyView(view: Ivette.ViewLayoutProps): void { +export function applyView(view: Ivette.ViewLayoutProps): void { const state = LAB.getValue(); const viewId = view.id; if (state.tabs.has(viewId)) @@ -521,7 +521,7 @@ function applyFavorite( } } -function applyComponent( +export function applyComponent( comp: Ivette.ComponentProps, at?: LayoutPosition ): void { @@ -533,7 +533,7 @@ function applyComponent( LAB.setValue({ ...state, panels, stack }); } -function dockComponent( +export function dockComponent( comp: Ivette.ComponentProps, at?: Ivette.LayoutPosition ): void @@ -660,7 +660,7 @@ export function getComponentStatus( ): ComponentStatus { const layout = state.stack[0] ?? defaultLayout; - const position= getLayoutPosition(layout, compId); + const position = getLayoutPosition(layout, compId); const active = state.panels.has(compId); const docked = state.docked.has(compId); return { position, active, docked }; @@ -1054,9 +1054,9 @@ export function ComponentItem(props: ComponentItemProps): JSX.Element { interface ID { id: string } -const inGroup = (group: ID) => (elt: ID) => elt.id.startsWith(group.id+'.'); -const groupOf = (elt: ID) => (group: ID) => elt.id.startsWith(group.id+'.'); -const inNoGroup = (groups: ID[]) => (elt: ID) => !groups.some(groupOf(elt)); +export const inGroup = (g: ID) => (e: ID) => e.id.startsWith(g.id+'.'); +export const groupOf = (e: ID) => (g: ID) => e.id.startsWith(g.id+'.'); +export const inNoGroup = (gs: ID[]) => (e: ID) => !gs.some(groupOf(e)); interface GroupSectionProps extends Ivette.ItemProps { filter: (comp: ID) => boolean;