Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ <h1>Example Apps with Seam React Components</h1>
<main>
<ul>
<li><a href="%BASE_URL%/basic/">Basic Example</a></li>
<li><a href="%BASE_URL%/web-components/">Web Components</a></li>
</ul>
</main>
</body>
Expand Down
2 changes: 2 additions & 0 deletions examples/vite-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ interface ImportMeta {
SEAM_USER_IDENTIFIER_KEY: string
}
}

declare module '@seamapi/react/elements.js' {}
3 changes: 3 additions & 0 deletions examples/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export default defineConfig(async ({ command, mode }) => {
],
resolve: {
alias: {
'@seamapi/react/elements.js': fileURLToPath(
new URL('../src/elements.js', import.meta.url)
),
'@seamapi/react/index.css': fileURLToPath(
new URL('../src/index.scss', import.meta.url)
),
Expand Down
23 changes: 23 additions & 0 deletions examples/web-components/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Web components example - Seam React Components</title>
</head>
<body>
<main class="seam-components">
<seam-device-table
publishable-key="%SEAM_PUBLISHABLE_KEY%"
user-identifier-key="%SEAM_USER_IDENTIFIER_KEY%"
disable-css-injection="true"
></seam-device-table>
<seam-supported-device-table
publishable-key="%SEAM_PUBLISHABLE_KEY%"
user-identifier-key="%SEAM_USER_IDENTIFIER_KEY%"
disable-css-injection="true"
></seam-supported-device-table>
</main>
<script type="module" src="/web-components/src/main.ts"></script>
</body>
</html>
11 changes: 11 additions & 0 deletions examples/web-components/src/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'vite/client'

interface ImportMetaEnv {
readonly SEAM_ENDPOINT: string
readonly SEAM_PUBLISHABLE_KEY: string
readonly SEAM_USER_IDENTIFIER_KEY: string
}

interface ImportMeta {
readonly env: ImportMetaEnv
}
2 changes: 2 additions & 0 deletions examples/web-components/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '@seamapi/react/index.css'
import '@seamapi/react/elements.js'
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 11 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"./hooks.js": {
"import": "./hooks.js"
},
"./elements.js": {
"import": "./dist/elements.js"
},
"./index.css": {
"import": "./index.css"
}
Expand Down Expand Up @@ -42,6 +45,7 @@
"index.min.css.map",
"lib",
"src",
"dist",
"!test",
"!**/*.test.ts",
"!**/*.test.tsx",
Expand All @@ -52,11 +56,13 @@
"scripts": {
"start": "concurrently --raw --kill-others npm:examples:storybook npm:storybook",
"dev": "npm run start",
"build": "npm run build:js",
"build": "npm run build:entrypoints",
"prebuild": "del 'index.*' 'hooks.*' lib",
"postbuild": "concurrently 'node ./index.js' 'node ./hooks.js'",
"postbuild": "concurrently --raw --group 'node ./index.js' 'node ./hooks.js'",
"build:entrypoints": "npm run build:js",
"prebuild:entrypoints": "npm run build:css",
"postbuild:entrypoints": "vite build",
"build:js": "tsc --project tsconfig.build.json",
"prebuild:js": "npm run build:css",
"postbuild:js": "tsc-alias --project tsconfig.build.json",
"build:css": "sass --load-path=node_modules src/index.scss:index.css",
"postbuild:css": "sass --style=compressed --load-path=node_modules src/index.scss:index.min.css",
Expand All @@ -71,7 +77,7 @@
"lint": "eslint --ignore-path .gitignore --ext .js,.cjs,.mjs,.ts,.tsx .",
"prelint": "prettier --check --ignore-path .gitignore .",
"postlint": "stylelint '**/*.scss'",
"prepack": "echo \"export default '$(jq -r .version < package.json)'\" > lib/version.js",
"prepack": "echo \"const seamapiReactVersion = '$(jq -r .version < package.json)'\n\nexport default seamapiReactVersion\" > src/lib/version.ts && echo \"declare const seamapiReactVersion = \\\"$(jq -r .version < package.json)\\\";\nexport default seamapiReactVersion;\" > lib/version.d.ts && echo -n \"const seamapiReactVersion = '$(jq -r .version < package.json)';\nexport default seamapiReactVersion;\n//# sourceMappingURL=version.js.map\" > lib/version.js",
"postversion": "git push --follow-tags",
"storybook": "storybook dev --port 6006",
"storybook:docs": "storybook dev --docs --port 6007",
Expand Down Expand Up @@ -112,6 +118,7 @@
"@mui/icons-material": "^5.11.16",
"@mui/material": "^5.12.2",
"@seamapi/fake-seam-connect": "^0.7.2",
"@r2wc/react-to-web-component": "^2.0.2",
"@storybook/addon-essentials": "^7.0.2",
"@storybook/addon-interactions": "^7.0.2",
"@storybook/addon-links": "^7.0.2",
Expand Down
27 changes: 27 additions & 0 deletions src/elements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineCustomElement, type ElementDefinition } from 'lib/element.js'
import * as components from 'lib/seam/components/elements.js'

const elementDefinitions = components as unknown as Record<
string,
Partial<ElementDefinition>
>

for (const key of Object.keys(elementDefinitions)) {
const elementDefinition = elementDefinitions[key]

if (elementDefinition == null) {
throw new Error(`Missing element element definition for ${key}`)
}

const { name, Component, props } = elementDefinition

if (name == null) {
throw new Error(`Missing element name for ${key}`)
}

if (Component == null) {
throw new Error(`Missing element Component for ${key}`)
}

defineCustomElement({ name, Component, props })
}
86 changes: 86 additions & 0 deletions src/lib/element.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import r2wc from '@r2wc/react-to-web-component'
import type { ComponentType } from 'react'
import type { Container } from 'react-dom'

import {
SeamProvider,
type SeamProviderPropsWithClientSessionToken,
type SeamProviderPropsWithPublishableKey,
} from 'lib/seam/SeamProvider.js'

declare global {
// eslint-disable-next-line no-var
var disableSeamCssInjection: boolean | undefined
// eslint-disable-next-line no-var
var disableSeamFontInjection: boolean | undefined
// eslint-disable-next-line no-var
var unminifiySeamCss: boolean | undefined
}

export interface ElementDefinition {
name: string
Component: Parameters<typeof r2wc>[0]
props?: ElementProps<Record<string, object>>
}

export type ElementProps<T> = Partial<
Record<keyof T, 'string' | 'number' | 'boolean' | 'function' | 'json'>
>

type ProviderProps = SeamProviderPropsWithPublishableKey &
SeamProviderPropsWithClientSessionToken

const providerProps: ElementProps<ProviderProps> = {
publishableKey: 'string',
userIdentifierKey: 'string',
clientSessionToken: 'string',
disableCssInjection: 'boolean',
disableFontInjection: 'boolean',
unminifiyCss: 'boolean',
}

export const defineCustomElement = ({
name,
Component,
props = {},
}: ElementDefinition): void => {
const element = r2wc(withProvider(Component), {
props: {
...props,
...providerProps,
},
})
globalThis?.customElements?.define(name, element)
}

function withProvider<P extends JSX.IntrinsicAttributes>(
Component: ComponentType<P>
) {
return ({
publishableKey,
userIdentifierKey,
clientSessionToken,
disableCssInjection,
disableFontInjection,
unminifiyCss,
container: _container,
...props
}: ProviderProps & { container: Container } & P): JSX.Element | null => {
return (
<SeamProvider
publishableKey={publishableKey}
userIdentifierKey={userIdentifierKey}
clientSessionToken={clientSessionToken}
disableCssInjection={
disableCssInjection ?? globalThis.disableSeamCssInjection
}
disableFontInjection={
disableFontInjection ?? globalThis.disableSeamFontInjection
}
unminifiyCss={unminifiyCss ?? globalThis?.unminifiySeamCss}
>
<Component {...(props as P)} />
</SeamProvider>
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ElementProps } from 'lib/element.js'

import type { AccessCodeDetailsProps } from './AccessCodeDetails.js'

export const name = 'seam-access-code-details'

export const props: ElementProps<AccessCodeDetailsProps> = {
accessCodeId: 'string',
onBack: 'function',
}

export { AccessCodeDetails as Component } from './AccessCodeDetails.js'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ElementProps } from 'lib/element.js'

import type { AccessCodeTableProps } from './AccessCodeTable.js'

export const name = 'seam-access-code-table'

export const props: ElementProps<AccessCodeTableProps> = {
deviceId: 'string',
onBack: 'function',
}

export { AccessCodeTable as Component } from './AccessCodeTable.js'
12 changes: 12 additions & 0 deletions src/lib/seam/components/DeviceDetails/DeviceDetails.element.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ElementProps } from 'lib/element.js'

import type { DeviceDetailsProps } from './DeviceDetails.js'

export const name = 'seam-device-details'

export const props: ElementProps<DeviceDetailsProps> = {
deviceId: 'string',
onBack: 'function',
}

export { DeviceDetails as Component } from './DeviceDetails.js'
11 changes: 11 additions & 0 deletions src/lib/seam/components/DeviceTable/DeviceTable.element.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { ElementProps } from 'lib/element.js'

import type { DeviceTableProps } from './DeviceTable.js'

export const name = 'seam-device-table'

export const props: ElementProps<DeviceTableProps> = {
onBack: 'function',
}

export { DeviceTable as Component } from './DeviceTable.js'
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ export function SupportedDeviceContent({
function EmptyResult({
filterValue,
resetFilterValue,
}: Pick<SupportedDeviceContentProps, 'filterValue' | 'resetFilterValue'>) {
}: Pick<
SupportedDeviceContentProps,
'filterValue' | 'resetFilterValue'
>): JSX.Element {
const noMatchingRows = (
<>
<p>{t.noMatch}</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { ElementProps } from 'lib/element.js'

import type { SupportedDeviceTableProps } from './SupportedDeviceTable.js'

export const name = 'seam-supported-device-table'

export const props: ElementProps<SupportedDeviceTableProps> = {
cannotFilter: 'boolean',
}

export { SupportedDeviceTable as Component } from './SupportedDeviceTable.js'
5 changes: 5 additions & 0 deletions src/lib/seam/components/elements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * as AccessCodeDetails from './AccessCodeDetails/AccessCodeDetails.element.js'
export * as AccessCodeTable from './AccessCodeTable/AccessCodeTable.element.js'
export * as DeviceDetails from './DeviceDetails/DeviceDetails.element.js'
export * as DeviceTable from './DeviceTable/DeviceTable.element.js'
export * as SupportedDeviceTable from './SupportedDeviceTable/SupportedDeviceTable.element.js'
4 changes: 3 additions & 1 deletion src/lib/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export default null
const seamapiReactVersion = null

export default seamapiReactVersion
1 change: 1 addition & 0 deletions src/stories/Introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ import seamWordmarkS from './assets/seam-wordmark-s.webp'
Seam React component library interactive documentation.

- <a href='/examples/basic/'>Basic Example App</a> ([source](https://github.com/seamapi/react/tree/main/examples/basic/))
- <a href='/examples/web-components/'>Web Components Example App</a> ([source](https://github.com/seamapi/react/tree/main/examples/web-components/))
4 changes: 4 additions & 0 deletions tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"files": ["src/index.ts", "src/hooks.ts"],
"include": ["src/**/*"],
"exclude": [
"src/elements.ts",
"src/lib/element.tsx",
"src/lib/seam/components/elements.ts",
"**/*.element.ts",
"**/*.test.ts",
"**/*.test.tsx",
"**/*.stories.ts",
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"src/**/*",
"test/**/*",
"examples/**/*",
"api/**/*",
".storybook/**/*",
"api/**/*"
"vite.config.ts"
]
}
Loading