From b493ef708166d209bdcec99a7e5b3375d25b2fd3 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 18 May 2026 21:42:31 +0000 Subject: [PATCH 1/2] refactor: Remove SupportedDeviceTable component Removes the SupportedDeviceTable and SupportedDeviceTableManufacturerKeys components along with their stories, tests, related hooks, styles, and example/documentation references. --- CLAUDE.md | 3 +- README.md | 1 - examples/basic/src/App.tsx | 3 - examples/web-components/index.html | 5 - .../FilterCategoryMenu.tsx | 78 ---- .../HiddenDevicesOverlay.tsx | 13 - .../ShowAllDevicesButton.tsx | 32 -- .../SupportedDeviceContent.tsx | 161 ------- .../SupportedDeviceContentRows.tsx | 22 - .../SupportedDeviceFilterArea.tsx | 145 ------ .../SupportedDeviceManufacturerSection.tsx | 109 ----- .../SupportedDeviceRow.tsx | 93 ---- .../SupportedDeviceTable.element.ts | 15 - .../SupportedDeviceTable.stories.tsx | 98 ----- .../SupportedDeviceTable.test.tsx | 11 - .../SupportedDeviceTable.tsx | 70 --- ...rtedDeviceTableManufacturerKeys.element.ts | 9 - ...tedDeviceTableManufacturerKeys.stories.tsx | 28 -- .../SupportedDeviceTableManufacturerKeys.tsx | 64 --- .../SupportedDeviceTable/use-device-model.ts | 44 -- .../SupportedDeviceTable/use-device-models.ts | 57 --- .../use-filtered-device-models.ts | 88 ---- .../use-filtered-manufacturers.test.ts | 109 ----- .../use-filtered-manufacturers.ts | 69 --- .../SupportedDeviceTable/use-manufacturer.ts | 40 -- .../SupportedDeviceTable/use-manufacturers.ts | 53 --- src/lib/seam/components/elements.ts | 2 - src/lib/seam/components/index.ts | 2 - src/stories/Introduction.mdx | 1 - src/styles/_main.scss | 4 - ...ported-device-table-manufacturer-keys.scss | 20 - src/styles/_supported-device-table.scss | 412 ------------------ 32 files changed, 1 insertion(+), 1860 deletions(-) delete mode 100644 src/lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.element.ts delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.stories.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.test.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.ts delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.stories.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.tsx delete mode 100644 src/lib/seam/components/SupportedDeviceTable/use-device-model.ts delete mode 100644 src/lib/seam/components/SupportedDeviceTable/use-device-models.ts delete mode 100644 src/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.ts delete mode 100644 src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.test.ts delete mode 100644 src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.ts delete mode 100644 src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts delete mode 100644 src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts delete mode 100644 src/styles/_supported-device-table-manufacturer-keys.scss delete mode 100644 src/styles/_supported-device-table.scss diff --git a/CLAUDE.md b/CLAUDE.md index fc6648937..9b3e74ff8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,8 +56,7 @@ src/ │ │ ├── CreateAccessCodeForm/ │ │ ├── DeviceDetails/ │ │ ├── DeviceTable/ - │ │ ├── EditAccessCodeForm/ - │ │ └── SupportedDeviceTable/ + │ │ └── EditAccessCodeForm/ │ ├── access-codes/ # Access code hooks │ ├── client-sessions/ # Session hooks │ ├── connected-accounts/ # Account hooks diff --git a/README.md b/README.md index 688ef8a48..5b6ecce3e 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,6 @@ refreshing data, and performing actions. - [Get started with Angular](https://docs.seam.co/latest/seam-components/overview/angular). - [Get started with Vue](https://docs.seam.co/latest/seam-components/overview/vue). - [Get started with Client Sessions](https://docs.seam.co/latest/seam-components/get-started-with-react-components-and-client-session-tokens). -- [Make a Supported Devices Page](https://docs.seam.co/latest/seam-components/make-a-supported-devices-page). - Reference the [Component API](https://docs.seam.co/latest/seam-components/react-components). - Find developer specific technical documentation in the [README](https://github.com/seamapi/react/). - Play with the components live in the interactive [Storybook](https://react.seam.co/)! diff --git a/examples/basic/src/App.tsx b/examples/basic/src/App.tsx index fc2ef5ace..0b7db2735 100644 --- a/examples/basic/src/App.tsx +++ b/examples/basic/src/App.tsx @@ -2,7 +2,6 @@ import { ConnectAccountButton, DeviceTable, SeamProvider, - SupportedDeviceTable, } from '@seamapi/react' export function App(): JSX.Element { @@ -17,8 +16,6 @@ export function App(): JSX.Element {

Seam Components

-

Supported Devices

- ) diff --git a/examples/web-components/index.html b/examples/web-components/index.html index ee32010df..e5e8d9316 100644 --- a/examples/web-components/index.html +++ b/examples/web-components/index.html @@ -17,11 +17,6 @@ user-identifier-key="%SEAM_USER_IDENTIFIER_KEY%" disable-css-injection="true" > - diff --git a/src/lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.tsx b/src/lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.tsx deleted file mode 100644 index 38edab38d..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { ChevronDownIcon } from 'lib/icons/ChevronDown.js' -import { Menu } from 'lib/ui/Menu/Menu.js' -import { MenuItem } from 'lib/ui/Menu/MenuItem.js' - -export type FilterCategoryMenuProps = - | FilterCategoryMenuPropsWithAllOption - | FilterCategoryMenuPropsWithoutAllOption - -interface FilterCategoryMenuPropsWithAllOption - extends FilterCategoryMenuBaseProps { - hideAllOption?: false - allLabel: string - onAllOptionSelect: () => void -} - -interface FilterCategoryMenuPropsWithoutAllOption - extends FilterCategoryMenuBaseProps { - hideAllOption: true - allLabel: never - onAllOptionSelect?: never -} - -interface FilterCategoryMenuBaseProps { - label: string - options: string[] - onSelect: (option: string) => void - buttonLabel?: string -} - -export function FilterCategoryMenu({ - label = t.filter, - allLabel, - options, - hideAllOption = false, - onSelect, - onAllOptionSelect, - buttonLabel, -}: FilterCategoryMenuProps): JSX.Element { - const sortedOptions = [...options].sort((a, b) => a.localeCompare(b)) - const usableOptions = hideAllOption - ? sortedOptions - : [allLabel, ...sortedOptions] - - return ( -
-

{label}

- ( - - )} - > -
- {usableOptions.map((option, index) => ( - { - if (option === allLabel) { - onAllOptionSelect?.() - } else { - onSelect(option) - } - }} - > - {option} - - ))} -
-
-
- ) -} - -const t = { - filter: 'Filter', -} diff --git a/src/lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.tsx b/src/lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.tsx deleted file mode 100644 index bb09576e2..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.tsx +++ /dev/null @@ -1,13 +0,0 @@ -interface HiddenDevicesOverlayProps { - visible: boolean -} - -export function HiddenDevicesOverlay({ - visible, -}: HiddenDevicesOverlayProps): JSX.Element | null { - if (!visible) { - return null - } - - return
-} diff --git a/src/lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.tsx b/src/lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.tsx deleted file mode 100644 index f649bc670..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { ChevronRightIcon } from 'lib/icons/ChevronRight.js' - -interface ShowAllDevicesButtonProps { - onClick: () => void - visible: boolean - expanded: boolean - totalDeviceCount: number -} - -export function ShowAllDevicesButton({ - onClick, - visible, - expanded, - totalDeviceCount, -}: ShowAllDevicesButtonProps): JSX.Element | null { - if (!visible) { - return null - } - - const label = expanded ? t.showLess : t.showAll(totalDeviceCount) - - return ( - - ) -} - -const t = { - showLess: 'Show less', - showAll: (count: number) => `See all ${count}`, -} diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.tsx deleted file mode 100644 index 3a83eff55..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import type { DeviceModel } from '@seamapi/types/devicedb' -import { useMemo } from 'react' - -import { SupportedDeviceManufacturerSection } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.js' -import { - type DeviceModelFilters, - useFilteredDeviceModels, -} from 'lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js' -import { Button } from 'lib/ui/Button.js' - -interface SupportedDeviceContentProps { - filterValue: string - resetFilterValue: () => void - filters: DeviceModelFilters - manufacturers: string[] | null - excludedManufacturers: string[] - includeIf: string[] | null - excludeIf: string[] -} - -export function SupportedDeviceContent({ - resetFilterValue, - filterValue, - filters, - manufacturers, - excludedManufacturers, - includeIf, - excludeIf, -}: SupportedDeviceContentProps): JSX.Element | null { - const { deviceModels, isPending, isError, refetch } = useFilteredDeviceModels( - { - filterValue, - filters, - manufacturers, - excludedManufacturers, - includeIf, - excludeIf, - } - ) - - const groupedDeviceModels = useMemo( - () => groupDeviceModelsByManufacturer(deviceModels ?? []), - [deviceModels] - ) - - if (isPending) { - return ( -
-

{t.loading}

-
- ) - } - - if (isError) { - return ( -
-

{t.error}

- -
- ) - } - - if (deviceModels == null) { - return null - } - - const isEmpty = deviceModels.length === 0 - if (isEmpty) { - return ( -
- -
- ) - } - - return ( - <> - {Object.entries(groupedDeviceModels) - .sort( - (e1, e2) => - e1[1][0]?.manufacturer.display_name.localeCompare( - e2[1][0]?.manufacturer.display_name ?? '' - ) ?? 0 - ) - .map(([manufacturerId, models]) => { - return ( - - ) - })} - - ) -} - -function EmptyResult({ - filterValue, - resetFilterValue, -}: Pick< - SupportedDeviceContentProps, - 'filterValue' | 'resetFilterValue' ->): JSX.Element { - const noMatchingRows = ( - <> -

{t.noMatch}

- - - ) - - return ( -
-
-
- {filterValue.length === 0 ?

{t.noneFound}

: noMatchingRows} -
-
-
- ) -} - -const groupDeviceModelsByManufacturer = ( - deviceModels: DeviceModel[] -): Record => { - const result: Record = {} - - for (const model of deviceModels) { - const { manufacturer } = model - const list = result[manufacturer.manufacturer_id] ?? [] - result[manufacturer.manufacturer_id] = [...list, model] - } - return result -} - -const t = { - loading: 'Loading device models...', - retry: 'Retry', - error: 'There was an error fetching device models.', - noneFound: 'No device models found.', - noMatch: 'No device models matched your search.', - clear: 'Clear search terms', -} diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.tsx deleted file mode 100644 index 1f6af887a..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceContentRows.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import type { DeviceModel } from '@seamapi/types/devicedb' - -import { SupportedDeviceRow } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js' - -interface SupportedDeviceContentRowsProps { - deviceModels: DeviceModel[] -} - -export function SupportedDeviceContentRows({ - deviceModels, -}: SupportedDeviceContentRowsProps): JSX.Element | null { - return ( -
- {deviceModels.map((deviceModel) => ( - - ))} -
- ) -} diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.tsx deleted file mode 100644 index ac231a4ce..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import type { Dispatch, SetStateAction } from 'react' - -import { FilterCategoryMenu } from 'lib/seam/components/SupportedDeviceTable/FilterCategoryMenu.js' -import { - type DeviceModelFilters, - supportedIntegrationSupportLevels, -} from 'lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js' -import { Button } from 'lib/ui/Button.js' -import { Menu } from 'lib/ui/Menu/Menu.js' -import { SearchTextField } from 'lib/ui/TextField/SearchTextField.js' - -import { useFilteredManufacturers } from './use-filtered-manufacturers.js' - -interface SupportedDeviceFilterAreaProps { - filterValue: string - setFilterValue: (filter: string) => void - filters: DeviceModelFilters - setFilters: Dispatch> - manufacturers: string[] | null - excludedManufacturers: string[] -} - -export function SupportedDeviceFilterArea({ - filterValue, - setFilterValue, - filters, - setFilters, - manufacturers, - excludedManufacturers, -}: SupportedDeviceFilterAreaProps): JSX.Element { - const appliedFiltersCount = getAppliedFilterCount(filters) - - const { manufacturers: manufacturersData } = useFilteredManufacturers({ - integrationSupportLevels: filters.supportedOnly - ? supportedIntegrationSupportLevels - : null, - manufacturers, - excludedManufacturers, - }) - - const resetFilter = (filterType: keyof DeviceModelFilters): void => { - setFilters((filters) => ({ - ...filters, - [filterType]: null, - })) - } - - const filterButtonLabel = - appliedFiltersCount > 0 ? `${t.filters} (${appliedFiltersCount})` : t.filter - - const allLabel = t.all - - return ( -
-
-
- ( - - )} - > -
{ - event.stopPropagation() - }} - > -
- manufacturer.display_name - ) ?? [] - } - onSelect={(manufacturer: string) => { - setFilters((filters) => ({ - ...filters, - manufacturer, - })) - }} - buttonLabel={filters.manufacturer ?? allLabel} - onAllOptionSelect={() => { - resetFilter('manufacturer') - }} - /> -
-
- -
-
-
-
- { - setFilterValue(value) - }} - className='seam-supported-device-table-filter-area-search-bar' - /> -
-
-
- ) -} - -const getAppliedFilterCount = (filters: DeviceModelFilters): number => { - let count = 0 - if (filters.manufacturer !== null) count++ - if (!filters.supportedOnly) count++ - return count -} - -const t = { - all: 'All', - manufacturer: 'Manufacturer', - supported: 'Supported', - filter: 'Filter', - filters: 'Filters', -} diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.tsx deleted file mode 100644 index ff46cf66e..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceManufacturerSection.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import type { - DeviceModel, - ManufacturerAnnotation, -} from '@seamapi/types/devicedb' -import classNames from 'classnames' - -import { ChevronRightIcon } from 'lib/icons/ChevronRight.js' -import { InfoBlueIcon } from 'lib/icons/InfoBlue.js' -import { HiddenDevicesOverlay } from 'lib/seam/components/SupportedDeviceTable/HiddenDevicesOverlay.js' -import { ShowAllDevicesButton } from 'lib/seam/components/SupportedDeviceTable/ShowAllDevicesButton.js' -import { SupportedDeviceRow } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.js' -import { useManufacturer } from 'lib/seam/components/SupportedDeviceTable/use-manufacturer.js' -import { useToggle } from 'lib/ui/use-toggle.js' - -/** - * How many device models required before collapsing the list, - * and requiring the user to click to view all. - */ -const maxDevicesBeforeCollapsing = 3 - -interface SupportedDeviceManufacturerSectionProps { - manufacturerId: string - deviceModels: DeviceModel[] -} - -export function SupportedDeviceManufacturerSection({ - manufacturerId, - deviceModels, -}: SupportedDeviceManufacturerSectionProps): JSX.Element | null { - const { manufacturer } = useManufacturer({ manufacturer_id: manufacturerId }) - - const [expanded, toggleExpand] = useToggle() - - const canExpand = deviceModels.length > maxDevicesBeforeCollapsing - - const visibleDevices = - !canExpand || expanded - ? deviceModels - : deviceModels.filter( - (_deviceModel, index) => index < maxDevicesBeforeCollapsing - ) - - const handleHeaderClick = (): void => { - if (!canExpand) { - return - } - - toggleExpand() - } - - return ( -
-
- {manufacturer?.display_name} -
- {manufacturer?.display_name} {t.devices} -
- {canExpand && } -
- {manufacturer?.annotations.map((annotation, idx) => ( - - ))} -
- {visibleDevices.map((deviceModel) => ( - - ))} -
- - -
- ) -} - -function ManufacturerAnnotationBox({ - annotation, -}: { - annotation: ManufacturerAnnotation -}): JSX.Element { - return ( -
- -

{annotation.message}

-
- ) -} - -const t = { - devices: 'Devices', -} diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.tsx deleted file mode 100644 index 46218ede3..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceRow.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import type { DeviceModel } from '@seamapi/types/devicedb' -import classNames from 'classnames' - -import { DotDivider } from 'lib/ui/layout/DotDivider.js' - -interface SupportedDeviceRowProps { - deviceModel: DeviceModel -} - -export function SupportedDeviceRow({ - deviceModel, -}: SupportedDeviceRowProps): JSX.Element { - return ( -
- - - -
- ) -} - -export function ImageColumn({ - deviceModel, -}: SupportedDeviceRowProps): JSX.Element { - return ( -
-
- -
-
- ) -} - -export function ModelColumn({ - deviceModel, -}: SupportedDeviceRowProps): JSX.Element { - const sku = deviceModel.aesthetic_variants[0]?.manufacturer_sku - const connection = - deviceModel.main_connection_type === 'unknown' - ? null - : deviceModel.main_connection_type - return ( -
-
-
{deviceModel.display_name}
-
-
-
- {sku} - {sku != null && connection != null && } - {connection} -
-
-
- ) -} - -export function StatusColumn({ - deviceModel, -}: SupportedDeviceRowProps): JSX.Element { - const statusColor = - supportLevelColors[deviceModel.manufacturer.integration] ?? 'unknown' - - return ( -
-
- {status[deviceModel.manufacturer.integration]} -
-
- ) -} - -const supportLevelColors: Record< - DeviceModel['manufacturer']['integration'], - 'green' | 'blue' | 'unknown' -> = { - stable: 'green', - beta: 'blue', - planned: 'unknown', - unsupported: 'unknown', - inquire: 'unknown', -} - -const status: Record = { - stable: 'LIVE', - beta: 'BETA', - unsupported: 'Inquire', - planned: 'Inquire', - inquire: 'Inquire', -} diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.element.ts b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.element.ts deleted file mode 100644 index f5f829103..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.element.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ElementProps } from 'lib/element.js' - -import type { SupportedDeviceTableProps } from './SupportedDeviceTable.js' - -export const name = 'seam-supported-device-table' - -export const props: ElementProps = { - disableFilter: 'boolean', - manufacturers: 'array', - excludedManufacturers: 'array', - includeIf: 'array', - excludeIf: 'array', -} - -export { SupportedDeviceTable as Component } from './SupportedDeviceTable.js' diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.stories.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.stories.tsx deleted file mode 100644 index f13d4f5ee..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.stories.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { Button, Dialog, DialogActions } from '@mui/material' -import type { Meta, StoryObj } from '@storybook/react' - -import { SupportedDeviceTable } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.js' -import { useToggle } from 'lib/ui/use-toggle.js' - -/** - * These stories showcase the supported devices table. - * - * > **💡 The Storybook uses sample data for demonstration purposes!** - * > - * > ⚡ To see the SupportedDeviceTable with live data, visit https://react.seam.co/examples/basic/ - */ -const meta: Meta = { - title: 'Components/SupportedDeviceTable', - component: SupportedDeviceTable, - tags: ['autodocs'], - parameters: { - design: { - type: 'figma', - url: 'https://www.figma.com/file/6nCfNVHmYQ7wxhnFOpFBm6/Supported-devices?type=design&node-id=171-36651&mode=design&t=JkLcfU9cdo7cMpHR-4', - }, - }, -} - -export default meta - -type Story = StoryObj - -export const Content: Story = {} - -export const NoFilter: Story = { - render: (props) => , -} - -export const ChooseManufacturers: Story = { - render: (props) => ( - - ), -} - -export const ExcludeManufacturers: Story = { - render: (props) => ( - - ), -} - -export const IncludeIf: Story = { - render: (props) => ( - - ), -} - -export const ExcludeIf: Story = { - render: (props) => ( - - ), -} - -export const InsideModal: Story = { - render: (props) => { - const [open, toggleOpen] = useToggle() - return ( - <> - - - - - - - - - - ) - }, -} diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.test.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.test.tsx deleted file mode 100644 index 0ff0c1e1a..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.test.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { test } from 'vitest' - -import type { ApiTestContext } from 'fixtures/api.js' -import { render, screen } from 'fixtures/react.js' - -import { SupportedDeviceTable } from './SupportedDeviceTable.js' - -test('SupportedDeviceTable', async (ctx) => { - render(, ctx) - await screen.findByText('Smart Lock') -}) diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.tsx deleted file mode 100644 index 73775fc9e..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTable.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import classNames from 'classnames' -import { useState } from 'react' - -import { - type CommonProps, - withRequiredCommonProps, -} from 'lib/seam/components/common-props.js' -import { SupportedDeviceContent } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceContent.js' -import { SupportedDeviceFilterArea } from 'lib/seam/components/SupportedDeviceTable/SupportedDeviceFilterArea.js' -import type { DeviceModelFilters } from 'lib/seam/components/SupportedDeviceTable/use-filtered-device-models.js' -import { useComponentTelemetry } from 'lib/telemetry/index.js' - -export interface SupportedDeviceTableProps extends CommonProps { - disableFilter?: boolean - manufacturers?: string[] | null - excludedManufacturers?: string[] - includeIf?: string[] | null - excludeIf?: string[] -} - -export const NestedSupportedDeviceTable = - withRequiredCommonProps(SupportedDeviceTable) - -export function SupportedDeviceTable({ - disableFilter = false, - manufacturers = null, - excludedManufacturers = [], - includeIf = null, - excludeIf = [], - className, -}: SupportedDeviceTableProps = {}): JSX.Element { - useComponentTelemetry('SupportedDeviceTable') - - const [filterValue, setFilterValue] = useState('') - const [filters, setFilters] = useState({ - supportedOnly: true, - manufacturer: null, - }) - - return ( -
- {!disableFilter && ( - - )} - { - setFilterValue('') - }} - filterValue={filterValue} - filters={filters} - manufacturers={manufacturers} - excludedManufacturers={excludedManufacturers} - includeIf={includeIf} - excludeIf={excludeIf} - /> -
- ) -} diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.ts b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.ts deleted file mode 100644 index 3481a79b2..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ElementProps } from 'lib/element.js' - -import type { SupportedDeviceTableManufacturerKeysProps } from './SupportedDeviceTableManufacturerKeys.js' - -export const name = 'seam-supported-device-table-manufacturer-keys' - -export const props: ElementProps = {} - -export { SupportedDeviceTableManufacturerKeys as Component } from './SupportedDeviceTableManufacturerKeys.js' diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.stories.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.stories.tsx deleted file mode 100644 index 1d8638b79..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { Container } from '@mui/material' -import type { Meta, StoryObj } from '@storybook/react' - -import { SupportedDeviceTableManufacturerKeys } from './SupportedDeviceTableManufacturerKeys.js' - -/** - * These stories showcase the valid manufacturer keys for the supported devices table. - * This component is meant for internal documentation and not recommended for external use. - */ -const meta: Meta = { - title: 'Components/SupportedDeviceTableManufacturerKeys', - component: SupportedDeviceTableManufacturerKeys, - tags: ['autodocs'], -} - -export default meta - -type Story = StoryObj - -export const Content: Story = {} - -export const ScrollingContent: Story = { - render: (props) => ( - - - - ), -} diff --git a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.tsx b/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.tsx deleted file mode 100644 index 53f463c62..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import type { Manufacturer } from '@seamapi/types/devicedb' -import classNames from 'classnames' - -import { CopyIcon } from 'lib/icons/Copy.js' -import { - type CommonProps, - withRequiredCommonProps, -} from 'lib/seam/components/common-props.js' -import { useComponentTelemetry } from 'lib/telemetry/index.js' -import { copyToClipboard } from 'lib/ui/clipboard.js' -import { MenuItem } from 'lib/ui/Menu/MenuItem.js' - -import { useManufacturers } from './use-manufacturers.js' - -export interface SupportedDeviceTableManufacturerKeysProps - extends CommonProps {} - -export const NestedSupportedDeviceTableManufacturerKeys = - withRequiredCommonProps(SupportedDeviceTableManufacturerKeys) - -export function SupportedDeviceTableManufacturerKeys({ - className, -}: SupportedDeviceTableManufacturerKeysProps = {}): JSX.Element { - useComponentTelemetry('SupportedDeviceTableManufacturerKeys') - - const { manufacturers } = useManufacturers() - - return ( -
- {manufacturers?.map((manufacturer) => ( - - ))} -
- ) -} - -function ManufacturerKey({ - manufacturer, -}: { - manufacturer: Manufacturer -}): JSX.Element { - const key = manufacturer.display_name - return ( -
-
{key}
- { - void copyToClipboard(key) - }} - > - - -
- ) -} diff --git a/src/lib/seam/components/SupportedDeviceTable/use-device-model.ts b/src/lib/seam/components/SupportedDeviceTable/use-device-model.ts deleted file mode 100644 index 928fcb7bc..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/use-device-model.ts +++ /dev/null @@ -1,44 +0,0 @@ -import type { SeamHttpApiError } from '@seamapi/http/connect' -import { useSeamClient } from '@seamapi/react-query' -import type { - DeviceModel, - RouteRequestParams, - RouteResponse, -} from '@seamapi/types/devicedb' -import { useQuery } from '@tanstack/react-query' - -import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' - -export type UseDeviceModelParams = DeviceModelsGetParams - -export type UseDeviceModelData = DeviceModel | null - -export function useDeviceModel( - params: UseDeviceModelParams -): UseSeamQueryResultLegacy<'deviceModel', UseDeviceModelData> { - const { client: seam } = useSeamClient() - const { data, ...rest } = useQuery({ - enabled: seam != null, - queryKey: ['internal', 'device_models', 'get', params], - queryFn: async () => { - if (seam == null) return null - const { - data: { device_model: deviceModel }, - } = await seam.client.get( - '/internal/devicedb/v1/device_models/get', - { params } - ) - // UPSTREAM: Response type does not match DeviceModel. - return deviceModel as DeviceModel - }, - }) - - return { - ...rest, - deviceModel: data, - } -} - -type DeviceModelsGetParams = RouteRequestParams<'/v1/device_models/get'> - -type DeviceModelsGetResponse = RouteResponse<'/v1/device_models/get'> diff --git a/src/lib/seam/components/SupportedDeviceTable/use-device-models.ts b/src/lib/seam/components/SupportedDeviceTable/use-device-models.ts deleted file mode 100644 index 03d9fea45..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/use-device-models.ts +++ /dev/null @@ -1,57 +0,0 @@ -import type { SeamHttpApiError } from '@seamapi/http/connect' -import { useSeamClient } from '@seamapi/react-query' -import type { - DeviceModel, - RouteRequestParams, - RouteResponse, -} from '@seamapi/types/devicedb' -import { useQuery, useQueryClient } from '@tanstack/react-query' - -import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' - -export type UseDeviceModelsParams = DeviceModelsListParams - -export type UseDeviceModelsData = DeviceModel[] - -export function useDeviceModels( - params?: UseDeviceModelsParams -): UseSeamQueryResultLegacy<'deviceModels', UseDeviceModelsData> { - const { client: seam } = useSeamClient() - const queryClient = useQueryClient() - - const { data, ...rest } = useQuery({ - enabled: seam != null, - queryKey: ['internal', 'device_models', 'list', params], - queryFn: async () => { - if (seam == null) return [] - const { - data: { device_models: deviceModels }, - } = await seam.client.get( - '/internal/devicedb/v1/device_models/list', - { params } - ) - for (const deviceModel of deviceModels) { - queryClient.setQueryData( - [ - 'internal', - 'device_models', - 'get', - { device_model_id: deviceModel.device_model_id }, - ], - deviceModel - ) - } - // UPSTREAM: Response type does not match DeviceModel[]. - return deviceModels as DeviceModel[] - }, - }) - - return { - ...rest, - deviceModels: data, - } -} - -type DeviceModelsListParams = RouteRequestParams<'/v1/device_models/list'> - -type DeviceModelsListResponse = RouteResponse<'/v1/device_models/list'> diff --git a/src/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.ts b/src/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.ts deleted file mode 100644 index 21fec6cfa..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/use-filtered-device-models.ts +++ /dev/null @@ -1,88 +0,0 @@ -import type { ManufacturerIntegrationSupportLevel } from '@seamapi/types/devicedb' - -import { - useDeviceModels, - type UseDeviceModelsParams, -} from 'lib/seam/components/SupportedDeviceTable/use-device-models.js' - -import { useFilteredManufacturers } from './use-filtered-manufacturers.js' - -export interface DeviceModelFilters { - supportedOnly: boolean - manufacturer: string | null -} - -export const supportedIntegrationSupportLevels: ManufacturerIntegrationSupportLevel[] = - ['stable', 'beta'] - -export const useFilteredDeviceModels = ({ - filterValue, - filters, - includeIf, - excludeIf, - ...manufacturersParams -}: { - filterValue: string - filters: DeviceModelFilters - manufacturers: string[] | null - excludedManufacturers: string[] - includeIf: string[] | null - excludeIf: string[] -}): ReturnType => { - const { manufacturers } = useFilteredManufacturers({ - ...manufacturersParams, - integrationSupportLevels: filters.supportedOnly - ? supportedIntegrationSupportLevels - : null, - }) - - const params: UseDeviceModelsParams = {} - - if (excludeIf.length > 0) { - params.exclude_if = excludeIf - } - - // UPSTREAM: API does not parse zero-length arrays correctly. - if (includeIf != null && includeIf.length > 0) { - params.include_if = includeIf - } - - if (filterValue.trim() !== '') { - params.text_search = filterValue.trim() - } - - if (filters.supportedOnly) { - params.integration_support_levels = supportedIntegrationSupportLevels - } - - if (filters.manufacturer !== null) { - const manufacturer = manufacturers?.find( - (manufacturer) => manufacturer.display_name === filters.manufacturer - ) - - if (manufacturer != null) { - params.manufacturer_id = manufacturer.manufacturer_id - } - } - - if (filters.manufacturer == null && manufacturers != null) { - params.manufacturer_ids = manufacturers.map((m) => m.manufacturer_id) - } - - const { deviceModels, ...rest } = useDeviceModels(params) - - return { - ...rest, - deviceModels: - // UPSTREAM: API does not parse zero-length arrays correctly. - includeIf?.length === 0 - ? [] - : deviceModels?.filter((deviceModel) => - manufacturers?.some( - (manufacturer) => - deviceModel.manufacturer.manufacturer_id === - manufacturer.manufacturer_id - ) - ), - } -} diff --git a/src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.test.ts b/src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.test.ts deleted file mode 100644 index 37ddcceb2..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { describe, expect, it } from 'vitest' - -import { createLiqeQuery } from './use-filtered-manufacturers.js' - -describe('createLiqeQuery', () => { - it('returns no query with empty params', () => { - expect( - createLiqeQuery({ - manufacturers: null, - excludedManufacturers: [], - }) - ).toBe(undefined) - }) - - it('returns no query with " in params', () => { - expect( - createLiqeQuery({ - manufacturers: ['august', 'foo"bar'], - excludedManufacturers: [], - }) - ).toBe(undefined) - - expect( - createLiqeQuery({ - manufacturers: null, - excludedManufacturers: ['august', 'foo"bar'], - }) - ).toBe(undefined) - - expect( - createLiqeQuery({ - manufacturers: ['august', 'foo"bar'], - excludedManufacturers: ['august', 'foo"bar'], - }) - ).toBe(undefined) - }) - - it('filters manufacturers', () => { - expect( - createLiqeQuery({ - manufacturers: [], - excludedManufacturers: [], - }) - ).toBe('manufacturer_id:none') - - expect( - createLiqeQuery({ - manufacturers: ['august'], - excludedManufacturers: [], - }) - ).toBe('(display_name:"august")') - - expect( - createLiqeQuery({ - manufacturers: ['august', '4suites', 'smart things'], - excludedManufacturers: [], - }) - ).toBe( - '(display_name:"august" OR display_name:"4suites" OR display_name:"smart things")' - ) - }) - - it('excludes manufacturers', () => { - expect( - createLiqeQuery({ - manufacturers: null, - excludedManufacturers: ['august'], - }) - ).toBe('NOT (display_name:"august")') - - expect( - createLiqeQuery({ - manufacturers: null, - excludedManufacturers: ['august', '4suites', 'smart things'], - }) - ).toBe( - 'NOT (display_name:"august" OR display_name:"4suites" OR display_name:"smart things")' - ) - }) - - it('filters and excludes manufacturers', () => { - expect( - createLiqeQuery({ - manufacturers: ['august'], - excludedManufacturers: ['4suites'], - }) - ).toBe('(display_name:"august") AND NOT (display_name:"4suites")') - - expect( - createLiqeQuery({ - manufacturers: ['august', '4suites', 'smart things'], - excludedManufacturers: ['nuki', 'lockly'], - }) - ).toBe( - '(display_name:"august" OR display_name:"4suites" OR display_name:"smart things") AND NOT (display_name:"nuki" OR display_name:"lockly")' - ) - }) - - it('filters and excludes with uuid', () => { - expect( - createLiqeQuery({ - manufacturers: ['august=aa79cf7a7ff9'], - excludedManufacturers: ['4suites=318b1551bfb4'], - }) - ).toBe( - '(manufacturer_id:"aa79cf7a7ff9") AND NOT (manufacturer_id:"318b1551bfb4")' - ) - }) -}) diff --git a/src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.ts b/src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.ts deleted file mode 100644 index fa70b8f55..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/use-filtered-manufacturers.ts +++ /dev/null @@ -1,69 +0,0 @@ -import type { ManufacturerIntegrationSupportLevel } from '@seamapi/types/devicedb' - -import { useManufacturers } from 'lib/seam/components/SupportedDeviceTable/use-manufacturers.js' - -interface Params { - manufacturers: string[] | null - excludedManufacturers: string[] - integrationSupportLevels: ManufacturerIntegrationSupportLevel[] | null -} - -export const useFilteredManufacturers = ({ - integrationSupportLevels, - ...params -}: Params): ReturnType => { - const { manufacturers, ...rest } = useManufacturers({ - integration_support_levels: integrationSupportLevels ?? undefined, - liqe_query: createLiqeQuery(params), - }) - - return { - ...rest, - manufacturers: manufacturers?.filter( - (manufacturer) => manufacturer.device_model_count > 0 - ), - } -} - -export const createLiqeQuery = ({ - manufacturers, - excludedManufacturers, -}: Pick): - | string - | undefined => { - if ( - (manufacturers?.some(isInvalidInput) ?? false) || - excludedManufacturers.some(isInvalidInput) - ) { - return undefined - } - - const excludedManufacturersClause = `NOT (${excludedManufacturers - .map(manufacturerToMatcher) - .join(' OR ')})` - - if (manufacturers == null) { - if (excludedManufacturers.length === 0) return undefined - return excludedManufacturersClause - } - - if (manufacturers.length === 0) { - return 'manufacturer_id:none' - } - - const includedManufacturersClause = `(${manufacturers - .map(manufacturerToMatcher) - .join(' OR ')})` - - if (excludedManufacturers.length === 0) return includedManufacturersClause - - return `${includedManufacturersClause} AND ${excludedManufacturersClause}` -} - -const manufacturerToMatcher = (value: string): string => { - const [manufacturer, uuid] = value.split('=') - if (uuid != null) return `manufacturer_id:"${uuid}"` - return `display_name:"${manufacturer}"` -} - -const isInvalidInput = (value: string): boolean => value.includes('"') diff --git a/src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts b/src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts deleted file mode 100644 index 3fe0ec4b4..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { SeamHttpApiError } from '@seamapi/http/connect' -import { useSeamClient } from '@seamapi/react-query' -import type { - Manufacturer, - RouteRequestParams, - RouteResponse, -} from '@seamapi/types/devicedb' -import { useQuery } from '@tanstack/react-query' - -import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' - -export type UseManufacturerParams = ManufacturersGetParams - -export type UseManufacturerData = Manufacturer | null - -export function useManufacturer( - params: UseManufacturerParams -): UseSeamQueryResultLegacy<'manufacturer', UseManufacturerData> { - const { client: seam } = useSeamClient() - const { data, ...rest } = useQuery({ - enabled: seam != null, - queryKey: ['internal', 'manufacturers', 'get', params], - queryFn: async () => { - if (seam == null) return null - const { - data: { manufacturer }, - } = await seam.client.get( - '/internal/devicedb/v1/manufacturers/get', - { params } - ) - return manufacturer - }, - }) - - return { ...rest, manufacturer: data } -} - -type ManufacturersGetParams = RouteRequestParams<'/v1/manufacturers/get'> - -type ManufacturersGetResponse = RouteResponse<'/v1/manufacturers/get'> diff --git a/src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts b/src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts deleted file mode 100644 index 21251fd44..000000000 --- a/src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { SeamHttpApiError } from '@seamapi/http/connect' -import { useSeamClient } from '@seamapi/react-query' -import type { - Manufacturer, - RouteRequestParams, - RouteResponse, -} from '@seamapi/types/devicedb' -import { useQuery, useQueryClient } from '@tanstack/react-query' - -import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' - -export type UseManufacturersParams = ManufacturersListParams - -export type UseManufacturersData = Manufacturer[] - -export function useManufacturers( - params?: UseManufacturersParams -): UseSeamQueryResultLegacy<'manufacturers', UseManufacturersData> { - const { client: seam } = useSeamClient() - const queryClient = useQueryClient() - - const { data, ...rest } = useQuery({ - enabled: seam != null, - queryKey: ['internal', 'manufacturers', 'list', params], - queryFn: async () => { - if (seam == null) return [] - const { - data: { manufacturers }, - } = await seam.client.get( - '/internal/devicedb/v1/manufacturers/list', - { params } - ) - for (const manufacturer of manufacturers) { - queryClient.setQueryData( - [ - 'internal', - 'manufacturers', - 'get', - { manufacturer_id: manufacturer.manufacturer_id }, - ], - manufacturer - ) - } - return manufacturers - }, - }) - - return { ...rest, manufacturers: data } -} - -type ManufacturersListParams = RouteRequestParams<'/v1/manufacturers/list'> - -type ManufacturersListResponse = RouteResponse<'/v1/manufacturers/list'> diff --git a/src/lib/seam/components/elements.ts b/src/lib/seam/components/elements.ts index ba9a050ae..1a045877d 100644 --- a/src/lib/seam/components/elements.ts +++ b/src/lib/seam/components/elements.ts @@ -5,5 +5,3 @@ export * as CreateAccessCodeForm from './CreateAccessCodeForm/CreateAccessCodeFo export * as DeviceDetails from './DeviceDetails/DeviceDetails.element.js' export * as DeviceTable from './DeviceTable/DeviceTable.element.js' export * as EditAccessCodeForm from './EditAccessCodeForm/EditAccessCodeForm.element.js' -export * as SupportedDeviceTable from './SupportedDeviceTable/SupportedDeviceTable.element.js' -export * as SupportedDeviceTableManufacturerKeys from './SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.element.js' diff --git a/src/lib/seam/components/index.ts b/src/lib/seam/components/index.ts index 58451ffaa..5fb379b74 100644 --- a/src/lib/seam/components/index.ts +++ b/src/lib/seam/components/index.ts @@ -6,5 +6,3 @@ export * from './CreateAccessCodeForm/CreateAccessCodeForm.js' export * from './DeviceDetails/DeviceDetails.js' export * from './DeviceTable/DeviceTable.js' export * from './EditAccessCodeForm/EditAccessCodeForm.js' -export * from './SupportedDeviceTable/SupportedDeviceTable.js' -export * from './SupportedDeviceTable/SupportedDeviceTableManufacturerKeys.js' diff --git a/src/stories/Introduction.mdx b/src/stories/Introduction.mdx index d82c9cb1d..73a382f94 100644 --- a/src/stories/Introduction.mdx +++ b/src/stories/Introduction.mdx @@ -38,7 +38,6 @@ refreshing data, and performing actions. - [Get started with Angular](https://docs.seam.co/latest/seam-components/overview/angular). - [Get started with Vue](https://docs.seam.co/latest/seam-components/overview/vue). - [Get started with Client Sessions](https://docs.seam.co/latest/seam-components/get-started-with-react-components-and-client-session-tokens). -- [Make a Supported Devices Page](https://docs.seam.co/latest/seam-components/make-a-supported-devices-page). - Reference the [Component API](https://docs.seam.co/latest/seam-components/react-components). - Find developer specific technical documentation in the [README](https://github.com/seamapi/react/). - Play with the components live in the interactive [Storybook](https://react.seam.co/)! diff --git a/src/styles/_main.scss b/src/styles/_main.scss index 53403d84a..641eba01c 100644 --- a/src/styles/_main.scss +++ b/src/styles/_main.scss @@ -13,8 +13,6 @@ @use './device-details'; @use './device-table'; @use './access-code-details'; -@use './supported-device-table'; -@use './supported-device-table-manufacturer-keys'; @use './access-code-form'; @use './input-label'; @use './form-field'; @@ -64,8 +62,6 @@ @include access-code-details.all; @include access-code-form.all; @include alert.all; - @include supported-device-table.all; - @include supported-device-table-manufacturer-keys.all; @include thermostat.all; @include seam-table.all; @include noise-sensor.all; diff --git a/src/styles/_supported-device-table-manufacturer-keys.scss b/src/styles/_supported-device-table-manufacturer-keys.scss deleted file mode 100644 index 75fc3861a..000000000 --- a/src/styles/_supported-device-table-manufacturer-keys.scss +++ /dev/null @@ -1,20 +0,0 @@ -@mixin all { - .supported-device-table-manufacturer-keys { - font-size: 18px; - - .seam-manufacturer-key { - display: table-row; - } - - .seam-manufacturer-key-value { - display: table-cell; - } - - .seam-copy-button { - display: table-cell; - cursor: pointer; - padding-left: 10px; - font-size: 25px; - } - } -} diff --git a/src/styles/_supported-device-table.scss b/src/styles/_supported-device-table.scss deleted file mode 100644 index 951cd9722..000000000 --- a/src/styles/_supported-device-table.scss +++ /dev/null @@ -1,412 +0,0 @@ -@use 'sass:math'; -@use './colors'; - -$row-height: 64px; -$row-padding: 8px; -$see-all-button-height: 30px; - -@mixin all { - .seam-supported-device-table-content-wrap { - background: colors.$white; - } - - .seam-supported-device-table-filter-area { - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - flex-direction: row; - padding: 16px; - - .seam-filters-wrap { - display: flex; - justify-content: flex-start; - align-items: center; - flex-direction: row; - gap: 8px; - } - - .seam-supported-device-table-filter-area-search-bar-wrap { - position: relative; - display: flex; - justify-content: center; - align-items: center; - flex-direction: row; - } - } - - .seam-supported-device-table-filter-menu { - width: 100%; - padding: 8px 16px; - - .seam-filter-menu-row { - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - flex-direction: row; - - &:not(:last-of-type) { - margin-bottom: 8px; - } - - .seam-filter-checkbox-label { - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - flex-direction: row; - } - - .seam-filter-checkbox { - appearance: checkbox; - } - } - - .seam-supported-device-table-filter-menu-wrap { - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - flex-direction: row; - - & button { - appearance: none; - padding: 4px 8px; - padding-right: 24px; - margin: 0; - border: 0; - box-shadow: none; - border-radius: 4px; - background-color: colors.$bg-b; - position: relative; - cursor: pointer; - - &:hover { - background-color: colors.$bg-c; - } - - & span { - font-size: 14px; - font-weight: 500; - } - - & svg { - position: absolute; - top: 2px; - } - } - } - } - - .seam-manufacturer-section { - margin-bottom: 32px; - position: relative; - display: flex; - padding: 8px 16px 16px; - flex-direction: column; - justify-content: center; - align-items: flex-start; - gap: 10px; - align-self: stretch; - - .seam-manufacturer-annotation-box { - display: flex; - padding: 8px; - align-items: center; - align-content: center; - gap: 0 8px; - align-self: stretch; - flex-wrap: wrap; - border-radius: 6px; - background-color: colors.$primary-transparent; - - .seam-annotation { - display: flex; - align-items: flex-start; - align-content: flex-start; - gap: 2px; - flex: 1 0 0; - flex-wrap: wrap; - color: colors.$text-gray-1; - font-size: 14px; - line-height: 120%; - } - } - - .seam-header { - display: flex; - align-items: center; - height: 64px; - - .seam-manufacturer-image { - width: 48px; - height: 48px; - padding: 0 8px; - box-sizing: content-box; - margin-right: 8px; - } - - .seam-manufacturer-name { - font-size: 21px; - line-height: 132%; - flex: 1; - } - - .chevron { - transform: rotate(90deg); - margin-right: 24px; - } - } - - .show-all-devices-button { - cursor: pointer; - background: colors.$white; - display: flex; - height: $see-all-button-height; - padding: 5px 24px 4px 16px; - align-items: center; - gap: 2px; - font-size: 14px; - line-height: 115%; - color: colors.$text-gray-1; - border-radius: 30px; - border: 0; - box-shadow: - 0 1px 1px 0 rgb(16 27 37 / 10%), - 0 1px 8px 0 rgb(46 69 82 / 12%); - position: absolute; - bottom: math.div( - -($row-height - $see-all-button-height - $row-padding), - 2 - ) - or calc(-1 * ($row-height - $see-all-button-height - $row-padding) / 2); - left: 50%; - transform: translate(-50%, -47px); - z-index: 3; - - svg { - transform: rotate(90deg); - font-size: 25px; - } - } - - .hidden-devices-overlay { - background: linear-gradient( - 180deg, - rgb(255 255 255 / 0%) 10.17%, - #fff 86.98% - ); - position: absolute; - height: $row-height; - width: 100%; - bottom: 0; - z-index: 2; - } - - &.can-expand { - .seam-header { - cursor: pointer; - - &:hover { - background: colors.$bg-aa; - } - } - } - - &.expanded { - margin-bottom: 96px; // 32px (usual margin) + 64px (empty row) - - .seam-header { - .chevron { - transform: rotate(270deg); - } - } - - .show-all-devices-button { - transform: translate(-50%, 16px); - - svg { - transform: rotate(270deg); - } - } - } - } - - .seam-supported-device-table-content-state-block { - width: 100%; - background-color: colors.$bg-a; - padding: 32px 8px; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - gap: 8px; - } - - .seam-supported-device-table-content-message-row { - height: auto !important; - } - - .seam-supported-device-table-content-message { - width: 100%; - padding: 32px 0; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - text-align: center; - gap: 4px; - - & p { - line-height: 1; - margin: 0; - } - - & button { - cursor: pointer; - margin-top: 8px; - } - } - - .seam-supported-device-table-content { - width: 100%; - overflow-x: auto; - table-layout: auto; - border-collapse: collapse; - - .seam-row { - height: $row-height; - border-bottom: 1px solid colors.$bg-b; - display: flex; - - &:first-child { - border-top: 1px solid colors.$bg-b; - } - - .seam-col { - display: flex; - padding: 8px; - } - } - - .seam-status-pill { - display: inline-flex; - padding: 4px 8px; - border-radius: 16px; - - & span { - font-size: 11px; - line-height: 134%; - letter-spacing: 0.55px; - } - - &.status-green { - background-color: colors.$pill-green-bg; - color: colors.$pill-green-text; - } - - &.status-blue { - background-color: colors.$pill-blue-bg; - color: colors.$pill-blue-text; - } - - &.status-unknown { - color: colors.$text-gray-1; - font-size: 12px; - line-height: 118%; - } - - &:not(.status-unknown) { - font-weight: 600; - } - } - - .seam-device-image-col { - align-items: center; - - .seam-image-box { - width: 48px; - height: 48px; - - img { - width: 100%; - } - } - } - - .seam-model-col { - flex: 1; - display: flex; - flex-direction: column; - align-items: flex-start; - justify-content: center; - gap: 2px; - - .seam-model-name { - font-size: 14px; - - .seam-truncated-text { - width: 270px; - } - } - - .seam-model-id { - color: colors.$text-gray-2; - font-size: 12px; - - .seam-truncated-text { - width: 220px; - } - - .seam-dot-divider { - margin: 0 4px; - color: colors.$text-gray-3; - } - } - - @media only screen and (width >= 450px) { - .seam-model-name { - font-size: 16px; - } - - .seam-model-id { - font-size: 14px; - } - } - - @media only screen and (width >= 768px) { - flex-direction: row; - align-items: center; - justify-content: flex-start; - - .seam-model-name { - flex: 1; - font-size: 14px; - } - - .seam-model-id { - flex: 0 0 40%; - font-size: 14px; - display: flex; - justify-content: flex-end; - - .seam-truncated-text { - text-align: right; - } - } - } - } - - .seam-status-col { - width: 70px; - text-align: center; - align-items: center; - } - } - - .seam-supported-device-table-filter-menu-content { - max-height: 300px; - overflow: auto; - } -} From 1a72126eb94a786e55f990e5fd3649305d4e8f97 Mon Sep 17 00:00:00 2001 From: Seam Bot Date: Mon, 18 May 2026 21:45:16 +0000 Subject: [PATCH 2/2] ci: Format code --- examples/basic/src/App.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/basic/src/App.tsx b/examples/basic/src/App.tsx index 0b7db2735..217464a85 100644 --- a/examples/basic/src/App.tsx +++ b/examples/basic/src/App.tsx @@ -1,8 +1,4 @@ -import { - ConnectAccountButton, - DeviceTable, - SeamProvider, -} from '@seamapi/react' +import { ConnectAccountButton, DeviceTable, SeamProvider } from '@seamapi/react' export function App(): JSX.Element { return (