diff --git a/packages/docs/blog/2023-02-28-dockview-1.6.0.mdx b/packages/docs/blog/2023-02-28-dockview-1.6.0.mdx new file mode 100644 index 000000000..83883bc20 --- /dev/null +++ b/packages/docs/blog/2023-02-28-dockview-1.6.0.mdx @@ -0,0 +1,33 @@ +--- +slug: dockview-1.6.0-release +title: Dockview 1.6.0 +tags: [release] +--- + +import Link from '@docusaurus/Link'; + +# Release Notes + +Please reference to docs @ [dockview.dev](https://dockview.dev). +If you feel anything is missing or unclear please let me know. + +## 🚀 Features + +- magnetic dnd controls [#177](https://github.com/mathuo/dockview/pull/177) +- group dnd [#171](https://github.com/mathuo/dockview/pull/171) +- full width tabs [#171](https://github.com/mathuo/dockview/pull/177) +- addPanel improvements +- update parameters via panel.api.updateParameters +- allow dnd on empty groups [#168](https://github.com/mathuo/dockview/pull/168) + +## 🛠Miscs + +- Update dependencies including the dev dependencies for dockview and all dependencies for the docs website. + [#180](https://github.com/mathuo/dockview/pull/180) +- A variety of internal changes including file name changes +- Improve internal dnd control logic to handle a wider variety of cases +- Various doc enhancements @ [dockview.dev](https://dockview.dev) + +## 🔥 Breaking changes + +- addEmptyGroup renamed to addGroup diff --git a/packages/docs/docs/components/dockview.mdx b/packages/docs/docs/components/dockview.mdx index 0faa319cf..0e941796c 100644 --- a/packages/docs/docs/components/dockview.mdx +++ b/packages/docs/docs/components/dockview.mdx @@ -13,7 +13,13 @@ import { ContextMenuDockview } from '@site/src/components/dockview/contextMenu'; import { NestedDockview } from '@site/src/components/dockview/nested'; import { CustomHeadersDockview } from '@site/src/components/dockview/customHeaders'; import { ResizeDockview } from '@site/src/components/dockview/resize'; +import { DockviewGroupControl } from '@site/src/components/dockview/groupControl'; +import { + DockviewNative, + DockviewNative2, +} from '@site/src/components/dockview/native'; import Link from '@docusaurus/Link'; +import useBaseUrl from '@docusaurus/useBaseUrl'; # Dockview @@ -43,17 +49,21 @@ You can create a Dockview through the use of the `ReactDockview` component. import { ReactDockview } from 'dockview'; ``` -| Property | Type | Optional | Default | Description | -| ------------------- | ------------------------------------ | -------- | ------- | ------------------------------------------------------------ | -| onReady | (event: SplitviewReadyEvent) => void | No | | | -| components | object | No | | | -| tabComponents | object | Yes | | | -| watermarkComponent | object | Yes | | | -| hideBorders | boolean | Yes | false | | -| className | string | Yes | '' | | -| disableAutoResizing | boolean | Yes | false | See <Link to="../basics/#auto-resizing">Auto Resizing</Link> | -| onDidDrop | Event | Yes | false | | -| showDndOverlay | Event | Yes | false | | +| Property | Type | Optional | Default | Description | +| --------------------- | ------------------------------------ | -------- | --------- | ------------------------------------------------------------ | +| onReady | (event: SplitviewReadyEvent) => void | No | | | +| components | object | No | | | +| tabComponents | object | Yes | | | +| watermarkComponent | object | Yes | | | +| hideBorders | boolean | Yes | false | | +| className | string | Yes | '' | | +| disableAutoResizing | boolean | Yes | false | See <Link to="../basics/#auto-resizing">Auto Resizing</Link> | +| onDidDrop | Event | Yes | false | | +| showDndOverlay | Event | Yes | false | | +| defaultTabComponent | object | Yes | | | +| groupControlComponent | object | Yes | | | +| tabHeight | number | Yes | | | +| singleTabMode | 'fullwidth' \| 'default' | Yes | 'default' | | ## Dockview API @@ -101,13 +111,13 @@ const onReady = (event: DockviewReadyEvent) => { | | | | | addPanel | `addPanel(options: AddPanelOptions): IDockviewPanel` | | | getPanel | `(id: string) \| IDockviewPanel \| undefined` | | -| addEmptyGroup | `(options? AddGroupOptions): void` | | +| addGroup | `(options? AddGroupOptions): void` | | | closeAllGroups | `(): void` | | | removeGroup | `(group: GroupPanel): void` | | | getGroup | `(id: string): GroupPanel \| undefined` | | | | | | | getTabHeight | `(): number \| undefined` | | -| setTabHeight | `(hegiht: number \| undefined): void` | | +| setTabHeight | `(height: number \| undefined): void` | | | updateOptions | `(options:SplitviewComponentUpdateOptions): void` | | | focus | `(): void` | | | layout | `(width: number, height:number): void` | <Link to="../basics/#auto-resizing">Auto Resizing</Link> | @@ -125,66 +135,139 @@ const MyComponent = (props: IDockviewPanelProps<{ title: string }>) => { }; ``` -| Property | Type | Description | -| ---------------------- | ----------------------------------------------------------- | --------------- | -| id | `string` | Panel id | -| isFocused | `boolean` | Is panel focsed | -| isActive | `boolean` | Is panel active | -| width | `number` | Panel width | -| height | `number` | Panel height | -| onDidDimensionsChange | `Event<PanelDimensionChangeEvent>` | | -| onDidFocusChange | `Event<FocusEvent>` | | -| onDidVisibilityChange | `Event<VisibilityEvent>` | | -| onDidActiveChange | `Event<ActiveEvent>` | | -| setActive | `(): void` | | -| | | | -| onDidConstraintsChange | `onDidConstraintsChange: Event<PanelConstraintChangeEvent>` | | -| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | | -| setSize | `(event: SizeEvent): void` | | -| | | | -| group | `GroupPanel | undefined` | -| isGroupActive | `boolean` | | -| title | `string` | | -| suppressClosable | `boolean` | | -| close | `(): void` | | -| setTitle | `(title: string): void` | | +| Property | Type | Description | +| ---------------------- | ----------------------------------------------------------- | ---------------- | +| id | `string` | Panel id | +| isFocused | `boolean` | Is panel focused | +| isActive | `boolean` | Is panel active | +| width | `number` | Panel width | +| height | `number` | Panel height | +| onDidDimensionsChange | `Event<PanelDimensionChangeEvent>` | | +| onDidFocusChange | `Event<FocusEvent>` | | +| onDidVisibilityChange | `Event<VisibilityEvent>` | | +| onDidActiveChange | `Event<ActiveEvent>` | | +| setActive | `(): void` | | +| | | | +| onDidConstraintsChange | `onDidConstraintsChange: Event<PanelConstraintChangeEvent>` | | +| setConstraints | `(value: PanelConstraintChangeEvent2): void;` | | +| setSize | `(event: SizeEvent): void` | | +| | | | +| group | `GroupPanel | undefined` | +| isGroupActive | `boolean` | | +| title | `string` | | +| suppressClosable | `boolean` | | +| close | `(): void` | | +| setTitle | `(title: string): void` | | + +## Essential Features + +### Add Panel + +Using the dockview API you can access the `addPanel` method which returns an instance of the created panel. +The minimum method signature is: + +```ts +const panel = api.addPanel({ + id: 'my_unique_panel_id', + component: 'my_component', +}); +``` + +where `id` is the unique id of the panel and `component` is the implenentation which +will be used to render the panel. You will have registered this using the `components` prop of the `DockviewReactComponent` component. + +You can optionally provide a `tabComponent` parameters to the `addPanel` method which will render the tab using a custom renderer. +You will have registered this using the `tabComponents` prop of the `DockviewReactComponent` component. + +```ts +const panel = api.addPanel({ + id: 'my_unique_panel_id', + component: 'my_component', + tabComponent: 'my_tab_component', +}); +``` + +You can pass properties to the panel using the `params` key. +You can update these properties through the panels `api` object and its `updateParameters` method. + +```ts +const panel = api.addPanel({ + id: 'my_unique_panel_id', + component: 'my_component', + params: { + myCustomKey: 'my_custom_value', + }, +}); + +panel.api.updateParameters({ + myCustomKey: 'my_custom_value', + myOtherCustomKey: 'my_other_custom_key', +}); +``` + +> Note `updateParameters` does not accept partial parameter updates, you should call it with the entire set of parameters +> you want the panel to receive. + +Finally `addPanel` accepts a `position` object which tells dockview where to place the panel. + +- This object optionally accepts either a `referencePanel` or `referenceGroup` which can be the associated id as a string + or the panel/group object reference. +- This object accepts a `direction` property which dictates where, + relative to the provided reference the new panel will be placed. + +> If neither a `referencePanel` or `referenceGroup` then the provided `direction` will be treated as absolute. + +> If no `direction` is provided the library will place the new panel in a pre-determined position. + +```ts +const panel = api.addPanel({ + id: 'panel_1', + component: 'default', +}); + +const panel2 = api.addPanel({ + id: 'panel_2', + component: 'default', + position: { + referencePanel: panel1, + direction: 'right', + }, +}); +``` ## Advanced Features ### Resizing via API -Each Dockview is comprised of a number of groups, each of which have a number of panels. -Logically most people would want to resize a panel but practically this really translates to resizing the group to which the panel belongs. +Each Dockview contains of a number of groups and each group has a number of panels. +Logically a user may want to resize a panel, but this translates to resizing the group which contains that panel. -From the api you can access the panels group object (`props.group`) which exposes it's own api object (`props.groups.api`). -This api is largly similar to the <Link to="./gridview/#gridview-panel-api">Gridview API</Link>. - -To resize an individual panel you could create a snippet similar to below. +You can set the size of a panel using `props.api.setSize(...)`. +You can also set the size of the group associated with the panel using `props.api.group.api.setSize(...)` although this isn't recommended +due to the clunky syntax. ```tsx -const onResizePanel = () => { - props.api.group.api.setSize({ - height: 100, - }); -}; +// it's mandatory to provide either a height or a width, providing both is optional +props.api.setSize({ + height: 100, + width: 200, +}); + +// you could also resize the panels group, although not recommended it achieved the same result +props.api.group.api.setSize({ + height: 100, + width: 200, +}); ``` -```tsx -const onResizePanel = () => { - props.api.group.api.setSize({ - width: 100, - }); -}; -``` - -Here is a working example of resizing panels via these API methods. +You can see an example invoking both approaches below. <ResizeDockview /> ### Locked group -Locking a group will disable all drop events for this group ensuring a user can not add additional panels to the group. -You can still add groups to a locked panel programatically using the API. +Locking a group will disable all drop events for this group ensuring no additional panels can be added to the group through drop events. +You can still add groups to a locked panel programatically using the API though. ```tsx panel.group.locked = true; @@ -192,7 +275,7 @@ panel.group.locked = true; ### Group header -You may wish to hide the header section of a group. This can achieved through setting the `hidden` variable on `panel.group.header`. +You may wish to hide the header section of a group. This can achieved through the `hidden` variable on `panel.group.header`. ```tsx panel.group.header.hidden = true; @@ -200,13 +283,11 @@ panel.group.header.hidden = true; ### Custom Tab Headers -You can provide custom renderers for your tab headers. +You can provide custom renderers for your tab headers for maximum customization. A default implementation of `DockviewDefaultTab` is provided should you only wish to attach minor changes and events that do not alter the default behaviour, for example to add a custom context menu event handler. -You are also free to define a custom renderer entirely from scratch and not make use of the `DockviewDefaultTab` component. - ```tsx title="Attaching a custom context menu event handlers to a custom header" import { IDockviewPanelHeaderProps, DockviewDefaultTab } from 'dockview'; @@ -219,7 +300,8 @@ const MyCustomheader = (props: IDockviewPanelHeaderProps) => { }; ``` -To use a custom renderer you can must register a collection of tab components +You are also free to define a custom renderer entirely from scratch and not make use of the `DockviewDefaultTab` component. +To use a custom renderer you can must register a collection of tab components. ```tsx const tabComponents = { @@ -233,7 +315,7 @@ return <DockviewReact tabComponents={tabComponents} ... />; api.addPanel({ id: 'panel_1', component: 'default', - tabComponent: 'myCustomHeader', // <-- + tabComponent: 'myCustomHeader', // <-- your registered renderers title: 'Panel 1', }); ``` @@ -246,26 +328,35 @@ You can also override the default tab renderer which will be used when no `tabCo As a simple example the below attachs a custom event handler for the context menu on all tabs as a default tab renderer +The below example uses a custom tab renderer to reigster a popover when the user right clicked on a tab. +This still makes use of the `DockviewDefaultTab` since it's only a minor change. + <CustomHeadersDockview /> -### Rendering +### Panel Rendering -Although `DockviewReact` will only add those tabs that are visible to the DOM all associated React Components for each tab including those that -are not initially visible will be created. -This will mean that any hooks in those components will run and if you running expensive operations in the tabs you may end up doing a lot of initial -work for what are hidden tabs. +By default `DockviewReact` only adds to the DOM those panels that are visible, +if a panel is not the active tab and not shown the contents of the hidden panel will be removed from the DOM. -This is the default behaviour to ensure the greatest flexibility for the user but you can create a Higher-Order component wrapping your components that -will ensure the component is only created if the tab is visible as below: +However the React Components associated with each panel are only created once and will always exist for as long as the panel exists, hidden or not. -```tsx -import { PanelApi } from 'dockview'; +> For example this means that any hooks in those components will run whether the panel is visible or not which may lead to excessive background work depending +> on the panels implementation. + +This is the default behaviour to ensure the greatest flexibility for the user but through the panels `props.api` you can listen to the visiblity state of the panel +and write additional logic to optimize your application. + +For example if you wanted to unmount the React Components when the panel is not visible you could create a Higher-Order-Component that listens to the panels +visiblity state and only renders the panel when visible. + +```tsx title="Only rendering the React Component when the panel is visible, otherwise rendering a null React Component" +import { IDockviewPanelProps } from 'dockview'; import * as React from 'react'; -function RenderWhenVisible< - T extends { api: Pick<PanelApi, 'isVisible' | 'onDidVisibilityChange'> } ->(component: React.FunctionComponent<T>) { - const HigherOrderComponent = (props: T) => { +function RenderWhenVisible( + component: React.FunctionComponent<IDockviewPanelProps> +) { + const HigherOrderComponent = (props: IDockviewPanelProps) => { const [visible, setVisible] = React.useState<boolean>( props.api.isVisible ); @@ -291,10 +382,10 @@ function RenderWhenVisible< ``` ```tsx -const component = RenderWhenVisible(MyComponent); +const components = { default: RenderWhenVisible(MyComponent) }; ``` -Through toggling the checkbox you can see that when you only render those panels which are visible the underling React component is destroyed when it becomes hidden and re-created when it becomes visible. +Toggling the checkbox you can see that when you only render those panels which are visible the underling React component is destroyed when it becomes hidden and re-created when it becomes visible. <Checkbox /> <div @@ -310,7 +401,40 @@ Through toggling the checkbox you can see that when you only render those panels ### Drag And Drop -The component exposes some method to help determine whether external drag events should be interacted with or not. +#### Built-in behaviours + +Dockview supports a wide variety of built-in Drag and Drop possibilities. +Below are some examples of the operations you can perform. + +<img style={{ width: '60%' }} src={useBaseUrl('/img/add_to_tab.svg')} /> + +> Drag a tab onto another tab to place it inbetween existing tabs. + +<img style={{ width: '60%' }} src={useBaseUrl('/img/add_to_empty_space.svg')} /> + +> Drag a tab to the right of the last tab to place it after the existing tabs. + +<img style={{ width: '60%' }} src={useBaseUrl('/img/add_to_group.svg')} /> + +> Drag a group onto an existing group to merge the two groups. + +<div style={{ display: 'flex', justifyContent: 'space-around' }}> + <img style={{ width: '40%' }} src={useBaseUrl('/img/drop_positions.svg')} /> + <img + style={{ width: '40%' }} + src={useBaseUrl('/img/magnet_drop_positions.svg')} + /> +</div> + +> Drag into the left/right/top/bottom target zone of a panel to create a new group in the selected direction. + +> Drag into the center of a panel to add to that group. + +> Drag to the edge of the dockview component to create a new group on the selected edge. + +#### Extended behaviours + +For interaction with the Drag events directly the component exposes some method to help determine whether external drag events should be interacted with or not. ```tsx /** @@ -375,3 +499,51 @@ const Component: React.FunctionComponent<IDockviewGroupControlProps> = () => { return <DockviewReact {...props} groupControlComponent={Component} />; ``` + +As a simple example the below uses the `groupControlComponent` to render a small control that indicates whether the group +is active and which panel is active in that group. + +```tsx +const GroupControlComponent = (props: IDockviewGroupControlProps) => { + const isGroupActive = props.isGroupActive; + const activePanel = props.activePanel; + + return ( + <div className="dockview-groupcontrol-demo"> + <span + className="dockview-groupcontrol-demo-group-active" + style={{ + background: isGroupActive ? 'green' : 'red', + }} + > + {isGroupActive ? 'Group Active' : 'Group Inactive'} + </span> + <span className="dockview-groupcontrol-demo-active-panel">{`activePanel: ${ + activePanel?.id || 'null' + }`}</span> + </div> + ); +}; +``` + +<DockviewGroupControl /> + +### Full width tabs + +`DockviewReactComponent` accepts the prop `singleTabMode`. If set `singleTabMode=fullwidth` then when there is only one tab in a group this tab will expand +to the entire width of the group. For example: + +> This can be conmbined with <Link to="./dockview/#locked-group">Locked Groups</Link> to create an application that feels more like a Window Manager +> rather than a collection of groups and tabs. + +```tsx +<DockviewReactComponent singleTabMode="fullwidth" {...otherProps} /> +``` + +<DockviewNative /> + +### Example + +hello + +<DockviewNative2 /> diff --git a/packages/docs/src/components/HomepageFeatures/index.tsx b/packages/docs/src/components/HomepageFeatures/index.tsx index cd8efbf61..bad899c47 100644 --- a/packages/docs/src/components/HomepageFeatures/index.tsx +++ b/packages/docs/src/components/HomepageFeatures/index.tsx @@ -11,7 +11,7 @@ type FeatureItem = { const FeatureList: FeatureItem[] = [ { title: '', - Svg: require('@site/static/img/dockview_grid_2.svg').default, + Svg: require('@site/static/img/dockview_grid_3.svg').default, description: ( <> <div className="feature-banner"> diff --git a/packages/docs/src/components/dockview/customHeaders.tsx b/packages/docs/src/components/dockview/customHeaders.tsx index 8494cdefb..08e5b85b1 100644 --- a/packages/docs/src/components/dockview/customHeaders.tsx +++ b/packages/docs/src/components/dockview/customHeaders.tsx @@ -84,7 +84,7 @@ export const CustomHeadersDockview = () => { position: { referencePanel: 'panel_7', direction: 'within' }, }); - event.api.addEmptyGroup(); + event.api.addGroup(); }; return ( diff --git a/packages/docs/src/components/dockview/demo.tsx b/packages/docs/src/components/dockview/demo.tsx index 88410fc6d..c8ce7aadc 100644 --- a/packages/docs/src/components/dockview/demo.tsx +++ b/packages/docs/src/components/dockview/demo.tsx @@ -209,9 +209,8 @@ const Icon = (props: { }; const Button = () => { - const [position, setPosition] = React.useState< - { x: number; y: number } | undefined - >(undefined); + const [position, setPosition] = + React.useState<{ x: number; y: number } | undefined>(undefined); const close = () => setPosition(undefined); @@ -316,19 +315,19 @@ export const DockviewDemo = () => { position: { referencePanel: 'panel_7', direction: 'within' }, }); - event.api.addEmptyGroup(); + event.api.addGroup(); event.api.getPanel('panel_1').api.setActive(); - setInterval(() => { - event.api.getPanel('panel_1').update({ - params: { - params: { - title: Date.now().toString(), - }, - }, - }); - }, 1000); + // setInterval(() => { + // event.api.getPanel('panel_1').update({ + // params: { + // params: { + // title: Date.now().toString(), + // }, + // }, + // }); + // }, 1000); }; return ( diff --git a/packages/docs/src/components/dockview/groupControl.scss b/packages/docs/src/components/dockview/groupControl.scss new file mode 100644 index 000000000..9a9d5bce1 --- /dev/null +++ b/packages/docs/src/components/dockview/groupControl.scss @@ -0,0 +1,17 @@ +.dockview-groupcontrol-demo { + height: 100%; + display: flex; + align-items: center; + color: white; + background-color: black; + padding-left: 8px; + + .dockview-groupcontrol-demo-group-active { + padding: 0px 8px; + } + + .dockview-groupcontrol-demo-active-panel { + color: yellow; + padding: 0px 8px; + } +} diff --git a/packages/docs/src/components/dockview/groupControl.tsx b/packages/docs/src/components/dockview/groupControl.tsx new file mode 100644 index 000000000..1279b5092 --- /dev/null +++ b/packages/docs/src/components/dockview/groupControl.tsx @@ -0,0 +1,103 @@ +import {} from '@site/../dockview/dist/cjs/dnd/droptarget'; +import { + DockviewReact, + DockviewReadyEvent, + IDockviewGroupControlProps, + IDockviewPanelProps, +} from 'dockview'; +import * as React from 'react'; +import './groupControl.scss'; + +const components = { + default: (props: IDockviewPanelProps<{ title: string; x?: number }>) => { + return ( + <div + style={{ + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + color: 'white', + height: '100%', + }} + > + <span>{`${props.params.title}`}</span> + {props.params.x && <span>{` ${props.params.x}`}</span>} + </div> + ); + }, +}; + +const GroupControlComponent = (props: IDockviewGroupControlProps) => { + const isGroupActive = props.isGroupActive; + const activePanel = props.activePanel; + + return ( + <div className="dockview-groupcontrol-demo"> + <span + className="dockview-groupcontrol-demo-group-active" + style={{ + background: isGroupActive ? 'green' : 'red', + }} + > + {isGroupActive ? 'Group Active' : 'Group Inactive'} + </span> + <span className="dockview-groupcontrol-demo-active-panel">{`activePanel: ${ + activePanel?.id || 'null' + }`}</span> + </div> + ); +}; + +export const DockviewGroupControl = () => { + const onReady = (event: DockviewReadyEvent) => { + const panel1 = event.api.addPanel({ + id: 'panel_1', + component: 'default', + tabComponent: 'default', + params: { + title: 'Window 1', + }, + }); + + const panel2 = event.api.addPanel({ + id: 'panel_2', + component: 'default', + tabComponent: 'default', + params: { + title: 'Window 2', + }, + position: { + direction: 'right', + }, + }); + + const panel3 = event.api.addPanel({ + id: 'panel_3', + component: 'default', + tabComponent: 'default', + params: { + title: 'Window 3', + }, + position: { + direction: 'below', + }, + }); + }; + + return ( + <div + style={{ + height: '500px', + display: 'flex', + flexDirection: 'column', + }} + > + <DockviewReact + onReady={onReady} + components={components} + groupControlComponent={GroupControlComponent} + className="dockview-theme-abyss" + /> + </div> + ); +}; diff --git a/packages/docs/src/components/dockview/native.scss b/packages/docs/src/components/dockview/native.scss new file mode 100644 index 000000000..03d7d8c35 --- /dev/null +++ b/packages/docs/src/components/dockview/native.scss @@ -0,0 +1,34 @@ +.nested-dockview { + position: relative; + ::after { + content: ''; + position: absolute; + top: 0px; + left: 0px; + height: 1px; + width: 100%; + background-color: var(--dv-separator-border); + } +} + +.header-title { + padding: 0px 8px; +} + +.my-custom-tab { + padding: 0px 8px; + width: 100%; + display: flex; + height: 100%; + align-items: center; + background-color: var(--dv-tabs-and-actions-container-background-color); + + .my-custom-tab-icon { + font-size: 16px; + + &:hover { + border-radius: 2px; + background-color: var(--dv-icon-hover-background-color); + } + } +} diff --git a/packages/docs/src/components/dockview/native.tsx b/packages/docs/src/components/dockview/native.tsx new file mode 100644 index 000000000..f0a62997d --- /dev/null +++ b/packages/docs/src/components/dockview/native.tsx @@ -0,0 +1,259 @@ +import { + CanDisplayOverlay, + Droptarget, + DropTargetDirections, +} from '@site/../dockview/dist/cjs/dnd/droptarget'; +import { + DockviewDndOverlayEvent, + DockviewDropEvent, + DockviewReact, + DockviewReadyEvent, + GridviewReact, + GridviewReadyEvent, + IDockviewPanelProps, + IGridviewPanelProps, + Position, + Direction, + IDockviewPanelHeaderProps, +} from 'dockview'; +import * as React from 'react'; +import './native.scss'; + +class CustomDndTraget { + private data: any; + + static SINGLETON = new CustomDndTraget(); + + setData<T>(t: T): void { + this.data = t; + } + + getData<T>(): T { + return this.data; + } + + clearData(): void { + this.data = null; + } +} + +type CustomDescriptor = { + type: 'CUSTOM'; + id: string; +}; + +function isCustomDescriptor(obj: any): obj is CustomDescriptor { + return ( + typeof obj === 'object' && (obj as CustomDescriptor).type === 'CUSTOM' + ); +} + +function convertPositionToDirection(position: Position): Direction { + switch (position) { + case Position.Left: + return 'left'; + + case Position.Right: + return 'right'; + + case Position.Bottom: + return 'below'; + + case Position.Top: + return 'above'; + + case Position.Center: + return 'within'; + } +} + +const components = { + default: (props: IDockviewPanelProps<{ title: string; x?: number }>) => { + return ( + <div + style={{ + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + color: 'white', + height: '100%', + }} + > + <span>{`${props.params.title}`}</span> + {props.params.x && <span>{` ${props.params.x}`}</span>} + </div> + ); + }, + isolatedApp: ( + props: IDockviewPanelProps<{ title: string; x?: number }> + ) => { + const onReady = (event: DockviewReadyEvent) => { + const panel1 = event.api.addPanel({ + id: 'panel_1', + component: 'default', + params: { + title: 'Tab 1', + }, + }); + const panel2 = event.api.addPanel({ + id: 'panel_2', + component: 'default', + params: { + title: 'Tab 2', + }, + }); + const panel3 = event.api.addPanel({ + id: 'panel_3', + component: 'default', + params: { + title: 'Tab 3', + }, + }); + }; + return ( + <DockviewReact + onReady={onReady} + components={components} + tabComponents={tabComponents} + className="dockview-theme-abyss" + /> + ); + }, +}; + +const tabComponents = { + default: (props: IDockviewPanelHeaderProps<{ title: string }>) => { + return ( + <div className="my-custom-tab"> + <span>{props.params.title}</span> + <span style={{ flexGrow: 1 }} /> + + <span className="my-custom-tab-icon material-symbols-outlined"> + chrome_minimize + </span> + <span className="my-custom-tab-icon material-symbols-outlined"> + chrome_maximize + </span> + <span className="my-custom-tab-icon material-symbols-outlined"> + close + </span> + </div> + ); + }, +}; + +export const DockviewNative = () => { + const onReady = (event: DockviewReadyEvent) => { + const panel1 = event.api.addPanel({ + id: 'panel_1', + component: 'default', + tabComponent: 'default', + params: { + title: 'Window 1', + }, + }); + panel1.group.locked = true; + + const panel2 = event.api.addPanel({ + id: 'panel_2', + component: 'default', + tabComponent: 'default', + params: { + title: 'Window 2', + }, + position: { + direction: 'right', + }, + }); + panel2.group.locked = true; + + const panel3 = event.api.addPanel({ + id: 'panel_3', + component: 'default', + tabComponent: 'default', + params: { + title: 'Window 3', + }, + position: { + direction: 'below', + }, + }); + panel3.group.locked = true; + }; + + return ( + <div + style={{ + height: '500px', + display: 'flex', + flexDirection: 'column', + }} + > + <DockviewReact + onReady={onReady} + components={components} + tabComponents={tabComponents} + className="dockview-theme-abyss" + singleTabMode="fullwidth" + /> + </div> + ); +}; + +export const DockviewNative2 = () => { + const onReady = (event: DockviewReadyEvent) => { + const panel1 = event.api.addPanel({ + id: 'panel_1', + component: 'isolatedApp', + tabComponent: 'default', + params: { + title: 'Window 1', + }, + }); + panel1.group.locked = true; + + const panel2 = event.api.addPanel({ + id: 'panel_2', + component: 'isolatedApp', + tabComponent: 'default', + params: { + title: 'Window 2', + }, + position: { + direction: 'right', + }, + }); + panel2.group.locked = true; + + const panel3 = event.api.addPanel({ + id: 'panel_3', + component: 'isolatedApp', + tabComponent: 'default', + params: { + title: 'Window 3', + }, + position: { + direction: 'below', + }, + }); + panel3.group.locked = true; + }; + + return ( + <div + style={{ + height: '500px', + display: 'flex', + flexDirection: 'column', + }} + > + <DockviewReact + onReady={onReady} + components={components} + tabComponents={tabComponents} + className="dockview-theme-abyss" + singleTabMode="fullwidth" + /> + </div> + ); +}; diff --git a/packages/docs/src/components/dockview/rendering.tsx b/packages/docs/src/components/dockview/rendering.tsx index 78f775423..18b1b3ebf 100644 --- a/packages/docs/src/components/dockview/rendering.tsx +++ b/packages/docs/src/components/dockview/rendering.tsx @@ -13,10 +13,10 @@ const renderVisibleComponentsOnlyAtom = atom<boolean>({ default: false, }); -function RenderWhenVisible< - T extends { api: Pick<PanelApi, 'isVisible' | 'onDidVisibilityChange'> } ->(component: React.FunctionComponent<T>) { - const HigherOrderComponent = (props: T) => { +function RenderWhenVisible( + component: React.FunctionComponent<IDockviewPanelProps> +) { + const HigherOrderComponent = (props: IDockviewPanelProps) => { const [visible, setVisible] = React.useState<boolean>( props.api.isVisible ); diff --git a/packages/docs/src/components/dockview/resize.tsx b/packages/docs/src/components/dockview/resize.tsx index eaff93af3..a6e68cfb4 100644 --- a/packages/docs/src/components/dockview/resize.tsx +++ b/packages/docs/src/components/dockview/resize.tsx @@ -23,13 +23,24 @@ const Default = (props: IDockviewPanelProps) => { step={1} /> <button + style={{ width: '100px' }} onClick={() => { props.api.group.api.setSize({ width, }); }} > - Set + Resize Group + </button> + <button + style={{ width: '100px' }} + onClick={() => { + props.api.setSize({ + width, + }); + }} + > + Resize panel </button> </div> <div className="resize-control"> @@ -42,13 +53,24 @@ const Default = (props: IDockviewPanelProps) => { step={1} /> <button + style={{ width: '100px' }} onClick={() => { props.api.group.api.setSize({ height, }); }} > - Set + Resize Group + </button> + <button + style={{ width: '100px' }} + onClick={() => { + props.api.setSize({ + height, + }); + }} + > + Resize Panel </button> </div> </div> diff --git a/packages/docs/static/img/add_to_empty_space.svg b/packages/docs/static/img/add_to_empty_space.svg new file mode 100644 index 000000000..da2c2f446 --- /dev/null +++ b/packages/docs/static/img/add_to_empty_space.svg @@ -0,0 +1,20 @@ +<svg width="156" height="18" viewBox="0 0 156 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect y="4" width="156" height="14" fill="#1C1C2A"/> +<rect y="4" width="30" height="14" fill="#10192C"/> +<rect x="31" y="4" width="30" height="14" fill="#10192C"/> +<rect x="62" y="4" width="30" height="14" fill="#000C18"/> +<rect x="30" y="4" width="1" height="14" fill="#2B2B4A"/> +<rect x="61" y="4" width="1" height="14" fill="#2B2B4A"/> +<rect x="92" y="4" width="1" height="14" fill="#2B2B4A"/> +<rect x="66" y="9" width="7" height="4" rx="2" fill="white"/> +<rect x="76" y="9" width="12" height="4" rx="2" fill="white"/> +<rect x="33" y="9" width="15" height="4" rx="2" fill="#777777"/> +<rect x="2" y="9" width="6" height="4" rx="2" fill="#777777"/> +<rect x="10" y="9" width="18" height="4" rx="2" fill="#777777"/> +<rect x="93" y="4" width="63" height="14" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="111.5" y="0.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="115" y="5" width="7" height="4" rx="2" fill="white"/> +<rect x="126" y="5" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M128.344 13.2654C128.52 13.1426 128.51 12.8799 128.327 12.77L124.18 10.2905C123.961 10.1595 123.691 10.3492 123.739 10.5997L124.651 15.344C124.691 15.5542 124.935 15.653 125.11 15.5302L125.772 15.067C125.867 15.0002 125.914 14.8836 125.892 14.7693L125.602 13.2612C125.554 13.0106 125.825 12.821 126.044 12.952L127.362 13.7401C127.462 13.7999 127.588 13.7954 127.683 13.7286L128.344 13.2654Z" fill="white"/> +<rect x="127.5" y="14.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +</svg> diff --git a/packages/docs/static/img/add_to_group.svg b/packages/docs/static/img/add_to_group.svg new file mode 100644 index 000000000..e8f2ab88d --- /dev/null +++ b/packages/docs/static/img/add_to_group.svg @@ -0,0 +1,25 @@ +<svg width="156" height="18" viewBox="0 0 156 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect y="4" width="156" height="14" fill="#1C1C2A"/> +<rect y="4" width="30" height="14" fill="#10192C"/> +<rect x="31" y="4" width="30" height="14" fill="#10192C"/> +<rect x="62" y="4" width="30" height="14" fill="#000C18"/> +<rect x="30" y="4" width="1" height="14" fill="#2B2B4A"/> +<rect x="61" y="4" width="1" height="14" fill="#2B2B4A"/> +<rect x="92" y="4" width="1" height="14" fill="#2B2B4A"/> +<rect x="66" y="9" width="7" height="4" rx="2" fill="#777777"/> +<rect x="76" y="9" width="12" height="4" rx="2" fill="#777777"/> +<rect x="33" y="9" width="15" height="4" rx="2" fill="#282828"/> +<rect x="2" y="9" width="6" height="4" rx="2" fill="#282828"/> +<rect x="10" y="9" width="18" height="4" rx="2" fill="#282828"/> +<rect x="59" width="91" height="10" fill="#2B2B4A"/> +<rect x="60" y="1" width="89.1429" height="8" fill="#1C1C2A"/> +<rect x="60" y="1" width="17.1429" height="8" fill="#10192C"/> +<rect x="77.7142" y="1" width="17.1429" height="8" fill="#10192C"/> +<rect x="77.1428" y="1" width="0.571429" height="8" fill="#2B2B4A"/> +<rect x="94.8572" y="1" width="0.571429" height="8" fill="#2B2B4A"/> +<rect x="78.8572" y="3.85718" width="8.57143" height="2.28571" rx="1.14286" fill="white"/> +<rect x="89.1428" y="3.85718" width="2.85714" height="2.28571" rx="1.14286" fill="white"/> +<rect x="61.1428" y="3.85718" width="10.8571" height="2.28571" rx="1.14286" fill="#777777"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M117.344 8.26544C117.52 8.14263 117.51 7.87986 117.327 7.76998L113.18 5.29049C112.961 5.15953 112.691 5.34916 112.739 5.59974L113.651 10.344C113.691 10.5542 113.935 10.653 114.11 10.5302L114.772 10.067C114.867 10.0002 114.914 9.88362 114.892 9.76929L114.602 8.26123C114.554 8.01064 114.825 7.82101 115.044 7.95197L116.362 8.74015C116.462 8.79989 116.588 8.79538 116.683 8.7286L117.344 8.26544Z" fill="white"/> +<rect x="116.5" y="9.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +</svg> diff --git a/packages/docs/static/img/add_to_tab.svg b/packages/docs/static/img/add_to_tab.svg new file mode 100644 index 000000000..bdc5acf49 --- /dev/null +++ b/packages/docs/static/img/add_to_tab.svg @@ -0,0 +1,20 @@ +<svg width="156" height="18" viewBox="0 0 156 18" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect y="4" width="156" height="14" fill="#1C1C2A"/> +<rect y="4" width="30" height="14" fill="#10192C"/> +<rect x="31" y="4" width="30" height="14" fill="#10192C"/> +<rect x="62" y="4" width="30" height="14" fill="#000C18"/> +<rect x="30" y="4" width="1" height="14" fill="#2B2B4A"/> +<rect x="61" y="4" width="1" height="14" fill="#2B2B4A"/> +<rect x="92" y="4" width="1" height="14" fill="#2B2B4A"/> +<rect x="66" y="9" width="7" height="4" rx="2" fill="white"/> +<rect x="76" y="9" width="12" height="4" rx="2" fill="white"/> +<rect x="33" y="9" width="15" height="4" rx="2" fill="#777777"/> +<rect x="2" y="9" width="6" height="4" rx="2" fill="#777777"/> +<rect x="10" y="9" width="18" height="4" rx="2" fill="#777777"/> +<path d="M31 4H61V18H31V4Z" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="49.5" y="0.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="53" y="5" width="7" height="4" rx="2" fill="white"/> +<rect x="64" y="5" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M66.3445 13.2654C66.5198 13.1426 66.5104 12.8799 66.3266 12.77L62.1804 10.2905C61.9614 10.1595 61.6906 10.3492 61.7388 10.5997L62.6506 15.344C62.691 15.5542 62.9347 15.653 63.1101 15.5302L63.7716 15.067C63.8669 15.0002 63.9142 14.8836 63.8922 14.7693L63.6024 13.2612C63.5542 13.0106 63.825 12.821 64.044 12.952L65.362 13.7401C65.4619 13.7999 65.5876 13.7954 65.683 13.7286L66.3445 13.2654Z" fill="white"/> +<rect x="65.5" y="14.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +</svg> diff --git a/packages/docs/static/img/dockview_grid_3.svg b/packages/docs/static/img/dockview_grid_3.svg new file mode 100644 index 000000000..fb70b1897 --- /dev/null +++ b/packages/docs/static/img/dockview_grid_3.svg @@ -0,0 +1,61 @@ +<svg width="312" height="200" viewBox="0 0 312 200" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="311.504" height="200" rx="5" fill="white"/> +<path d="M0 5C0 2.23858 2.23858 0 5 0H307C309.761 0 312 2.23858 312 5V11H0V5Z" fill="#DCDCDC"/> +<rect y="10" width="312" height="1" fill="#BABABA"/> +<rect y="11" width="156" height="189" fill="#A8A8A8"/> +<rect x="156" y="11" width="156" height="91" fill="#000C18"/> +<rect x="234" y="102" width="78" height="98" fill="#000C18"/> +<rect x="156" y="102" width="78" height="98" fill="#000C18"/> +<rect y="24" width="156" height="176" fill="#000C18"/> +<rect x="157" y="102" width="155" height="1" fill="#2B2B4A"/> +<rect width="1" height="189" transform="matrix(-1 0 0 1 157 11)" fill="#2B2B4A"/> +<path d="M234 103H233V200H234V103Z" fill="#2B2B4A"/> +<rect y="11" width="156" height="14" fill="#1C1C2A"/> +<rect y="11" width="30" height="14" fill="#10192C"/> +<rect x="31" y="11" width="30" height="14" fill="#10192C"/> +<rect x="62" y="11" width="30" height="14" fill="#000C18"/> +<rect x="30" y="11" width="1" height="14" fill="#2B2B4A"/> +<rect x="61" y="11" width="1" height="14" fill="#2B2B4A"/> +<rect x="92" y="11" width="1" height="14" fill="#2B2B4A"/> +<rect x="157" y="11" width="155" height="14" fill="#1C1C2A"/> +<rect x="157" y="11" width="30" height="14" fill="#10192C"/> +<rect x="188" y="11" width="30" height="14" fill="#000C18"/> +<rect x="187" y="11" width="1" height="14" fill="#2B2B4A"/> +<rect x="218" y="11" width="1" height="14" fill="#2B2B4A"/> +<rect x="234" y="103" width="78" height="14" fill="#1C1C2A"/> +<rect x="234" y="103" width="24" height="14" fill="#10192C"/> +<rect x="258" y="103" width="24" height="14" fill="#000C18"/> +<rect x="258" y="103" width="0.503226" height="14" fill="#2B2B4A"/> +<rect x="282" y="103" width="0.503226" height="14" fill="#2B2B4A"/> +<rect x="66" y="16" width="7" height="4" rx="2" fill="white"/> +<rect x="76" y="16" width="12" height="4" rx="2" fill="white"/> +<rect x="191" y="16" width="12" height="4" rx="2" fill="#777777"/> +<rect x="260" y="108" width="7" height="4" rx="2" fill="#777777"/> +<rect x="268" y="108" width="11" height="4" rx="2" fill="#777777"/> +<rect x="206" y="16" width="4" height="4" rx="2" fill="#777777"/> +<rect x="160" y="16" width="5" height="4" rx="2" fill="#282828"/> +<rect x="166" y="16" width="16" height="4" rx="2" fill="#282828"/> +<rect x="237" y="108" width="16" height="4" rx="2" fill="#282828"/> +<rect x="33" y="16" width="15" height="4" rx="2" fill="#777777"/> +<rect x="4" y="3" width="4" height="4" rx="2" fill="#FD605E"/> +<rect x="10" y="3" width="4" height="4" rx="2" fill="#FBBC3F"/> +<rect x="16" y="3" width="4" height="4" rx="2" fill="#34C942"/> +<rect x="2" y="16" width="6" height="4" rx="2" fill="#777777"/> +<rect x="10" y="16" width="18" height="4" rx="2" fill="#777777"/> +<rect x="297" y="11" width="15" height="189" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="90.5" y="18.5" width="48" height="13" fill="#000C18" stroke="#2B2B4A"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M140.344 22.2654C140.52 22.1426 140.51 21.8799 140.327 21.77L136.18 19.2905C135.961 19.1595 135.691 19.3492 135.739 19.5997L136.651 24.344C136.691 24.5542 136.935 24.653 137.11 24.5302L137.772 24.067C137.867 24.0002 137.914 23.8836 137.892 23.7693L137.602 22.2612C137.554 22.0106 137.825 21.821 138.044 21.952L139.362 22.7401C139.462 22.7999 139.588 22.7954 139.683 22.7286L140.344 22.2654Z" fill="white"/> +<rect x="139.5" y="23.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +<path d="M97.3308 23.0909H97.7512L98.7399 25.5057H98.774L99.7626 23.0909H100.183V26H99.8535V23.7898H99.8251L98.916 26H98.5978L97.6887 23.7898H97.6603V26H97.3308V23.0909ZM102.219 25.108V23.8182H102.554V26H102.219V25.6307H102.196C102.145 25.7415 102.066 25.8357 101.958 25.9134C101.85 25.9901 101.713 26.0284 101.548 26.0284C101.412 26.0284 101.291 25.9986 101.185 25.9389C101.079 25.8783 100.995 25.7874 100.935 25.6662C100.874 25.544 100.844 25.3902 100.844 25.2045V23.8182H101.179V25.1818C101.179 25.3409 101.224 25.4678 101.313 25.5625C101.403 25.6572 101.517 25.7045 101.656 25.7045C101.74 25.7045 101.825 25.6832 101.911 25.6406C101.998 25.598 102.071 25.5327 102.129 25.4446C102.189 25.3565 102.219 25.2443 102.219 25.108ZM103.503 23.0909V26H103.168V23.0909H103.503ZM105.066 23.8182V24.1023H103.936V23.8182H105.066ZM104.265 23.2955H104.6V25.375C104.6 25.4697 104.614 25.5407 104.642 25.5881C104.67 25.6345 104.706 25.6657 104.749 25.6818C104.794 25.697 104.841 25.7045 104.89 25.7045C104.927 25.7045 104.957 25.7027 104.981 25.6989C105.005 25.6941 105.024 25.6903 105.038 25.6875L105.106 25.9886C105.083 25.9972 105.052 26.0057 105.011 26.0142C104.97 26.0237 104.919 26.0284 104.856 26.0284C104.761 26.0284 104.669 26.008 104.578 25.9673C104.488 25.9266 104.413 25.8646 104.353 25.7812C104.294 25.6979 104.265 25.5928 104.265 25.4659V23.2955ZM105.57 26V23.8182H105.906V26H105.57ZM105.741 23.4545C105.676 23.4545 105.619 23.4323 105.572 23.3878C105.526 23.3433 105.502 23.2898 105.502 23.2273C105.502 23.1648 105.526 23.1113 105.572 23.0668C105.619 23.0223 105.676 23 105.741 23C105.806 23 105.862 23.0223 105.909 23.0668C105.956 23.1113 105.98 23.1648 105.98 23.2273C105.98 23.2898 105.956 23.3433 105.909 23.3878C105.862 23.4323 105.806 23.4545 105.741 23.4545ZM106.52 26.8182V23.8182H106.844V24.1648H106.883C106.908 24.1269 106.942 24.0786 106.986 24.0199C107.03 23.9602 107.094 23.9072 107.176 23.8608C107.259 23.8134 107.372 23.7898 107.514 23.7898C107.698 23.7898 107.86 23.8357 108 23.9276C108.14 24.0194 108.249 24.1496 108.328 24.3182C108.407 24.4867 108.446 24.6856 108.446 24.9148C108.446 25.1458 108.407 25.3461 108.328 25.5156C108.249 25.6842 108.14 25.8149 108.001 25.9077C107.862 25.9995 107.702 26.0455 107.52 26.0455C107.38 26.0455 107.267 26.0223 107.183 25.9759C107.099 25.9285 107.034 25.875 106.988 25.8153C106.943 25.7547 106.908 25.7045 106.883 25.6648H106.855V26.8182H106.52ZM106.849 24.9091C106.849 25.0739 106.873 25.2192 106.922 25.3452C106.97 25.4702 107.041 25.5682 107.133 25.6392C107.226 25.7093 107.34 25.7443 107.474 25.7443C107.614 25.7443 107.731 25.7074 107.825 25.6335C107.92 25.5587 107.991 25.4583 108.038 25.3324C108.086 25.2055 108.111 25.0644 108.111 24.9091C108.111 24.7557 108.087 24.6174 108.04 24.4943C107.993 24.3703 107.923 24.2723 107.828 24.2003C107.734 24.1274 107.616 24.0909 107.474 24.0909C107.338 24.0909 107.223 24.1255 107.131 24.1946C107.038 24.2628 106.968 24.3584 106.92 24.4815C106.873 24.6037 106.849 24.7462 106.849 24.9091ZM109.292 23.0909V26H108.957V23.0909H109.292ZM110.821 26.0455C110.611 26.0455 110.43 25.9991 110.277 25.9062C110.126 25.8125 110.009 25.6818 109.926 25.5142C109.845 25.3456 109.804 25.1496 109.804 24.9261C109.804 24.7027 109.845 24.5057 109.926 24.3352C110.009 24.1638 110.123 24.0303 110.27 23.9347C110.418 23.8381 110.59 23.7898 110.787 23.7898C110.901 23.7898 111.013 23.8087 111.124 23.8466C111.235 23.8845 111.335 23.946 111.426 24.0312C111.517 24.1155 111.59 24.2273 111.644 24.3665C111.698 24.5057 111.725 24.6771 111.725 24.8807V25.0227H110.043V24.733H111.384C111.384 24.6098 111.359 24.5 111.31 24.4034C111.262 24.3068 111.192 24.2306 111.102 24.1747C111.013 24.1188 110.908 24.0909 110.787 24.0909C110.654 24.0909 110.538 24.1241 110.441 24.1903C110.344 24.2557 110.27 24.3409 110.218 24.446C110.165 24.5511 110.139 24.6638 110.139 24.7841V24.9773C110.139 25.142 110.168 25.2817 110.225 25.3963C110.282 25.5099 110.362 25.5966 110.465 25.6562C110.567 25.715 110.686 25.7443 110.821 25.7443C110.909 25.7443 110.989 25.732 111.06 25.7074C111.132 25.6818 111.194 25.6439 111.246 25.5938C111.298 25.5426 111.338 25.4792 111.367 25.4034L111.691 25.4943C111.656 25.6042 111.599 25.7008 111.519 25.7841C111.438 25.8665 111.339 25.9309 111.22 25.9773C111.102 26.0227 110.969 26.0455 110.821 26.0455ZM113.36 26.8182V23.8182H113.683V24.1648H113.723C113.748 24.1269 113.782 24.0786 113.825 24.0199C113.87 23.9602 113.933 23.9072 114.016 23.8608C114.099 23.8134 114.212 23.7898 114.354 23.7898C114.538 23.7898 114.7 23.8357 114.84 23.9276C114.98 24.0194 115.089 24.1496 115.168 24.3182C115.246 24.4867 115.286 24.6856 115.286 24.9148C115.286 25.1458 115.246 25.3461 115.168 25.5156C115.089 25.6842 114.98 25.8149 114.841 25.9077C114.702 25.9995 114.541 26.0455 114.36 26.0455C114.219 26.0455 114.107 26.0223 114.023 25.9759C113.939 25.9285 113.874 25.875 113.828 25.8153C113.783 25.7547 113.748 25.7045 113.723 25.6648H113.695V26.8182H113.36ZM113.689 24.9091C113.689 25.0739 113.713 25.2192 113.762 25.3452C113.81 25.4702 113.88 25.5682 113.973 25.6392C114.066 25.7093 114.18 25.7443 114.314 25.7443C114.454 25.7443 114.571 25.7074 114.665 25.6335C114.76 25.5587 114.831 25.4583 114.878 25.3324C114.926 25.2055 114.95 25.0644 114.95 24.9091C114.95 24.7557 114.927 24.6174 114.879 24.4943C114.833 24.3703 114.762 24.2723 114.668 24.2003C114.574 24.1274 114.456 24.0909 114.314 24.0909C114.178 24.0909 114.063 24.1255 113.97 24.1946C113.878 24.2628 113.807 24.3584 113.76 24.4815C113.713 24.6037 113.689 24.7462 113.689 24.9091ZM116.439 26.0511C116.301 26.0511 116.175 26.0251 116.063 25.973C115.95 25.92 115.86 25.8438 115.794 25.7443C115.728 25.6439 115.695 25.5227 115.695 25.3807C115.695 25.2557 115.719 25.1544 115.769 25.0767C115.818 24.9981 115.884 24.9366 115.966 24.892C116.048 24.8475 116.139 24.8144 116.239 24.7926C116.339 24.7699 116.44 24.7519 116.541 24.7386C116.674 24.7216 116.781 24.7088 116.864 24.7003C116.947 24.6908 117.008 24.6752 117.046 24.6534C117.084 24.6316 117.104 24.5937 117.104 24.5398V24.5284C117.104 24.3883 117.066 24.2794 116.989 24.2017C116.913 24.1241 116.798 24.0852 116.644 24.0852C116.484 24.0852 116.358 24.1203 116.267 24.1903C116.176 24.2604 116.112 24.3352 116.075 24.4148L115.757 24.3011C115.814 24.1686 115.89 24.0653 115.985 23.9915C116.08 23.9167 116.184 23.8646 116.297 23.8352C116.411 23.8049 116.522 23.7898 116.632 23.7898C116.702 23.7898 116.783 23.7983 116.874 23.8153C116.966 23.8314 117.054 23.8651 117.139 23.9162C117.226 23.9673 117.297 24.0445 117.354 24.1477C117.411 24.2509 117.439 24.3892 117.439 24.5625V26H117.104V25.7045H117.087C117.064 25.7519 117.026 25.8026 116.973 25.8565C116.92 25.9105 116.85 25.9564 116.762 25.9943C116.673 26.0322 116.566 26.0511 116.439 26.0511ZM116.49 25.75C116.623 25.75 116.735 25.724 116.825 25.6719C116.917 25.6198 116.986 25.5526 117.033 25.4702C117.08 25.3878 117.104 25.3011 117.104 25.2102V24.9034C117.09 24.9205 117.058 24.9361 117.01 24.9503C116.963 24.9635 116.908 24.9754 116.845 24.9858C116.784 24.9953 116.724 25.0038 116.665 25.0114C116.607 25.018 116.56 25.0237 116.524 25.0284C116.437 25.0398 116.356 25.0582 116.28 25.0838C116.205 25.1084 116.145 25.1458 116.098 25.196C116.053 25.2453 116.03 25.3125 116.03 25.3977C116.03 25.5142 116.073 25.6023 116.159 25.6619C116.246 25.7206 116.357 25.75 116.49 25.75ZM118.386 24.6875V26H118.051V23.8182H118.375V24.1591H118.403C118.454 24.0483 118.532 23.9593 118.636 23.892C118.74 23.8239 118.875 23.7898 119.04 23.7898C119.187 23.7898 119.317 23.8201 119.427 23.8807C119.538 23.9403 119.624 24.0312 119.686 24.1534C119.747 24.2746 119.778 24.428 119.778 24.6136V26H119.443V24.6364C119.443 24.465 119.398 24.3314 119.309 24.2358C119.22 24.1392 119.098 24.0909 118.943 24.0909C118.836 24.0909 118.74 24.1141 118.656 24.1605C118.573 24.2069 118.507 24.2746 118.459 24.3636C118.41 24.4527 118.386 24.5606 118.386 24.6875ZM121.306 26.0455C121.095 26.0455 120.914 25.9991 120.762 25.9062C120.61 25.8125 120.493 25.6818 120.411 25.5142C120.329 25.3456 120.289 25.1496 120.289 24.9261C120.289 24.7027 120.329 24.5057 120.411 24.3352C120.493 24.1638 120.608 24.0303 120.754 23.9347C120.902 23.8381 121.075 23.7898 121.271 23.7898C121.385 23.7898 121.497 23.8087 121.608 23.8466C121.719 23.8845 121.82 23.946 121.911 24.0312C122.002 24.1155 122.074 24.2273 122.128 24.3665C122.182 24.5057 122.209 24.6771 122.209 24.8807V25.0227H120.527V24.733H121.868C121.868 24.6098 121.843 24.5 121.794 24.4034C121.746 24.3068 121.677 24.2306 121.587 24.1747C121.498 24.1188 121.393 24.0909 121.271 24.0909C121.138 24.0909 121.022 24.1241 120.925 24.1903C120.828 24.2557 120.754 24.3409 120.702 24.446C120.65 24.5511 120.624 24.6638 120.624 24.7841V24.9773C120.624 25.142 120.652 25.2817 120.709 25.3963C120.767 25.5099 120.847 25.5966 120.949 25.6562C121.051 25.715 121.17 25.7443 121.306 25.7443C121.394 25.7443 121.473 25.732 121.544 25.7074C121.616 25.6818 121.678 25.6439 121.73 25.5938C121.782 25.5426 121.823 25.4792 121.851 25.4034L122.175 25.4943C122.141 25.6042 122.084 25.7008 122.003 25.7841C121.923 25.8665 121.823 25.9309 121.705 25.9773C121.586 26.0227 121.453 26.0455 121.306 26.0455ZM123.054 23.0909V26H122.719V23.0909H123.054ZM125.214 24.3068L124.912 24.392C124.894 24.3419 124.866 24.2931 124.829 24.2457C124.793 24.1974 124.743 24.1577 124.681 24.1264C124.618 24.0952 124.538 24.0795 124.441 24.0795C124.307 24.0795 124.196 24.1103 124.107 24.1719C124.019 24.2325 123.975 24.3097 123.975 24.4034C123.975 24.4867 124.005 24.5526 124.066 24.6009C124.126 24.6491 124.221 24.6894 124.35 24.7216L124.674 24.8011C124.869 24.8485 125.014 24.9209 125.11 25.0185C125.206 25.1151 125.253 25.2396 125.253 25.392C125.253 25.517 125.217 25.6288 125.145 25.7273C125.074 25.8258 124.975 25.9034 124.847 25.9602C124.719 26.017 124.571 26.0455 124.401 26.0455C124.179 26.0455 123.994 25.9972 123.849 25.9006C123.703 25.804 123.61 25.6629 123.572 25.4773L123.89 25.3977C123.92 25.5152 123.977 25.6032 124.062 25.6619C124.147 25.7206 124.258 25.75 124.395 25.75C124.552 25.75 124.676 25.7169 124.768 25.6506C124.86 25.5833 124.907 25.5028 124.907 25.4091C124.907 25.3333 124.88 25.2699 124.827 25.2188C124.774 25.1667 124.693 25.1278 124.583 25.1023L124.219 25.017C124.019 24.9697 123.873 24.8963 123.779 24.7969C123.686 24.6965 123.64 24.571 123.64 24.4205C123.64 24.2973 123.674 24.1884 123.743 24.0938C123.814 23.9991 123.909 23.9247 124.029 23.8707C124.15 23.8168 124.287 23.7898 124.441 23.7898C124.657 23.7898 124.826 23.8371 124.949 23.9318C125.073 24.0265 125.162 24.1515 125.214 24.3068ZM127.002 24.5455C127.002 24.1875 127.049 23.8584 127.142 23.5582C127.235 23.2571 127.369 22.9801 127.542 22.7273H127.838C127.769 22.821 127.705 22.9366 127.646 23.0739C127.587 23.2102 127.535 23.3603 127.491 23.5241C127.446 23.687 127.411 23.8556 127.386 24.0298C127.361 24.2041 127.349 24.3759 127.349 24.5455C127.349 24.7708 127.371 24.9995 127.414 25.2315C127.458 25.4635 127.517 25.679 127.59 25.8778C127.664 26.0767 127.747 26.2386 127.838 26.3636H127.542C127.369 26.1108 127.235 25.8343 127.142 25.5341C127.049 25.233 127.002 24.9034 127.002 24.5455ZM129.309 26.0398C129.122 26.0398 128.955 26.0076 128.808 25.9432C128.662 25.8788 128.546 25.7893 128.46 25.6747C128.375 25.5592 128.328 25.4252 128.321 25.2727H128.679C128.686 25.3665 128.719 25.4474 128.775 25.5156C128.832 25.5829 128.907 25.6349 128.998 25.6719C129.09 25.7088 129.192 25.7273 129.304 25.7273C129.429 25.7273 129.54 25.7055 129.636 25.6619C129.733 25.6184 129.809 25.5578 129.863 25.4801C129.918 25.4025 129.946 25.3125 129.946 25.2102C129.946 25.1032 129.919 25.009 129.866 24.9276C129.813 24.8452 129.736 24.7808 129.633 24.7344C129.531 24.688 129.406 24.6648 129.258 24.6648H129.025V24.3523H129.258C129.374 24.3523 129.475 24.3314 129.562 24.2898C129.65 24.2481 129.719 24.1894 129.768 24.1136C129.818 24.0379 129.844 23.9489 129.844 23.8466C129.844 23.7481 129.822 23.6624 129.778 23.5895C129.735 23.5166 129.673 23.4598 129.594 23.419C129.515 23.3783 129.422 23.358 129.315 23.358C129.215 23.358 129.12 23.3764 129.031 23.4134C128.943 23.4493 128.871 23.5019 128.815 23.571C128.759 23.6392 128.729 23.7216 128.724 23.8182H128.383C128.389 23.6657 128.435 23.5322 128.521 23.4176C128.607 23.3021 128.72 23.2121 128.859 23.1477C128.999 23.0833 129.153 23.0511 129.321 23.0511C129.501 23.0511 129.655 23.0876 129.784 23.1605C129.913 23.2325 130.012 23.3277 130.081 23.446C130.15 23.5644 130.184 23.6922 130.184 23.8295C130.184 23.9934 130.141 24.133 130.055 24.2486C129.97 24.3641 129.854 24.4441 129.707 24.4886V24.5114C129.891 24.5417 130.034 24.6198 130.138 24.7457C130.241 24.8707 130.292 25.0256 130.292 25.2102C130.292 25.3684 130.249 25.5104 130.163 25.6364C130.078 25.7614 129.961 25.8598 129.814 25.9318C129.666 26.0038 129.498 26.0398 129.309 26.0398ZM131.595 24.5455C131.595 24.9034 131.548 25.233 131.454 25.5341C131.362 25.8343 131.229 26.1108 131.055 26.3636H130.76C130.828 26.2699 130.891 26.1544 130.95 26.017C131.01 25.8807 131.062 25.7311 131.106 25.5682C131.151 25.4044 131.185 25.2353 131.21 25.0611C131.236 24.8859 131.248 24.714 131.248 24.5455C131.248 24.3201 131.227 24.0914 131.183 23.8594C131.14 23.6274 131.081 23.4119 131.007 23.2131C130.933 23.0142 130.851 22.8523 130.76 22.7273H131.055C131.229 22.9801 131.362 23.2571 131.454 23.5582C131.548 23.8584 131.595 24.1875 131.595 24.5455Z" fill="white"/> +<rect x="279.5" y="46.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="283" y="51" width="7" height="4" rx="2" fill="white"/> +<rect x="294" y="51" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M305.344 61.2654C305.52 61.1426 305.51 60.8799 305.327 60.77L301.18 58.2905C300.961 58.1595 300.691 58.3492 300.739 58.5997L301.651 63.344C301.691 63.5542 301.935 63.653 302.11 63.5302L302.772 63.067C302.867 63.0002 302.914 62.8836 302.892 62.7693L302.602 61.2612C302.554 61.0106 302.825 60.821 303.044 60.952L304.362 61.7401C304.462 61.7999 304.588 61.7954 304.683 61.7286L305.344 61.2654Z" fill="white"/> +<rect x="304.5" y="62.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +<rect x="157" y="153" width="76" height="47" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="180.5" y="163.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="184" y="168" width="7" height="4" rx="2" fill="white"/> +<rect x="195" y="168" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M194.344 176.265C194.52 176.143 194.51 175.88 194.327 175.77L190.18 173.29C189.961 173.16 189.691 173.349 189.739 173.6L190.651 178.344C190.691 178.554 190.935 178.653 191.11 178.53L191.772 178.067C191.867 178 191.914 177.884 191.892 177.769L191.602 176.261C191.554 176.011 191.825 175.821 192.044 175.952L193.362 176.74C193.462 176.8 193.588 176.795 193.683 176.729L194.344 176.265Z" fill="white"/> +<rect x="193.5" y="177.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +</svg> diff --git a/packages/docs/static/img/drop_positions.svg b/packages/docs/static/img/drop_positions.svg new file mode 100644 index 000000000..365e7f609 --- /dev/null +++ b/packages/docs/static/img/drop_positions.svg @@ -0,0 +1,45 @@ +<svg width="156" height="121" viewBox="0 0 156 121" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="156" height="14" fill="#1C1C2A"/> +<rect width="30" height="14" fill="#10192C"/> +<rect x="31" width="30" height="14" fill="#10192C"/> +<rect x="62" width="30" height="14" fill="#000C18"/> +<rect x="30" width="1" height="14" fill="#2B2B4A"/> +<rect x="61" width="1" height="14" fill="#2B2B4A"/> +<rect x="92" width="1" height="14" fill="#2B2B4A"/> +<rect x="66" y="5" width="7" height="4" rx="2" fill="white"/> +<rect x="76" y="5" width="12" height="4" rx="2" fill="white"/> +<rect x="33" y="5" width="15" height="4" rx="2" fill="#777777"/> +<rect x="2" y="5" width="6" height="4" rx="2" fill="#777777"/> +<rect x="10" y="5" width="18" height="4" rx="2" fill="#777777"/> +<rect y="14" width="156" height="107" fill="#000C18"/> +<rect x="38" y="14" width="80" height="25" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="38" y="96" width="80" height="25" fill="#E1E1E1" fill-opacity="0.25"/> +<rect y="29" width="30" height="77" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="38" y="48" width="80" height="38" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="126" y="29" width="30" height="77" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="63.5" y="20.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="67" y="25" width="7" height="4" rx="2" fill="white"/> +<rect x="78" y="25" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M80.3445 33.2654C80.5198 33.1426 80.5104 32.8799 80.3266 32.77L76.1804 30.2905C75.9614 30.1595 75.6906 30.3492 75.7388 30.5997L76.6506 35.344C76.691 35.5542 76.9347 35.653 77.1101 35.5302L77.7716 35.067C77.8669 35.0002 77.9142 34.8836 77.8922 34.7693L77.6024 33.2612C77.5542 33.0106 77.825 32.821 78.044 32.952L79.362 33.7401C79.4619 33.7999 79.5876 33.7954 79.683 33.7286L80.3445 33.2654Z" fill="white"/> +<rect x="79.5" y="34.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +<rect x="122.5" y="62.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="126" y="67" width="7" height="4" rx="2" fill="white"/> +<rect x="137" y="67" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M139.344 75.2654C139.52 75.1426 139.51 74.8799 139.327 74.77L135.18 72.2905C134.961 72.1595 134.691 72.3492 134.739 72.5997L135.651 77.344C135.691 77.5542 135.935 77.653 136.11 77.5302L136.772 77.067C136.867 77.0002 136.914 76.8836 136.892 76.7693L136.602 75.2612C136.554 75.0106 136.825 74.821 137.044 74.952L138.362 75.7401C138.462 75.7999 138.588 75.7954 138.683 75.7286L139.344 75.2654Z" fill="white"/> +<rect x="138.5" y="76.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +<rect x="62.5" y="100.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="66" y="105" width="7" height="4" rx="2" fill="white"/> +<rect x="77" y="105" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M79.3445 113.265C79.5198 113.143 79.5104 112.88 79.3266 112.77L75.1804 110.29C74.9614 110.16 74.6906 110.349 74.7388 110.6L75.6506 115.344C75.691 115.554 75.9347 115.653 76.1101 115.53L76.7716 115.067C76.8669 115 76.9142 114.884 76.8922 114.769L76.6024 113.261C76.5542 113.011 76.825 112.821 77.044 112.952L78.362 113.74C78.4619 113.8 78.5876 113.795 78.683 113.729L79.3445 113.265Z" fill="white"/> +<rect x="78.5" y="114.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +<rect x="4.5" y="62.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="8" y="67" width="7" height="4" rx="2" fill="white"/> +<rect x="19" y="67" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M21.3445 75.2654C21.5198 75.1426 21.5104 74.8799 21.3266 74.77L17.1804 72.2905C16.9614 72.1595 16.6906 72.3492 16.7388 72.5997L17.6506 77.344C17.691 77.5542 17.9347 77.653 18.1101 77.5302L18.7716 77.067C18.8669 77.0002 18.9142 76.8836 18.8922 76.7693L18.6024 75.2612C18.5542 75.0106 18.825 74.821 19.044 74.952L20.362 75.7401C20.4619 75.7999 20.5876 75.7954 20.683 75.7286L21.3445 75.2654Z" fill="white"/> +<rect x="20.5" y="76.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +<rect x="63.5" y="62.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="67" y="67" width="7" height="4" rx="2" fill="white"/> +<rect x="78" y="67" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M80.3445 75.2654C80.5198 75.1426 80.5104 74.8799 80.3266 74.77L76.1804 72.2905C75.9614 72.1595 75.6906 72.3492 75.7388 72.5997L76.6506 77.344C76.691 77.5542 76.9347 77.653 77.1101 77.5302L77.7716 77.067C77.8669 77.0002 77.9142 76.8836 77.8922 76.7693L77.6024 75.2612C77.5542 75.0106 77.825 74.821 78.044 74.952L79.362 75.7401C79.4619 75.7999 79.5876 75.7954 79.683 75.7286L80.3445 75.2654Z" fill="white"/> +<rect x="79.5" y="76.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +</svg> diff --git a/packages/docs/static/img/magnet_drop_positions.svg b/packages/docs/static/img/magnet_drop_positions.svg new file mode 100644 index 000000000..a82f693b0 --- /dev/null +++ b/packages/docs/static/img/magnet_drop_positions.svg @@ -0,0 +1,53 @@ +<svg width="163" height="131" viewBox="0 0 163 131" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M4 5C4 2.23858 6.23858 0 9 0H154C156.761 0 159 2.23858 159 5V11H4V5Z" fill="#DCDCDC"/> +<rect x="4" y="10" width="155" height="1" fill="#BABABA"/> +<rect x="4" y="11" width="155" height="61" fill="#000C18"/> +<rect x="81" y="73" width="78" height="58" fill="#000C18"/> +<rect x="4" y="73" width="77" height="58" fill="#000C18"/> +<rect x="4" y="72" width="155" height="1" fill="#2B2B4A"/> +<path d="M81 73H80V131H81V73Z" fill="#2B2B4A"/> +<rect x="4" y="11" width="155" height="14" fill="#1C1C2A"/> +<rect x="4" y="11" width="30" height="14" fill="#10192C"/> +<rect x="35" y="11" width="30" height="14" fill="#000C18"/> +<rect x="34" y="11" width="1" height="14" fill="#2B2B4A"/> +<rect x="65" y="11" width="1" height="14" fill="#2B2B4A"/> +<rect x="81" y="73" width="78" height="14" fill="#1C1C2A"/> +<rect x="81" y="73" width="24" height="14" fill="#10192C"/> +<rect x="105" y="73" width="24" height="14" fill="#000C18"/> +<rect x="105" y="73" width="0.503226" height="14" fill="#2B2B4A"/> +<rect x="129" y="73" width="0.503226" height="14" fill="#2B2B4A"/> +<rect x="38" y="16" width="12" height="4" rx="2" fill="#777777"/> +<rect x="107" y="78" width="7" height="4" rx="2" fill="#777777"/> +<rect x="115" y="78" width="11" height="4" rx="2" fill="#777777"/> +<rect x="53" y="16" width="4" height="4" rx="2" fill="#777777"/> +<rect x="7" y="16" width="5" height="4" rx="2" fill="#282828"/> +<rect x="13" y="16" width="16" height="4" rx="2" fill="#282828"/> +<rect x="84" y="78" width="16" height="4" rx="2" fill="#282828"/> +<rect x="8" y="3" width="4" height="4" rx="2" fill="#FD605E"/> +<rect x="14" y="3" width="4" height="4" rx="2" fill="#FBBC3F"/> +<rect x="20" y="3" width="4" height="4" rx="2" fill="#34C942"/> +<rect x="149" y="34" width="10" height="77" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="4" y="34" width="10" height="77" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="18" y="11" width="124" height="10" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="18" y="121" width="124" height="10" fill="#E1E1E1" fill-opacity="0.25"/> +<rect x="90.5" y="112.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="94" y="117" width="7" height="4" rx="2" fill="white"/> +<rect x="105" y="117" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M107.344 125.265C107.52 125.143 107.51 124.88 107.327 124.77L103.18 122.29C102.961 122.16 102.691 122.349 102.739 122.6L103.651 127.344C103.691 127.554 103.935 127.653 104.11 127.53L104.772 127.067C104.867 127 104.914 126.884 104.892 126.769L104.602 125.261C104.554 125.011 104.825 124.821 105.044 124.952L106.362 125.74C106.462 125.8 106.588 125.795 106.683 125.729L107.344 125.265Z" fill="white"/> +<rect x="106.5" y="126.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +<rect x="0.5" y="67.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="4" y="72" width="7" height="4" rx="2" fill="white"/> +<rect x="15" y="72" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M17.3445 80.2654C17.5198 80.1426 17.5104 79.8799 17.3266 79.77L13.1804 77.2905C12.9614 77.1595 12.6906 77.3492 12.7388 77.5997L13.6506 82.344C13.691 82.5542 13.9347 82.653 14.1101 82.5302L14.7716 82.067C14.8669 82.0002 14.9142 81.8836 14.8922 81.7693L14.6024 80.2612C14.5542 80.0106 14.825 79.821 15.044 79.952L16.362 80.7401C16.4619 80.7999 16.5876 80.7954 16.683 80.7286L17.3445 80.2654Z" fill="white"/> +<rect x="16.5" y="81.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +<rect x="133.5" y="50.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="137" y="55" width="7" height="4" rx="2" fill="white"/> +<rect x="148" y="55" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M150.344 63.2654C150.52 63.1426 150.51 62.8799 150.327 62.77L146.18 60.2905C145.961 60.1595 145.691 60.3492 145.739 60.5997L146.651 65.344C146.691 65.5542 146.935 65.653 147.11 65.5302L147.772 65.067C147.867 65.0002 147.914 64.8836 147.892 64.7693L147.602 63.2612C147.554 63.0106 147.825 62.821 148.044 62.952L149.362 63.7401C149.462 63.7999 149.588 63.7954 149.683 63.7286L150.344 63.2654Z" fill="white"/> +<rect x="149.5" y="64.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +<rect x="84.5" y="14.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/> +<rect x="88" y="19" width="7" height="4" rx="2" fill="white"/> +<rect x="99" y="19" width="12" height="4" rx="2" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M101.344 27.2654C101.52 27.1426 101.51 26.8799 101.327 26.77L97.1804 24.2905C96.9614 24.1595 96.6906 24.3492 96.7388 24.5997L97.6506 29.344C97.691 29.5542 97.9347 29.653 98.1101 29.5302L98.7716 29.067C98.8669 29.0002 98.9142 28.8836 98.8922 28.7693L98.6024 27.2612C98.5542 27.0106 98.825 26.821 99.044 26.952L100.362 27.7401C100.462 27.7999 100.588 27.7954 100.683 27.7286L101.344 27.2654Z" fill="white"/> +<rect x="100.5" y="28.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/> +</svg>