From 214f63a8c47c95be738825886afb15a22d3fd30a Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Mon, 20 May 2024 12:36:59 +0200 Subject: [PATCH] Improve types and components, minor improvements to the others (#6029) --- packages/client/news/6029.bugfix | 1 + packages/client/src/restapi/search/get.ts | 7 +- packages/components/news/6029.feature | 1 + .../src/components/Button/Button.tsx | 11 +- .../src/components/Popover/Popover.tsx | 34 +++- .../src/components/Table/Column.tsx | 19 +++ .../components/src/components/Table/Row.tsx | 38 +++++ .../src/components/Table/Table.stories.tsx | 7 +- .../components/src/components/Table/Table.tsx | 145 +++++++++--------- .../src/components/Table/TableHeader.tsx | 38 +++++ .../components/src/components/Toast/Toast.tsx | 41 +++++ packages/components/src/index.ts | 8 +- .../components/src/styles/basic/Table.css | 134 ++++++++-------- packages/components/src/styles/basic/main.css | 7 +- .../components/src/styles/basic/theme.css | 2 +- .../components/src/styles/quanta/Popover.css | 3 + .../components/src/styles/quanta/Table.css | 4 + .../src/styles/quanta/TextField.css | 3 + .../components/src/styles/quanta/main.css | 5 + .../components/src/styles/quanta/theme.css | 4 + packages/providers/news/6029.internal | 1 + packages/providers/src/RouterLocation.tsx | 3 +- packages/types/news/6029.feature | 1 + packages/types/src/index.d.ts | 1 + packages/types/src/services/common.d.ts | 52 +++++++ packages/types/src/services/index.d.ts | 1 + .../src/services/querystring-search.d.ts | 11 +- packages/types/src/services/search.d.ts | 4 +- packages/types/src/utils.d.ts | 4 + 29 files changed, 425 insertions(+), 165 deletions(-) create mode 100644 packages/client/news/6029.bugfix create mode 100644 packages/components/news/6029.feature create mode 100644 packages/components/src/components/Table/Column.tsx create mode 100644 packages/components/src/components/Table/Row.tsx create mode 100644 packages/components/src/components/Table/TableHeader.tsx create mode 100644 packages/components/src/components/Toast/Toast.tsx create mode 100644 packages/components/src/styles/quanta/Popover.css create mode 100644 packages/components/src/styles/quanta/Table.css create mode 100644 packages/components/src/styles/quanta/theme.css create mode 100644 packages/providers/news/6029.internal create mode 100644 packages/types/news/6029.feature create mode 100644 packages/types/src/services/common.d.ts create mode 100644 packages/types/src/utils.d.ts diff --git a/packages/client/news/6029.bugfix b/packages/client/news/6029.bugfix new file mode 100644 index 0000000000..da2cb22b54 --- /dev/null +++ b/packages/client/news/6029.bugfix @@ -0,0 +1 @@ +Fixed path search bug @pnicolli diff --git a/packages/client/src/restapi/search/get.ts b/packages/client/src/restapi/search/get.ts index 2de569d86f..53e44aadd0 100644 --- a/packages/client/src/restapi/search/get.ts +++ b/packages/client/src/restapi/search/get.ts @@ -21,10 +21,13 @@ export const getSearch = async ({ const options: ApiRequestParams = { config, - params: flattenedQuery, + params: { + ...flattenedQuery, + 'path.query': undefined, + }, }; - return apiRequest('get', '/@search', options); + return apiRequest('get', `${query.path?.query ?? ''}/@search`, options); }; export const getSearchQuery = ({ query, config }: SearchArgs) => ({ diff --git a/packages/components/news/6029.feature b/packages/components/news/6029.feature new file mode 100644 index 0000000000..1c8c104fa2 --- /dev/null +++ b/packages/components/news/6029.feature @@ -0,0 +1 @@ +Improved several components and styles @pnicolli diff --git a/packages/components/src/components/Button/Button.tsx b/packages/components/src/components/Button/Button.tsx index b5f2ae1fa8..9e8c76b371 100644 --- a/packages/components/src/components/Button/Button.tsx +++ b/packages/components/src/components/Button/Button.tsx @@ -1,6 +1,9 @@ -import React from 'react'; +import React, { forwardRef, ForwardedRef } from 'react'; import { Button as RACButton, ButtonProps } from 'react-aria-components'; -export function Button(props: ButtonProps) { - return ; -} +export const Button = forwardRef(function _Button( + props: ButtonProps, + ref: ForwardedRef, +) { + return ; +}); diff --git a/packages/components/src/components/Popover/Popover.tsx b/packages/components/src/components/Popover/Popover.tsx index d115987565..a79c3d1418 100644 --- a/packages/components/src/components/Popover/Popover.tsx +++ b/packages/components/src/components/Popover/Popover.tsx @@ -1,24 +1,42 @@ import React from 'react'; import { - Dialog, OverlayArrow, Popover as RACPopover, PopoverProps as RACPopoverProps, } from 'react-aria-components'; +import { Dialog } from '../Dialog/Dialog'; export interface PopoverProps extends Omit { children: React.ReactNode; + /** Mandatory when children don't contain a or dialogAriaLabelledBy */ + dialogAriaLabel?: string; + /** Mandatory when children don't contain a or dialogAriaLabel */ + dialogAriaLabelledby?: string; + showArrow?: boolean; } -export function Popover({ children, ...props }: PopoverProps) { +export function Popover({ + children, + dialogAriaLabel, + dialogAriaLabelledby, + showArrow, + ...props +}: PopoverProps) { return ( - - - - - - {children} + {showArrow && ( + + + + + + )} + + {children} + ); } diff --git a/packages/components/src/components/Table/Column.tsx b/packages/components/src/components/Table/Column.tsx new file mode 100644 index 0000000000..180f28a22e --- /dev/null +++ b/packages/components/src/components/Table/Column.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { type ColumnProps, Column as RACColumn } from 'react-aria-components'; + +export function Column(props: ColumnProps) { + return ( + + {({ allowsSorting, sortDirection }) => ( + <> + {props.children} + {allowsSorting && ( + + )} + + )} + + ); +} diff --git a/packages/components/src/components/Table/Row.tsx b/packages/components/src/components/Table/Row.tsx new file mode 100644 index 0000000000..7521a581d1 --- /dev/null +++ b/packages/components/src/components/Table/Row.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { + type RowProps, + Row as RACRow, + Cell, + Collection, + useTableOptions, + Button, +} from 'react-aria-components'; +import { Checkbox } from '../Checkbox/Checkbox'; +import { DraggableIcon } from '../Icons/DraggableIcon'; + +export function Row({ + id, + columns, + children, + ...otherProps +}: RowProps) { + let { selectionBehavior, allowsDragging } = useTableOptions(); + + return ( + + {allowsDragging && ( + + + + )} + {selectionBehavior === 'toggle' && ( + + + + )} + {children} + + ); +} diff --git a/packages/components/src/components/Table/Table.stories.tsx b/packages/components/src/components/Table/Table.stories.tsx index 82f5f9270a..bb2c3e68b2 100644 --- a/packages/components/src/components/Table/Table.stories.tsx +++ b/packages/components/src/components/Table/Table.stories.tsx @@ -1,5 +1,8 @@ import React from 'react'; -import { Table, TableHeader, Row, Column } from './Table'; +import { Table } from './Table'; +import { TableHeader } from './TableHeader'; +import { Column } from './Column'; +import { Row } from './Row'; import { Cell, TableBody } from 'react-aria-components'; import type { Meta, StoryObj } from '@storybook/react'; @@ -46,7 +49,7 @@ export const Default: Story = { ), args: { - onRowAction: null, + onRowAction: undefined, // selectionMode: "multiple", }, }; diff --git a/packages/components/src/components/Table/Table.tsx b/packages/components/src/components/Table/Table.tsx index 1fb3074d96..aa02923cd6 100644 --- a/packages/components/src/components/Table/Table.tsx +++ b/packages/components/src/components/Table/Table.tsx @@ -1,83 +1,90 @@ -import React from 'react'; +import React, { type ReactNode, type ComponentProps } from 'react'; import { - Button, - Cell, - Collection, - Column as RACColumn, - ColumnProps, - Row as RACRow, - RowProps, + type TableProps as RACTableProps, + ResizableTableContainer, + ColumnResizer, Table as RACTable, - TableHeader as RACTableHeader, - TableHeaderProps, - TableProps, - useTableOptions, + TableBody, + Cell, } from 'react-aria-components'; +import { TableHeader } from './TableHeader'; +import { Column } from './Column'; +import { Row } from './Row'; -import { Checkbox } from '../Checkbox/Checkbox'; - -export function Table(props: TableProps) { - return ; +interface ColumnType { + id: string; + name: ReactNode; + isRowHeader?: boolean; + // TODO support width constraints for resizable columns } -export function Column(props: ColumnProps) { - return ( - - {({ allowsSorting, sortDirection }) => ( - <> - {props.children} - {allowsSorting && ( - - )} - - )} - - ); +interface RowType { + id: string; + textValue?: string; + [key: string]: ReactNode; // TODO can we make this more specific? } -export function TableHeader({ - columns, - children, -}: TableHeaderProps) { - let { selectionBehavior, selectionMode, allowsDragging } = useTableOptions(); - - return ( - - {/* Add extra columns for drag and drop and selection. */} - {allowsDragging && } - {selectionBehavior === 'toggle' && ( - - {selectionMode === 'multiple' && } - - )} - {children} - - ); +interface TableProps extends RACTableProps { + columns?: C[]; + rows?: R[]; + resizableColumns?: boolean; + dragColumnHeader?: ComponentProps['dragColumnHeader']; + // TODO maybe a custom "selectall" component? Is it doable with react-aria-components? } -export function Row({ - id, +/** + * A wrapper around the `react-aria-components` Table component. + * + * See https://react-spectrum.adobe.com/react-aria/Table.html + */ +export function Table({ columns, - children, + rows, + resizableColumns, + dragColumnHeader, ...otherProps -}: RowProps) { - let { selectionBehavior, allowsDragging } = useTableOptions(); +}: TableProps) { + let table = null; + if (Array.isArray(columns) && Array.isArray(rows)) { + table = ( + + + {(column) => ( + + {resizableColumns && ( +
+ + {column.name} + + +
+ )} + {!resizableColumns && column.name} +
+ )} +
+ + {(item) => ( + + {(column) => {item[column.id]}} + + )} + +
+ ); + } else { + table = ; + + if (Array.isArray(columns)) { + console.warn('The Table component was given columns but no rows'); + } else if (Array.isArray(rows)) { + console.warn('The Table component was given rows but no columns'); + } + } - return ( - - {allowsDragging && ( - - - - )} - {selectionBehavior === 'toggle' && ( - - - - )} - {children} - - ); + if (resizableColumns) { + return {table}; + } else { + return table; + } } diff --git a/packages/components/src/components/Table/TableHeader.tsx b/packages/components/src/components/Table/TableHeader.tsx new file mode 100644 index 0000000000..fdf774cfac --- /dev/null +++ b/packages/components/src/components/Table/TableHeader.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { + type TableHeaderProps, + TableHeader as RACTableHeader, + useTableOptions, + Collection, +} from 'react-aria-components'; +import { Checkbox } from '../Checkbox/Checkbox'; +import { Column } from './Column'; + +interface Props extends TableHeaderProps { + dragColumnHeader?: React.ReactNode; +} + +export function TableHeader({ + columns, + children, + dragColumnHeader, +}: Props) { + let { selectionBehavior, selectionMode, allowsDragging } = useTableOptions(); + + return ( + + {/* Add extra columns for drag and drop and selection. */} + {allowsDragging && ( + + {dragColumnHeader} + + )} + {selectionBehavior === 'toggle' && ( + + {selectionMode === 'multiple' && } + + )} + {children} + + ); +} diff --git a/packages/components/src/components/Toast/Toast.tsx b/packages/components/src/components/Toast/Toast.tsx new file mode 100644 index 0000000000..88ec5d825d --- /dev/null +++ b/packages/components/src/components/Toast/Toast.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { CheckboxIcon, InfoIcon, CloseIcon } from '../Icons'; + +interface Props { + title?: string | Array; + content: string; + info?: boolean; + success?: boolean; + error?: boolean; + warning?: boolean; +} + +export function Toast(props: Props) { + function getIcon(props: Props) { + if (props.info) { + return InfoIcon; + } else if (props.success) { + return CheckboxIcon; + } else if (props.error) { + return CloseIcon; + } else if (props.warning) { + return CloseIcon; + } else { + return CheckboxIcon; + } + } + + const { title, content } = props; + + const Icon = getIcon(props); + + return ( + <> + +
+ {title &&

{title}

} +

{content}

+
+ + ); +} diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index ca95dd06e3..fd11f012a8 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -21,7 +21,7 @@ export { Menu, MenuItem } from './components/Menu/Menu'; export { Meter } from './components/Meter/Meter'; export { Modal } from './components/Modal/Modal'; export { NumberField } from './components/NumberField/NumberField'; -export { Popover } from './components/Popover/Popover'; +export { Popover, type PopoverProps } from './components/Popover/Popover'; export { ProgressBar } from './components/ProgressBar/ProgressBar'; export { RadioGroup } from './components/RadioGroup/RadioGroup'; export { RangeCalendar } from './components/RangeCalendar/RangeCalendar'; @@ -29,12 +29,16 @@ export { SearchField } from './components/SearchField/SearchField'; export { Select, SelectItem } from './components/Select/Select'; export { Slider } from './components/Slider/Slider'; export { Switch } from './components/Switch/Switch'; -export { Table, TableHeader, Row, Column } from './components/Table/Table'; +export { Table } from './components/Table/Table'; +export { TableHeader } from './components/Table/TableHeader'; +export { Row } from './components/Table/Row'; +export { Column } from './components/Table/Column'; export { Tabs } from './components/Tabs/Tabs'; export { TagGroup, Tag } from './components/TagGroup/TagGroup'; export { TextAreaField } from './components/TextAreaField/TextAreaField'; export { TextField } from './components/TextField/TextField'; export { TimeField } from './components/TimeField/TimeField'; +export { Toast } from './components/Toast/Toast'; export { ToggleButton } from './components/ToggleButton/ToggleButton'; export { Toolbar } from './components/Toolbar/Toolbar'; export { Tooltip } from './components/Tooltip/Tooltip'; diff --git a/packages/components/src/styles/basic/Table.css b/packages/components/src/styles/basic/Table.css index b7da2be130..a876bf2501 100644 --- a/packages/components/src/styles/basic/Table.css +++ b/packages/components/src/styles/basic/Table.css @@ -5,14 +5,38 @@ @import './Menu.css'; @import './theme.css'; +:root { + --plone-table-border: 0 none; + --plone-table-border-radius: 0; + --plone-table-padding: 0.286rem; + --plone-table-width: initial; + --plone-table-max-width: 100%; + --plone-table-background: var(--overlay-background); + + --plone-table-header-color: var(--text-color); + --plone-table-header-font-size: 1rem; + --plone-table-header-border-bottom: 1px solid var(--border-color); + + --plone-table-row-color: var(--text-color); + --plone-table-row-font-size: 1rem; + --plone-table-row-pressed: var(--highlight-pressed); + --plone-table-row-border-radius: 0; + + --plone-table-column-font-weight: 500; + + --plone-table-cell-padding: 18px 12px; + --plone-table-cell-border-bottom: 1px solid var(--smoke); +} + .react-aria-Table { + width: var(--plone-table-width); max-width: 100%; min-height: 100px; align-self: start; - padding: 0.286rem; - border: 1px solid var(--border-color); - border-radius: 6px; - background: var(--overlay-background); + padding: var(--plone-table-padding); + border: var(--plone-table-border); + border-radius: var(--plone-table-border-radius); + background: var(--plone-table-background); border-spacing: 0; forced-color-adjust: none; outline: none; @@ -24,16 +48,11 @@ } .react-aria-TableHeader { - color: var(--text-color); - - &:after { - display: table-row; - height: 2px; - content: ''; - } + color: var(--plone-table-header-color); + font-size: var(--plone-table-header-font-size); & tr:last-child .react-aria-Column { - border-bottom: 1px solid var(--border-color); + border-bottom: var(--plone-table-header-border-bottom); cursor: default; } } @@ -44,11 +63,11 @@ --radius: var(--radius-top) var(--radius-top) var(--radius-bottom) var(--radius-bottom); position: relative; - border-radius: var(--radius); + border-radius: var(--plone-table-row-border-radius); clip-path: inset(0 round var(--radius)); /* firefox */ - color: var(--text-color); + color: var(--plone-table-row-color); cursor: default; - font-size: 1.072rem; + font-size: var(--plone-table-row-font-size); outline: none; transform: scale(1); @@ -58,13 +77,17 @@ } &[data-pressed] { - background: var(--gray-100); + background: var(--plone-table-row-pressed); } &[data-selected] { background: var(--highlight-background); color: var(--highlight-foreground); + --text-color: var(--highlight-foreground); --focus-ring-color: var(--highlight-foreground); + --link-color: var(--highlight-foreground); + --link-color-secondary: var(--highlight-foreground); + --button-background: var(--highlight-background); &[data-focus-visible], .react-aria-Cell[data-focus-visible] { @@ -75,11 +98,31 @@ &[data-disabled] { color: var(--text-color-disabled); } + + &[data-dragging] { + opacity: 0.6; + transform: translateZ(0); + } + + [slot='drag'] { + all: unset; + width: 1em; + text-align: center; + + &[data-focus-visible] { + border-radius: 4px; + outline: 2px solid var(--focus-ring-color); + } + } + + &[data-href] { + cursor: pointer; + } } .react-aria-Cell, .react-aria-Column { - padding: 4px 8px; + padding: var(--plone-table-cell-padding); outline: none; text-align: left; @@ -90,6 +133,7 @@ } .react-aria-Cell { + border-bottom: var(--plone-table-cell-border-bottom); transform: translateZ(0); &:first-child { @@ -126,11 +170,9 @@ --background-color: var(--highlight-background); } -.react-aria-Row[data-href] { - cursor: pointer; -} - .react-aria-Column { + font-weight: var(--plone-table-column-font-weight); + .sort-indicator { padding: 0 2px; } @@ -140,25 +182,23 @@ } } -.react-aria-TableBody { - &[data-empty] { - font-style: italic; - text-align: center; - } -} - .react-aria-ResizableTableContainer { position: relative; overflow: auto; - max-width: 400px; - border: 1px solid var(--border-color); - border-radius: 6px; - background: var(--background-color); + max-width: var(--plone-table-max-width); + border: var(--plone-table-border); + border-radius: var(--plone-table-border-radius); + background: var(--plone-table-background); .react-aria-Table { border: none; } + .flex-wrapper { + display: flex; + align-items: center; + } + .column-name, .react-aria-Button { --background-color: var(--overlay-background); @@ -226,24 +266,6 @@ } } -.react-aria-Row { - &[data-dragging] { - opacity: 0.6; - transform: translateZ(0); - } - - [slot='drag'] { - all: unset; - width: 15px; - text-align: center; - - &[data-focus-visible] { - border-radius: 4px; - outline: 2px solid var(--focus-ring-color); - } - } -} - .react-aria-DropIndicator[data-drop-target] { outline: 1px solid var(--highlight-background); transform: translateZ(0); @@ -259,15 +281,3 @@ background: var(--highlight-overlay); outline: 2px solid var(--highlight-background); } - -.react-aria-DropIndicator[data-drop-target] { - outline: 1px solid var(--highlight-background); - transform: translateZ(0); -} - -.react-aria-Cell img { - display: block; - width: 30px; - height: 30px; - object-fit: cover; -} diff --git a/packages/components/src/styles/basic/main.css b/packages/components/src/styles/basic/main.css index 5f441b2bcc..60173bd34b 100644 --- a/packages/components/src/styles/basic/main.css +++ b/packages/components/src/styles/basic/main.css @@ -1,3 +1,7 @@ +@import './theme.css'; + +@import './icons.css'; + @import './Link.css'; @import './Button.css'; @import './ToggleButton.css'; @@ -39,6 +43,3 @@ @import './BlockToolbar.css'; @import './Container.css'; -@import './icons.css'; - -@import './theme.css'; diff --git a/packages/components/src/styles/basic/theme.css b/packages/components/src/styles/basic/theme.css index 9b99936dbe..3026b815df 100644 --- a/packages/components/src/styles/basic/theme.css +++ b/packages/components/src/styles/basic/theme.css @@ -48,7 +48,7 @@ --text-color: var(--basic-950); /* --gray-600 */ --text-color-base: var(--basic-600); /* --gray-500 */ --text-color-hover: var(--basic-950); /* --gray-600 */ - --text-color-disabled: var(--basic-400); /* --gray-200 */ + --text-color-disabled: var(--basic-500); /* --gray-200 */ --text-color-placeholder: var(--gray-400); /* Link */ --link-color: var(--quanta-sapphire); diff --git a/packages/components/src/styles/quanta/Popover.css b/packages/components/src/styles/quanta/Popover.css new file mode 100644 index 0000000000..caf9cee464 --- /dev/null +++ b/packages/components/src/styles/quanta/Popover.css @@ -0,0 +1,3 @@ +.q.react-aria-Popover { + --border-color: transparent; +} diff --git a/packages/components/src/styles/quanta/Table.css b/packages/components/src/styles/quanta/Table.css new file mode 100644 index 0000000000..64bf060907 --- /dev/null +++ b/packages/components/src/styles/quanta/Table.css @@ -0,0 +1,4 @@ +.react-aria-Table { + --plone-table-header-color: var(--quanta-sapphire); + --plone-table-cell-border-bottom: 1px solid var(--quanta-smoke); +} diff --git a/packages/components/src/styles/quanta/TextField.css b/packages/components/src/styles/quanta/TextField.css index 18162e0709..2ef292e85a 100644 --- a/packages/components/src/styles/quanta/TextField.css +++ b/packages/components/src/styles/quanta/TextField.css @@ -87,7 +87,10 @@ ) { color: var(--basic-500); } +} +.q.react-aria-TextField, +.q.react-aria-TextAreaField { .react-aria-Input, .react-aria-TextArea { width: 100%; diff --git a/packages/components/src/styles/quanta/main.css b/packages/components/src/styles/quanta/main.css index 36b9f0597b..6547762ff1 100644 --- a/packages/components/src/styles/quanta/main.css +++ b/packages/components/src/styles/quanta/main.css @@ -1,3 +1,8 @@ @import './colors.css'; +@import './theme.css'; + +/* Components */ @import './TextField.css'; @import './Select.css'; +@import './Table.css'; +@import './Popover.css'; diff --git a/packages/components/src/styles/quanta/theme.css b/packages/components/src/styles/quanta/theme.css new file mode 100644 index 0000000000..fceaf7de56 --- /dev/null +++ b/packages/components/src/styles/quanta/theme.css @@ -0,0 +1,4 @@ +:root { + --highlight-background: var(--quanta-sapphire); + --highlight-background-pressed: var(--quanta-royal); +} diff --git a/packages/providers/news/6029.internal b/packages/providers/news/6029.internal new file mode 100644 index 0000000000..528d1fc297 --- /dev/null +++ b/packages/providers/news/6029.internal @@ -0,0 +1 @@ +Cleanup imports in RouterLocation provider @pnicolli diff --git a/packages/providers/src/RouterLocation.tsx b/packages/providers/src/RouterLocation.tsx index 39806baea1..f2881957d4 100644 --- a/packages/providers/src/RouterLocation.tsx +++ b/packages/providers/src/RouterLocation.tsx @@ -1,5 +1,4 @@ -import React from 'react'; -import { createContext, ReactNode, useContext, useMemo } from 'react'; +import React, { createContext, ReactNode, useContext, useMemo } from 'react'; export type AnySearchSchema = {}; export interface Location { diff --git a/packages/types/news/6029.feature b/packages/types/news/6029.feature new file mode 100644 index 0000000000..e1f77cd58c --- /dev/null +++ b/packages/types/news/6029.feature @@ -0,0 +1 @@ +New Brain type and new ArrayElement utility @pnicolli diff --git a/packages/types/src/index.d.ts b/packages/types/src/index.d.ts index 7a19a7634a..9364577e39 100644 --- a/packages/types/src/index.d.ts +++ b/packages/types/src/index.d.ts @@ -2,4 +2,5 @@ export * from './blocks'; export * from './config'; export * from './content'; export * from './services'; +export * from './utils'; import './modules'; diff --git a/packages/types/src/services/common.d.ts b/packages/types/src/services/common.d.ts new file mode 100644 index 0000000000..8d1f25ab37 --- /dev/null +++ b/packages/types/src/services/common.d.ts @@ -0,0 +1,52 @@ +import type { PreviewImage } from '../content/common'; + +export interface Brain { + '@id': string; + '@type': string; + CreationDate: string; + Creator: string; + Date: string; + Description: string; + EffectiveDate: string | 'None'; // 'None' here is just for documentation + ExpirationDate: string | 'None'; // 'None' here is just for documentation + ModificationDate: string; + Subject: string[]; + Title: string; + Type: string; + UID: string; + author_name: string | null; + cmf_uid: string | null; + commentators: string[]; + created: string; + description: string; + effective: string | '1969-12-31T00:00:00+00:00'; // '1969-12-31T00:00:00+00:00' here is just for documentation + end: string | null; + exclude_from_nav: boolean; + expires: string | '2499-12-31T00:00:00+00:00'; // '2499-12-31T00:00:00+00:00' here is just for documentation + getIcon: string | null; // TODO is this correct? + getId: string; + getObjSize: string; + getPath: string; + getRemoteUrl: string | null; + getURL: string; + hasPreviewImage: boolean | null; // TODO is this correct? + head_title: string | null; // TODO is this correct? + id: string; + image_field: string; // TODO could this be more specific? + image_scales: Record | null; // TODO could this be more specific? + in_response_to: string | null; // TODO is this correct? + is_folderish: boolean; + last_comment_date: string | null; + listCreators: string[]; + location: string | null; // TODO is this correct? + mime_type: string; // TODO could this be more specific? + modified: string; + nav_title: string | null; // TODO is this correct? + portal_type: string; // TODO could this be more specific? + review_state: string; // TODO could this be more specific? + start: string | null; + sync_uid: string | null; + title: string; + total_comments: number; + type_title: string; // TODO could this be more specific? +} diff --git a/packages/types/src/services/index.d.ts b/packages/types/src/services/index.d.ts index ab2417113a..12a8a71c6b 100644 --- a/packages/types/src/services/index.d.ts +++ b/packages/types/src/services/index.d.ts @@ -1,3 +1,4 @@ +export * from './common'; export * from './actions'; export * from './breadcrumbs'; export * from './navigation'; diff --git a/packages/types/src/services/querystring-search.d.ts b/packages/types/src/services/querystring-search.d.ts index 520d945543..e60078c1a0 100644 --- a/packages/types/src/services/querystring-search.d.ts +++ b/packages/types/src/services/querystring-search.d.ts @@ -1,14 +1,7 @@ -interface ResultItem { - '@id': string; - '@type': string; - description: string; - review_state: string; - title: string; - type_title: string; -} +import { Brain } from './common'; export interface QuerystringSearchResponse { '@id': string; - items: ResultItem[]; + items: Brain[]; items_total: number; } diff --git a/packages/types/src/services/search.d.ts b/packages/types/src/services/search.d.ts index d1579492d6..39a119d56f 100644 --- a/packages/types/src/services/search.d.ts +++ b/packages/types/src/services/search.d.ts @@ -1,5 +1,7 @@ +import { Brain } from './common'; + export interface GetSearchResponse { '@id': string; - items: any[]; + items: Brain[]; items_total: number; } diff --git a/packages/types/src/utils.d.ts b/packages/types/src/utils.d.ts new file mode 100644 index 0000000000..220a792ceb --- /dev/null +++ b/packages/types/src/utils.d.ts @@ -0,0 +1,4 @@ +/** + * Get the type of the elements in an array + */ +export type ArrayElement = A extends readonly (infer T)[] ? T : never;