@monimesl/dot-renderer-react 0.1.0-alpha.2 → 0.1.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/theme.ts","../src/components/tokens.ts","../src/components/button.tsx","../src/components/image.tsx","../src/components/input.tsx","../src/components/text.tsx","../src/components/view.tsx","../src/components/index.ts","../src/page-root.tsx","../src/root.tsx","../src/renderer.tsx","../src/index.ts"],"sourcesContent":["import type { ColorScheme, SchemeColor, Theme } from '@monimesl/dot-core';\nimport { createContext, useContext } from 'react';\n\nexport interface ResolvedColors {\n primary: string;\n background: string;\n surface: string;\n text: string;\n subtle: string;\n muted: string;\n border: string;\n}\n\nexport interface ResolvedTheme {\n scheme: ColorScheme;\n colors: ResolvedColors;\n radius: number;\n}\n\nexport const FONT_FAMILY = 'system-ui, sans-serif';\n\nconst DEFAULT_RADIUS = 12;\n\n// Dash's own look: black, white and grays, so a dot feels at home in it.\nconst DEFAULT_COLORS: Record<ColorScheme, ResolvedColors> = {\n light: {\n primary: '#1c1c1e',\n background: '#f2f2f2',\n surface: '#ffffff',\n text: '#111111',\n subtle: '#8e8e93',\n muted: '#e9e9eb',\n border: '#e9e9eb',\n },\n dark: {\n primary: '#f5f5f5',\n background: '#121212',\n surface: '#1e1e1e',\n text: '#f5f5f5',\n subtle: '#8e8e93',\n muted: '#2c2c2e',\n border: '#2a2a2c',\n },\n};\n\nexport function resolveTheme(theme: Theme, systemScheme: ColorScheme): ResolvedTheme {\n const scheme = !theme.scheme || theme.scheme === 'system' ? systemScheme : theme.scheme;\n const defaults = DEFAULT_COLORS[scheme];\n const colors = theme.colors ?? {};\n const pick = (color: SchemeColor | undefined, fallback: string) => color?.[scheme] ?? fallback;\n return {\n scheme,\n colors: {\n primary: pick(colors.primary, defaults.primary),\n background: pick(colors.background, defaults.background),\n surface: pick(colors.surface, defaults.surface),\n text: pick(colors.text, defaults.text),\n subtle: defaults.subtle,\n muted: defaults.muted,\n border: defaults.border,\n },\n radius: theme.radius ?? DEFAULT_RADIUS,\n };\n}\n\nexport const ThemeContext = createContext<ResolvedTheme>(resolveTheme({}, 'light'));\n\nexport function useTheme(): ResolvedTheme {\n return useContext(ThemeContext);\n}\n","export const GAP = { none: 0, small: 4, medium: 8, large: 16 } as const;\n\nexport const FONT_SIZE = { caption: 13, body: 15, title: 20 } as const;\n\n// Between content and the edge of the page or of a card.\nexport const PADDING = 16;\n\n// Cards round a little more than the controls inside them.\nexport const CARD_RADIUS_SCALE = 1.5;\n\nexport const DISABLED_OPACITY = 0.6;\n","import type { Button as ButtonManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\n\nimport type { ReactComponent } from '../types';\nimport { useTheme } from '../theme';\nimport { DISABLED_OPACITY, FONT_SIZE } from './tokens';\n\nexport const Button: ReactComponent<typeof ButtonManifest> = ({\n variant = 'primary',\n disabled,\n onClick,\n children,\n}) => {\n const { colors, radius } = useTheme();\n const filled = variant === 'primary' && !disabled;\n let color = colors.text;\n if (filled) {\n color = colors.surface;\n } else if (disabled) {\n color = colors.subtle;\n }\n const handleClick = onClick ? () => onClick(createEvent('click')) : undefined;\n return (\n <button\n type=\"button\"\n className=\"dot-button\"\n data-variant={variant}\n disabled={disabled}\n onClick={handleClick}\n style={{\n padding: '10px 16px',\n border: 'none',\n borderRadius: radius,\n background: filled ? colors.primary : colors.muted,\n color,\n font: 'inherit',\n fontSize: FONT_SIZE.body,\n fontWeight: 600,\n opacity: disabled ? DISABLED_OPACITY : 1,\n cursor: disabled ? 'default' : 'pointer',\n }}\n >\n {children}\n </button>\n );\n};\n","import type { Image as ImageManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\nimport type { SyntheticEvent } from 'react';\n\nimport type { ReactComponent } from '../types';\nimport { useTheme } from '../theme';\n\nexport const Image: ReactComponent<typeof ImageManifest> = ({\n src,\n alt,\n width,\n height,\n onLoad,\n onError,\n}) => {\n const { radius } = useTheme();\n const handleLoad = onLoad\n ? (event: SyntheticEvent<HTMLImageElement>) => {\n const { naturalWidth, naturalHeight } = event.currentTarget;\n onLoad(createEvent('load', { width: naturalWidth, height: naturalHeight }));\n }\n : undefined;\n const handleError = onError\n ? () => onError(createEvent('error', { message: `Failed to load ${src}` }))\n : undefined;\n return (\n <img\n className=\"dot-image\"\n src={src}\n alt={alt ?? ''}\n width={width}\n height={height}\n style={{ borderRadius: radius }}\n onLoad={handleLoad}\n onError={handleError}\n />\n );\n};\n","import type { Input as InputManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\nimport { useState } from 'react';\n\nimport type { ReactComponent } from '../types';\nimport { useTheme } from '../theme';\nimport { DISABLED_OPACITY } from './tokens';\n\nconst HTML_TYPES = {\n text: { type: 'text', inputMode: 'text' },\n number: { type: 'text', inputMode: 'decimal' },\n email: { type: 'email', inputMode: 'email' },\n phone: { type: 'tel', inputMode: 'tel' },\n password: { type: 'password', inputMode: 'text' },\n} as const;\n\nexport const Input: ReactComponent<typeof InputManifest> = ({\n value,\n placeholder,\n label,\n type = 'text',\n maxLength,\n disabled,\n onChange,\n onSubmit,\n}) => {\n const { colors, radius } = useTheme();\n const [text, setText] = useState(value ?? '');\n const [awaitingEcho, setAwaitingEcho] = useState<string[]>([]);\n const [previousValue, setPreviousValue] = useState(value);\n\n // `value` is page state, which the service updates a moment after each keystroke. By the time\n // it sends back \"a\", the user may have typed \"abc\"; showing \"a\" would erase \"bc\". So a value\n // the user already typed is a late echo and is ignored. A value the user never typed, such as\n // a reset, was set by the page and replaces the text.\n if (value !== previousValue) {\n setPreviousValue(value);\n const echo = awaitingEcho.indexOf(value ?? '');\n if (echo >= 0) {\n setAwaitingEcho(awaitingEcho.slice(echo + 1));\n } else {\n setAwaitingEcho([]);\n setText(value ?? '');\n }\n }\n return (\n <input\n className=\"dot-input\"\n {...HTML_TYPES[type]}\n value={text}\n placeholder={placeholder}\n aria-label={label}\n maxLength={maxLength}\n disabled={disabled}\n onChange={(event) => {\n const next = event.currentTarget.value;\n setText(next);\n if (onChange && value !== undefined) {\n setAwaitingEcho([...awaitingEcho, next]);\n }\n onChange?.(createEvent('change', { value: next }));\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && onSubmit) {\n onSubmit(createEvent('submit', { value: text }));\n }\n }}\n style={{\n width: '100%',\n boxSizing: 'border-box',\n padding: '12px 14px',\n border: `1px solid ${colors.border}`,\n borderRadius: radius,\n background: colors.surface,\n color: colors.text,\n outlineColor: colors.primary,\n font: 'inherit',\n // At least 16px, or iOS zooms into the page when the field is focused.\n fontSize: 16,\n opacity: disabled ? DISABLED_OPACITY : 1,\n }}\n />\n );\n};\n","import type { Text as TextManifest } from '@monimesl/dot-core';\n\nimport type { ReactComponent } from '../types';\nimport { FONT_SIZE } from './tokens';\n\nconst VARIANTS = {\n body: { fontSize: FONT_SIZE.body },\n caption: { fontSize: FONT_SIZE.caption },\n title: { fontSize: FONT_SIZE.title, fontWeight: 600 },\n} as const;\n\nexport const Text: ReactComponent<typeof TextManifest> = ({ variant = 'body', children }) => (\n <span className=\"dot-text\" style={VARIANTS[variant]}>\n {children}\n </span>\n);\n","import type { View as ViewManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\n\nimport type { ReactComponent } from '../types';\nimport { useTheme } from '../theme';\nimport { CARD_RADIUS_SCALE, GAP, PADDING } from './tokens';\n\nconst ALIGN = {\n stretch: 'stretch',\n start: 'flex-start',\n center: 'center',\n end: 'flex-end',\n} as const;\n\nexport const View: ReactComponent<typeof ViewManifest> = ({\n direction = 'column',\n gap = 'medium',\n align = 'stretch',\n variant = 'plain',\n onTap,\n children,\n}) => {\n const { colors, radius } = useTheme();\n const card = variant === 'card';\n const handleClick = onTap ? () => onTap(createEvent('tap')) : undefined;\n return (\n <div\n className=\"dot-view\"\n onClick={handleClick}\n style={{\n display: 'flex',\n flexDirection: direction,\n gap: GAP[gap],\n alignItems: ALIGN[align],\n padding: card ? PADDING : undefined,\n borderRadius: card ? radius * CARD_RADIUS_SCALE : undefined,\n background: card ? colors.surface : undefined,\n border: card ? `1px solid ${colors.border}` : undefined,\n cursor: onTap ? 'pointer' : undefined,\n }}\n >\n {children}\n </div>\n );\n};\n","import type { BuiltinReactComponents } from '../types';\nimport { Button } from './button';\nimport { Image } from './image';\nimport { Input } from './input';\nimport { Text } from './text';\nimport { View } from './view';\n\nexport const builtins: BuiltinReactComponents = { Button, Image, Input, Text, View };\n","import type { ComponentType, ReactNode } from 'react';\nimport { createElement, Fragment, useMemo, useSyncExternalStore } from 'react';\nimport type { RenderContext } from '@monimesl/dot-core';\nimport { toList, toText } from '@monimesl/dot-core';\nimport type { PageController } from '@monimesl/dot-webview';\n\nexport type ComponentMap = Readonly<Record<string, ComponentType<Record<string, unknown>>>>;\n\ninterface PageRootProps {\n page: PageController;\n components: ComponentMap;\n}\n\nexport function PageRoot({ page, components }: PageRootProps) {\n const state = useSyncExternalStore(page.subscribe, page.getState);\n const context = useMemo<RenderContext<ReactNode>>(\n () => ({\n h(type, props, ...children) {\n const component = components[type];\n if (!component) {\n throw new Error(`The renderer has no component registered for tag '<${type}>'`);\n }\n return createElement(component, props, ...children);\n },\n text: toText,\n on: (handler) => page.on(handler),\n each: (items, render, key) =>\n createElement(\n Fragment,\n null,\n toList(items).map((item, index) =>\n createElement(\n Fragment,\n { key: key ? String(key(item, index)) : index },\n ...render(item, index),\n ),\n ),\n ),\n }),\n [page, components],\n );\n if (!state) {\n return null;\n }\n return createElement(Fragment, null, ...page.viewRenderer(state, context));\n}\n","import type { Theme } from '@monimesl/dot-core';\nimport type { ComponentType, ReactNode } from 'react';\nimport { useMemo, useSyncExternalStore } from 'react';\nimport type { DotContext, PageController } from '@monimesl/dot-webview';\n\nimport type { ComponentMap } from './page-root';\nimport { PageRoot } from './page-root';\nimport { PADDING } from './components/tokens';\nimport { FONT_FAMILY, resolveTheme, ThemeContext, useTheme } from './theme';\n\nexport type Wrapper = ComponentType<{ theme: Theme; children: ReactNode }>;\n\ninterface RootProps {\n page: PageController;\n dotContext: DotContext;\n components: ComponentMap;\n wrapper: Wrapper | undefined;\n}\n\nexport function Root({ page, dotContext, components, wrapper: Wrapper }: RootProps) {\n const theme = useSyncExternalStore(dotContext.theme.subscribe, dotContext.theme.get);\n const systemContext = useSyncExternalStore(\n dotContext.systemContext.subscribe,\n dotContext.systemContext.get,\n );\n const resolved = useMemo(\n () => resolveTheme(theme, systemContext.scheme),\n [theme, systemContext.scheme],\n );\n const content = <PageRoot page={page} components={components} />;\n\n return (\n <ThemeContext.Provider value={resolved}>\n {Wrapper ? (\n <Wrapper theme={{ ...theme, scheme: resolved.scheme }}>{content}</Wrapper>\n ) : (\n <DefaultSurface>{content}</DefaultSurface>\n )}\n </ThemeContext.Provider>\n );\n}\n\nfunction DefaultSurface({ children }: { children: ReactNode }) {\n const { colors } = useTheme();\n return (\n <div\n className=\"dot-surface\"\n style={{\n minHeight: '100vh',\n boxSizing: 'border-box',\n padding: PADDING,\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n background: colors.background,\n color: colors.text,\n fontFamily: FONT_FAMILY,\n }}\n >\n {children}\n </div>\n );\n}\n","import type { Renderer } from '@monimesl/dot-webview';\nimport type { JSXElementConstructor } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport { builtins } from './components';\nimport type { ComponentMap } from './page-root';\nimport type { Wrapper } from './root';\nimport { Root } from './root';\nimport type { BuiltinReactComponents } from './types';\n\nexport interface ReactRendererOptions {\n components?: Partial<BuiltinReactComponents> &\n Readonly<Record<string, JSXElementConstructor<never>>>;\n wrapper?: Wrapper;\n}\n\nexport function reactRenderer({ components = {}, wrapper }: ReactRendererOptions = {}): Renderer {\n const registry = { ...builtins, ...components } as unknown as ComponentMap;\n\n return {\n name: 'react',\n mount(container, page, dotContext) {\n const root = createRoot(container);\n root.render(\n <Root page={page} dotContext={dotContext} components={registry} wrapper={wrapper} />,\n );\n return () => root.unmount();\n },\n };\n}\n","export type { Wrapper } from './root';\nexport { builtins } from './components';\nimport { reactRenderer } from './renderer';\n\nexport type { ReactRendererOptions } from './renderer';\n\nexport { resolveTheme, useTheme } from './theme';\nexport type { ResolvedColors, ResolvedTheme } from './theme';\n\nexport type { BuiltinReactComponents, ReactComponent, ReactComponents } from './types';\n\nexport default reactRenderer;\n"],"mappings":";;;;;AAmBA,MAAa,cAAc;AAE3B,MAAM,iBAAiB;AAGvB,MAAM,iBAAsD;CAC1D,OAAO;EACL,SAAS;EACT,YAAY;EACZ,SAAS;EACT,MAAM;EACN,QAAQ;EACR,OAAO;EACP,QAAQ;CACV;CACA,MAAM;EACJ,SAAS;EACT,YAAY;EACZ,SAAS;EACT,MAAM;EACN,QAAQ;EACR,OAAO;EACP,QAAQ;CACV;AACF;AAEA,SAAgB,aAAa,OAAc,cAA0C;CACnF,MAAM,SAAS,CAAC,MAAM,UAAU,MAAM,WAAW,WAAW,eAAe,MAAM;CACjF,MAAM,WAAW,eAAe;CAChC,MAAM,SAAS,MAAM,UAAU,CAAC;CAChC,MAAM,QAAQ,OAAgC,aAAqB,QAAQ,WAAW;CACtF,OAAO;EACL;EACA,QAAQ;GACN,SAAS,KAAK,OAAO,SAAS,SAAS,OAAO;GAC9C,YAAY,KAAK,OAAO,YAAY,SAAS,UAAU;GACvD,SAAS,KAAK,OAAO,SAAS,SAAS,OAAO;GAC9C,MAAM,KAAK,OAAO,MAAM,SAAS,IAAI;GACrC,QAAQ,SAAS;GACjB,OAAO,SAAS;GAChB,QAAQ,SAAS;EACnB;EACA,QAAQ,MAAM,UAAU;CAC1B;AACF;AAEA,MAAa,eAAe,cAA6B,aAAa,CAAC,GAAG,OAAO,CAAC;AAElF,SAAgB,WAA0B;CACxC,OAAO,WAAW,YAAY;AAChC;;;ACrEA,MAAa,MAAM;CAAE,MAAM;CAAG,OAAO;CAAG,QAAQ;CAAG,OAAO;AAAG;AAE7D,MAAa,YAAY;CAAE,SAAS;CAAI,MAAM;CAAI,OAAO;AAAG;AAM5D,MAAa,oBAAoB;AAEjC,MAAa,mBAAmB;;;ACHhC,MAAa,UAAiD,EAC5D,UAAU,WACV,UACA,SACA,eACI;CACJ,MAAM,EAAE,QAAQ,WAAW,SAAS;CACpC,MAAM,SAAS,YAAY,aAAa,CAAC;CACzC,IAAI,QAAQ,OAAO;CACnB,IAAI,QACF,QAAQ,OAAO;MACV,IAAI,UACT,QAAQ,OAAO;CAGjB,OACE,oBAAC,UAAD;EACE,MAAK;EACL,WAAU;EACV,gBAAc;EACJ;EACV,SAPgB,gBAAgB,QAAQ,YAAY,OAAO,CAAC,IAAI,KAAA;EAQhE,OAAO;GACL,SAAS;GACT,QAAQ;GACR,cAAc;GACd,YAAY,SAAS,OAAO,UAAU,OAAO;GAC7C;GACA,MAAM;GACN,UAAU,UAAU;GACpB,YAAY;GACZ,SAAS,WAAW,mBAAmB;GACvC,QAAQ,WAAW,YAAY;EACjC;EAEC;CACK,CAAA;AAEZ;;;ACtCA,MAAa,SAA+C,EAC1D,KACA,KACA,OACA,QACA,QACA,cACI;CACJ,MAAM,EAAE,WAAW,SAAS;CAU5B,OACE,oBAAC,OAAD;EACE,WAAU;EACL;EACL,KAAK,OAAO;EACL;EACC;EACR,OAAO,EAAE,cAAc,OAAO;EAC9B,QAjBe,UACd,UAA4C;GAC3C,MAAM,EAAE,cAAc,kBAAkB,MAAM;GAC9C,OAAO,YAAY,QAAQ;IAAE,OAAO;IAAc,QAAQ;GAAc,CAAC,CAAC;EAC5E,IACA,KAAA;EAaA,SAZgB,gBACV,QAAQ,YAAY,SAAS,EAAE,SAAS,kBAAkB,MAAM,CAAC,CAAC,IACxE,KAAA;CAWD,CAAA;AAEL;;;AC7BA,MAAM,aAAa;CACjB,MAAM;EAAE,MAAM;EAAQ,WAAW;CAAO;CACxC,QAAQ;EAAE,MAAM;EAAQ,WAAW;CAAU;CAC7C,OAAO;EAAE,MAAM;EAAS,WAAW;CAAQ;CAC3C,OAAO;EAAE,MAAM;EAAO,WAAW;CAAM;CACvC,UAAU;EAAE,MAAM;EAAY,WAAW;CAAO;AAClD;AAEA,MAAa,SAA+C,EAC1D,OACA,aACA,OACA,OAAO,QACP,WACA,UACA,UACA,eACI;CACJ,MAAM,EAAE,QAAQ,WAAW,SAAS;CACpC,MAAM,CAAC,MAAM,WAAW,SAAS,SAAS,EAAE;CAC5C,MAAM,CAAC,cAAc,mBAAmB,SAAmB,CAAC,CAAC;CAC7D,MAAM,CAAC,eAAe,oBAAoB,SAAS,KAAK;CAMxD,IAAI,UAAU,eAAe;EAC3B,iBAAiB,KAAK;EACtB,MAAM,OAAO,aAAa,QAAQ,SAAS,EAAE;EAC7C,IAAI,QAAQ,GACV,gBAAgB,aAAa,MAAM,OAAO,CAAC,CAAC;OACvC;GACL,gBAAgB,CAAC,CAAC;GAClB,QAAQ,SAAS,EAAE;EACrB;CACF;CACA,OACE,oBAAC,SAAD;EACE,WAAU;EACV,GAAI,WAAW;EACf,OAAO;EACM;EACb,cAAY;EACD;EACD;EACV,WAAW,UAAU;GACnB,MAAM,OAAO,MAAM,cAAc;GACjC,QAAQ,IAAI;GACZ,IAAI,YAAY,UAAU,KAAA,GACxB,gBAAgB,CAAC,GAAG,cAAc,IAAI,CAAC;GAEzC,WAAW,YAAY,UAAU,EAAE,OAAO,KAAK,CAAC,CAAC;EACnD;EACA,YAAY,UAAU;GACpB,IAAI,MAAM,QAAQ,WAAW,UAC3B,SAAS,YAAY,UAAU,EAAE,OAAO,KAAK,CAAC,CAAC;EAEnD;EACA,OAAO;GACL,OAAO;GACP,WAAW;GACX,SAAS;GACT,QAAQ,aAAa,OAAO;GAC5B,cAAc;GACd,YAAY,OAAO;GACnB,OAAO,OAAO;GACd,cAAc,OAAO;GACrB,MAAM;GAEN,UAAU;GACV,SAAS,WAAW,mBAAmB;EACzC;CACD,CAAA;AAEL;;;AC9EA,MAAM,WAAW;CACf,MAAM,EAAE,UAAU,UAAU,KAAK;CACjC,SAAS,EAAE,UAAU,UAAU,QAAQ;CACvC,OAAO;EAAE,UAAU,UAAU;EAAO,YAAY;CAAI;AACtD;AAEA,MAAa,QAA6C,EAAE,UAAU,QAAQ,eAC5E,oBAAC,QAAD;CAAM,WAAU;CAAW,OAAO,SAAS;CACxC;AACG,CAAA;;;ACPR,MAAM,QAAQ;CACZ,SAAS;CACT,OAAO;CACP,QAAQ;CACR,KAAK;AACP;AAEA,MAAa,QAA6C,EACxD,YAAY,UACZ,MAAM,UACN,QAAQ,WACR,UAAU,SACV,OACA,eACI;CACJ,MAAM,EAAE,QAAQ,WAAW,SAAS;CACpC,MAAM,OAAO,YAAY;CAEzB,OACE,oBAAC,OAAD;EACE,WAAU;EACV,SAJgB,cAAc,MAAM,YAAY,KAAK,CAAC,IAAI,KAAA;EAK1D,OAAO;GACL,SAAS;GACT,eAAe;GACf,KAAK,IAAI;GACT,YAAY,MAAM;GAClB,SAAS,OAAA,KAAiB,KAAA;GAC1B,cAAc,OAAO,SAAS,oBAAoB,KAAA;GAClD,YAAY,OAAO,OAAO,UAAU,KAAA;GACpC,QAAQ,OAAO,aAAa,OAAO,WAAW,KAAA;GAC9C,QAAQ,QAAQ,YAAY,KAAA;EAC9B;EAEC;CACE,CAAA;AAET;;;ACrCA,MAAa,WAAmC;CAAE;CAAQ;CAAO;CAAO;CAAM;AAAK;;;ACMnF,SAAgB,SAAS,EAAE,MAAM,cAA6B;CAC5D,MAAM,QAAQ,qBAAqB,KAAK,WAAW,KAAK,QAAQ;CAChE,MAAM,UAAU,eACP;EACL,EAAE,MAAM,OAAO,GAAG,UAAU;GAC1B,MAAM,YAAY,WAAW;GAC7B,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,sDAAsD,KAAK,GAAG;GAEhF,OAAO,cAAc,WAAW,OAAO,GAAG,QAAQ;EACpD;EACA,MAAM;EACN,KAAK,YAAY,KAAK,GAAG,OAAO;EAChC,OAAO,OAAO,QAAQ,QACpB,cACE,UACA,MACA,OAAO,KAAK,CAAC,CAAC,KAAK,MAAM,UACvB,cACE,UACA,EAAE,KAAK,MAAM,OAAO,IAAI,MAAM,KAAK,CAAC,IAAI,MAAM,GAC9C,GAAG,OAAO,MAAM,KAAK,CACvB,CACF,CACF;CACJ,IACA,CAAC,MAAM,UAAU,CACnB;CACA,IAAI,CAAC,OACH,OAAO;CAET,OAAO,cAAc,UAAU,MAAM,GAAG,KAAK,aAAa,OAAO,OAAO,CAAC;AAC3E;;;AC1BA,SAAgB,KAAK,EAAE,MAAM,YAAY,YAAY,SAAS,WAAsB;CAClF,MAAM,QAAQ,qBAAqB,WAAW,MAAM,WAAW,WAAW,MAAM,GAAG;CACnF,MAAM,gBAAgB,qBACpB,WAAW,cAAc,WACzB,WAAW,cAAc,GAC3B;CACA,MAAM,WAAW,cACT,aAAa,OAAO,cAAc,MAAM,GAC9C,CAAC,OAAO,cAAc,MAAM,CAC9B;CACA,MAAM,UAAU,oBAAC,UAAD;EAAgB;EAAkB;CAAa,CAAA;CAE/D,OACE,oBAAC,aAAa,UAAd;EAAuB,OAAO;EAC3B,UAAA,UACC,oBAAC,SAAD;GAAS,OAAO;IAAE,GAAG;IAAO,QAAQ,SAAS;GAAO;GAAI,UAAA;EAAiB,CAAA,IAEzE,oBAAC,gBAAD,EAAA,UAAiB,QAAwB,CAAA;CAEtB,CAAA;AAE3B;AAEA,SAAS,eAAe,EAAE,YAAqC;CAC7D,MAAM,EAAE,WAAW,SAAS;CAC5B,OACE,oBAAC,OAAD;EACE,WAAU;EACV,OAAO;GACL,WAAW;GACX,WAAW;GACX,SAAA;GACA,SAAS;GACT,eAAe;GACf,KAAK;GACL,YAAY,OAAO;GACnB,OAAO,OAAO;GACd,YAAY;EACd;EAEC;CACE,CAAA;AAET;;;AC9CA,SAAgB,cAAc,EAAE,aAAa,CAAC,GAAG,YAAkC,CAAC,GAAa;CAC/F,MAAM,WAAW;EAAE,GAAG;EAAU,GAAG;CAAW;CAE9C,OAAO;EACL,MAAM;EACN,MAAM,WAAW,MAAM,YAAY;GACjC,MAAM,OAAO,WAAW,SAAS;GACjC,KAAK,OACH,oBAAC,MAAD;IAAY;IAAkB;IAAY,YAAY;IAAmB;GAAU,CAAA,CACrF;GACA,aAAa,KAAK,QAAQ;EAC5B;CACF;AACF;;;AClBA,IAAA,cAAe"}
1
+ {"version":3,"file":"index.js","names":["Image","List"],"sources":["../src/theme.ts","../src/components/tokens.ts","../src/components/spinner.tsx","../src/components/button.tsx","../src/components/divider.tsx","../src/components/tones.ts","../src/components/icon.tsx","../src/components/feedback.tsx","../src/components/footer.tsx","../src/components/image.tsx","../src/components/field.tsx","../src/components/field-box.ts","../src/components/typed-text.ts","../src/components/input.tsx","../src/components/list.tsx","../src/components/animate.ts","../src/components/sheet.tsx","../src/components/select.tsx","../src/components/skeleton.tsx","../src/components/text.tsx","../src/components/text-area.tsx","../src/components/toast.tsx","../src/components/toggles.tsx","../src/components/view.tsx","../src/components/index.ts","../src/page-root.tsx","../src/root.tsx","../src/renderer.tsx","../src/index.ts"],"sourcesContent":["import type { ColorScheme, SchemeColor, Theme } from '@monimesl/dot-core';\nimport { createContext, useContext } from 'react';\n\nexport interface ResolvedColors {\n primary: string;\n background: string;\n surface: string;\n text: string;\n subtle: string;\n muted: string;\n border: string;\n info: string;\n success: string;\n warning: string;\n danger: string;\n}\n\nexport interface ResolvedTheme {\n scheme: ColorScheme;\n colors: ResolvedColors;\n radius: number;\n}\n\nexport const FONT_FAMILY = 'system-ui, sans-serif';\n\nconst DEFAULT_RADIUS = 12;\n\n// Dash's own look: black, white and grays, so a dot feels at home in it.\nconst DEFAULT_COLORS: Record<ColorScheme, ResolvedColors> = {\n light: {\n primary: '#1c1c1e',\n background: '#f2f2f2',\n surface: '#ffffff',\n text: '#111111',\n subtle: '#8e8e93',\n muted: '#e9e9eb',\n border: '#e9e9eb',\n info: '#0a64d6',\n success: '#1a8a4a',\n warning: '#b25e00',\n danger: '#d0312d',\n },\n dark: {\n primary: '#f5f5f5',\n background: '#121212',\n surface: '#1e1e1e',\n text: '#f5f5f5',\n subtle: '#8e8e93',\n muted: '#2c2c2e',\n border: '#2a2a2c',\n info: '#4c9dff',\n success: '#3ecf72',\n warning: '#ffb340',\n danger: '#ff6961',\n },\n};\n\nexport function resolveTheme(theme: Theme, systemScheme: ColorScheme): ResolvedTheme {\n const scheme = !theme.scheme || theme.scheme === 'system' ? systemScheme : theme.scheme;\n const defaults = DEFAULT_COLORS[scheme];\n const colors = theme.colors ?? {};\n const pick = (color: SchemeColor | undefined, fallback: string) => color?.[scheme] ?? fallback;\n return {\n scheme,\n colors: {\n primary: pick(colors.primary, defaults.primary),\n background: pick(colors.background, defaults.background),\n surface: pick(colors.surface, defaults.surface),\n text: pick(colors.text, defaults.text),\n subtle: defaults.subtle,\n muted: defaults.muted,\n border: defaults.border,\n info: defaults.info,\n success: defaults.success,\n warning: defaults.warning,\n danger: defaults.danger,\n },\n radius: theme.radius ?? DEFAULT_RADIUS,\n };\n}\n\nexport const ThemeContext = createContext<ResolvedTheme>(resolveTheme({}, 'light'));\n\nexport function useTheme(): ResolvedTheme {\n return useContext(ThemeContext);\n}\n","export const SPACE = { none: 0, small: 4, medium: 8, large: 16 } as const;\n\nexport const FONT_SIZE = { caption: 13, body: 15, title: 20 } as const;\n\n// Cards round a little more than the controls inside them.\nexport const CARD_RADIUS_SCALE = 1.5;\n\nexport const DISABLED_OPACITY = 0.6;\n\nexport const ICON_SIZE = { small: 16, medium: 20, large: 28 } as const;\n\n// At least 16px, or iOS zooms into the page when a field is focused.\nexport const FIELD_FONT_SIZE = 16;\n","import type { Spinner as SpinnerManifest } from '@monimesl/dot-core';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { ICON_SIZE } from './tokens';\n\n// A quarter arc turning over a faint full circle, in the current text color.\nexport function LoadingIcon({ size }: { size: number }) {\n return (\n <svg\n className=\"dot-spinner\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={3}\n role=\"progressbar\"\n aria-label=\"Loading\"\n style={{ flexShrink: 0 }}\n >\n <circle cx=\"12\" cy=\"12\" r=\"9\" strokeOpacity={0.25} />\n <path d=\"M21 12a9 9 0 0 0-9-9\" strokeLinecap=\"round\">\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"0.8s\"\n repeatCount=\"indefinite\"\n />\n </path>\n </svg>\n );\n}\n\nexport const Spinner: ReactComponent<typeof SpinnerManifest> = ({ size = 'medium' }) => {\n const { colors } = useTheme();\n return (\n <span style={{ display: 'inline-flex', alignSelf: 'center', color: colors.subtle }}>\n <LoadingIcon size={ICON_SIZE[size]} />\n </span>\n );\n};\n","import type { Button as ButtonManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\n\nimport type { ReactComponent } from '../types';\nimport { useTheme } from '../theme';\nimport { LoadingIcon } from './spinner';\nimport { DISABLED_OPACITY, FONT_SIZE, ICON_SIZE, SPACE } from './tokens';\n\nexport const Button: ReactComponent<typeof ButtonManifest> = ({\n variant = 'primary',\n disabled,\n loading,\n onClick,\n children,\n}) => {\n const { colors, radius } = useTheme();\n const filled = variant === 'primary' && !disabled;\n let color = colors.text;\n if (filled) {\n color = colors.surface;\n } else if (disabled) {\n color = colors.subtle;\n }\n const handleClick = onClick && !loading ? () => onClick(createEvent('click')) : undefined;\n return (\n <button\n type=\"button\"\n className=\"dot-button\"\n data-variant={variant}\n disabled={disabled}\n aria-busy={loading}\n onClick={handleClick}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: SPACE.medium,\n minHeight: 48,\n padding: '12px 20px',\n border: 'none',\n borderRadius: radius,\n background: filled ? colors.primary : colors.muted,\n color,\n font: 'inherit',\n fontSize: FONT_SIZE.body,\n fontWeight: 600,\n opacity: disabled ? DISABLED_OPACITY : 1,\n cursor: disabled || loading ? 'default' : 'pointer',\n }}\n >\n {loading ? <LoadingIcon size={ICON_SIZE.small} /> : null}\n {children}\n </button>\n );\n};\n","import type { Divider as DividerManifest } from '@monimesl/dot-core';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\n\nexport const Divider: ReactComponent<typeof DividerManifest> = () => {\n const { colors } = useTheme();\n return (\n <div\n className=\"dot-divider\"\n role=\"separator\"\n style={{ height: 1, alignSelf: 'stretch', flexShrink: 0, background: colors.border }}\n />\n );\n};\n","import type { IconName, STATUS_TONES, TONES } from '@monimesl/dot-core';\n\nimport type { ResolvedColors } from '../theme';\n\nexport type Tone = (typeof TONES)[number];\n\nexport const STATUS_ICONS: Record<(typeof STATUS_TONES)[number], IconName> = {\n default: 'info',\n info: 'info',\n success: 'success',\n warning: 'warning',\n danger: 'error',\n};\n\nexport function toneColor(colors: ResolvedColors, tone: Tone): string {\n switch (tone) {\n case 'default':\n return colors.text;\n case 'muted':\n return colors.subtle;\n default:\n return colors[tone];\n }\n}\n\nexport function toneBackground(colors: ResolvedColors, tone: Tone): string {\n if (tone === 'default' || tone === 'muted') {\n return colors.muted;\n }\n return withOpacity(colors[tone], 0.14);\n}\n\n// Appends an alpha channel to a #rrggbb color.\nfunction withOpacity(color: string, opacity: number): string {\n const alpha = Math.round(opacity * 255)\n .toString(16)\n .padStart(2, '0');\n return `${color}${alpha}`;\n}\n","import type { IconName, Icon as IconManifest } from '@monimesl/dot-core';\nimport type { IconNode } from 'lucide';\nimport {\n ArrowDown,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n Banknote,\n Bell,\n Calendar,\n Check,\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n ChevronUp,\n CircleAlert,\n CircleCheck,\n CircleHelp,\n Clock,\n Copy,\n CreditCard,\n Download,\n Droplet,\n Ellipsis,\n Eye,\n EyeOff,\n File,\n Gift,\n Heart,\n History,\n House,\n Image,\n Info,\n Landmark,\n LayoutGrid,\n List,\n Lock,\n LogOut,\n Mail,\n MapPin,\n Minus,\n Pencil,\n Phone,\n Plus,\n QrCode,\n Receipt,\n RefreshCw,\n Search,\n Send,\n Settings,\n Share2,\n ShoppingCart,\n Smartphone,\n Star,\n Trash2,\n TriangleAlert,\n Upload,\n User,\n Users,\n Wallet,\n Wifi,\n X,\n Zap,\n} from 'lucide';\nimport { createElement } from 'react';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { ICON_SIZE } from './tokens';\nimport { toneColor } from './tones';\n\n// Drawn by Lucide (lucide.dev, ISC license).\nconst ICONS: Record<IconName, IconNode> = {\n 'arrow-down': ArrowDown,\n 'arrow-left': ArrowLeft,\n 'arrow-right': ArrowRight,\n 'arrow-up': ArrowUp,\n bank: Landmark,\n bell: Bell,\n bolt: Zap,\n calendar: Calendar,\n card: CreditCard,\n cart: ShoppingCart,\n cash: Banknote,\n check: Check,\n 'chevron-down': ChevronDown,\n 'chevron-left': ChevronLeft,\n 'chevron-right': ChevronRight,\n 'chevron-up': ChevronUp,\n clock: Clock,\n close: X,\n copy: Copy,\n download: Download,\n edit: Pencil,\n error: CircleAlert,\n eye: Eye,\n 'eye-off': EyeOff,\n file: File,\n gift: Gift,\n grid: LayoutGrid,\n heart: Heart,\n help: CircleHelp,\n history: History,\n home: House,\n image: Image,\n info: Info,\n list: List,\n location: MapPin,\n lock: Lock,\n logout: LogOut,\n mail: Mail,\n minus: Minus,\n mobile: Smartphone,\n more: Ellipsis,\n phone: Phone,\n plus: Plus,\n 'qr-code': QrCode,\n receipt: Receipt,\n refresh: RefreshCw,\n search: Search,\n send: Send,\n settings: Settings,\n share: Share2,\n star: Star,\n success: CircleCheck,\n trash: Trash2,\n upload: Upload,\n user: User,\n users: Users,\n wallet: Wallet,\n warning: TriangleAlert,\n water: Droplet,\n wifi: Wifi,\n};\n\ninterface IconGraphicProps {\n name: IconName;\n size: number;\n color: string;\n}\n\nexport function IconGraphic({ name, size, color }: IconGraphicProps) {\n return (\n <svg\n className=\"dot-icon\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ display: 'inline-block', verticalAlign: 'middle', flexShrink: 0 }}\n >\n {ICONS[name].map(([tag, attributes], index) =>\n createElement(tag, { key: index, ...attributes }),\n )}\n </svg>\n );\n}\n\nexport const Icon: ReactComponent<typeof IconManifest> = ({\n name,\n size = 'medium',\n tone = 'default',\n}) => {\n const { colors } = useTheme();\n if (!name) {\n return null;\n }\n return <IconGraphic name={name} size={ICON_SIZE[size]} color={toneColor(colors, tone)} />;\n};\n","import type {\n Badge as BadgeManifest,\n Notice as NoticeManifest,\n ProgressBar as ProgressBarManifest,\n} from '@monimesl/dot-core';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { IconGraphic } from './icon';\nimport { FONT_SIZE, ICON_SIZE, SPACE } from './tokens';\nimport { STATUS_ICONS, toneBackground, toneColor } from './tones';\n\nexport const ProgressBar: ReactComponent<typeof ProgressBarManifest> = ({ value = 0 }) => {\n const { colors } = useTheme();\n const percent = Math.min(100, Math.max(0, value));\n return (\n <div\n className=\"dot-progress-bar\"\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={percent}\n style={{ height: 6, borderRadius: 3, background: colors.muted, overflow: 'hidden' }}\n >\n <div\n style={{\n width: `${percent}%`,\n height: '100%',\n background: colors.primary,\n transition: 'width 0.2s',\n }}\n />\n </div>\n );\n};\n\nexport const Notice: ReactComponent<typeof NoticeManifest> = ({\n tone = 'default',\n title,\n children,\n}) => {\n const { colors, radius } = useTheme();\n return (\n <div\n className=\"dot-notice\"\n role={tone === 'danger' ? 'alert' : 'status'}\n style={{\n display: 'flex',\n gap: SPACE.medium,\n padding: '12px 14px',\n borderRadius: radius,\n background: toneBackground(colors, tone),\n color: colors.text,\n fontSize: FONT_SIZE.body,\n }}\n >\n <IconGraphic\n name={STATUS_ICONS[tone]}\n size={ICON_SIZE.medium}\n color={toneColor(colors, tone)}\n />\n <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n {title ? <span style={{ fontWeight: 600 }}>{title}</span> : null}\n {children ? <span>{children}</span> : null}\n </div>\n </div>\n );\n};\n\nexport const Badge: ReactComponent<typeof BadgeManifest> = ({ tone = 'default', children }) => {\n const { colors } = useTheme();\n return (\n <span\n className=\"dot-badge\"\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n // Keeps its own width in a column, which would otherwise stretch it.\n width: 'fit-content',\n padding: '2px 8px',\n borderRadius: 999,\n background: toneBackground(colors, tone),\n color: toneColor(colors, tone),\n fontSize: FONT_SIZE.caption,\n fontWeight: 600,\n whiteSpace: 'nowrap',\n }}\n >\n {children}\n </span>\n );\n};\n","import type { Footer as FooterManifest } from '@monimesl/dot-core';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { SPACE } from './tokens';\n\nexport const Footer: ReactComponent<typeof FooterManifest> = ({ children }) => {\n const { colors } = useTheme();\n return (\n <div\n className=\"dot-footer\"\n style={{\n position: 'sticky',\n bottom: 0,\n // Sits at the bottom of a short page too.\n marginTop: 'auto',\n display: 'flex',\n flexDirection: 'column',\n gap: SPACE.medium,\n paddingTop: SPACE.medium,\n paddingBottom: SPACE.medium,\n background: colors.background,\n }}\n >\n {children}\n </div>\n );\n};\n","import type { Image as ImageManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\nimport type { SyntheticEvent } from 'react';\n\nimport type { ReactComponent } from '../types';\nimport { useTheme } from '../theme';\n\nexport const Image: ReactComponent<typeof ImageManifest> = ({\n src,\n alt,\n width,\n height,\n fit = 'cover',\n shape = 'rounded',\n onLoad,\n onError,\n}) => {\n const { radius } = useTheme();\n const corners = { rounded: radius, square: 0, circle: '50%' }[shape];\n const handleLoad = onLoad\n ? (event: SyntheticEvent<HTMLImageElement>) => {\n const { naturalWidth, naturalHeight } = event.currentTarget;\n onLoad(createEvent('load', { width: naturalWidth, height: naturalHeight }));\n }\n : undefined;\n const handleError = onError\n ? () => onError(createEvent('error', { message: `Failed to load ${src}` }))\n : undefined;\n return (\n <img\n className=\"dot-image\"\n src={src}\n alt={alt ?? ''}\n width={width}\n height={height}\n style={{ borderRadius: corners, objectFit: fit }}\n onLoad={handleLoad}\n onError={handleError}\n />\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { useTheme } from '../theme';\nimport { FONT_SIZE, SPACE } from './tokens';\n\ninterface FieldProps {\n label: string | undefined;\n hint: string | undefined;\n error: string | undefined;\n children: ReactNode;\n}\n\nexport function Field({ label, hint, error, children }: FieldProps) {\n const { colors } = useTheme();\n const note = error || hint;\n return (\n <label\n className=\"dot-field\"\n style={{ display: 'flex', flexDirection: 'column', gap: SPACE.small }}\n >\n {label ? <FieldLabel>{label}</FieldLabel> : null}\n {children}\n {note ? (\n <span style={{ fontSize: FONT_SIZE.caption, color: error ? colors.danger : colors.subtle }}>\n {note}\n </span>\n ) : null}\n </label>\n );\n}\n\nexport function FieldLabel({ children }: { children: ReactNode }) {\n return <span style={{ fontSize: FONT_SIZE.caption, fontWeight: 500 }}>{children}</span>;\n}\n","import type { CSSProperties } from 'react';\nimport { useState } from 'react';\n\nimport { useTheme } from '../theme';\nimport { DISABLED_OPACITY, FIELD_FONT_SIZE } from './tokens';\n\nexport function useFieldBox(error: string | undefined, disabled: boolean | undefined) {\n const { colors, radius } = useTheme();\n const [focused, setFocused] = useState(false);\n let borderColor = colors.border;\n if (error) {\n borderColor = colors.danger;\n } else if (focused) {\n borderColor = colors.primary;\n }\n const style: CSSProperties = {\n border: `1px solid ${borderColor}`,\n borderRadius: radius,\n background: colors.surface,\n color: colors.text,\n fontSize: FIELD_FONT_SIZE,\n opacity: disabled ? DISABLED_OPACITY : 1,\n };\n return { style, onFocus: () => setFocused(true), onBlur: () => setFocused(false) };\n}\n","import { useState } from 'react';\n\n// `value` is page state, which the service updates a moment after each keystroke. By the time\n// it sends back \"a\", the user may have typed \"abc\"; showing \"a\" would erase \"bc\". So a value\n// the user already typed is a late echo and is ignored. A value the user never typed, such as\n// a reset, was set by the page and replaces the text.\nexport function useTypedText(\n value: string | undefined,\n sendsChanges: boolean,\n): [text: string, type: (next: string) => void] {\n const [text, setText] = useState(value ?? '');\n const [awaitingEcho, setAwaitingEcho] = useState<string[]>([]);\n const [previousValue, setPreviousValue] = useState(value);\n\n if (value !== previousValue) {\n setPreviousValue(value);\n const echo = awaitingEcho.indexOf(value ?? '');\n if (echo >= 0) {\n setAwaitingEcho(awaitingEcho.slice(echo + 1));\n } else {\n setAwaitingEcho([]);\n setText(value ?? '');\n }\n }\n\n const type = (next: string) => {\n setText(next);\n if (sendsChanges && value !== undefined) {\n setAwaitingEcho([...awaitingEcho, next]);\n }\n };\n return [text, type];\n}\n","import type { Input as InputManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { Field } from './field';\nimport { useFieldBox } from './field-box';\nimport { SPACE } from './tokens';\nimport { useTypedText } from './typed-text';\n\nconst HTML_TYPES = {\n text: { type: 'text', inputMode: 'text' },\n number: { type: 'text', inputMode: 'decimal' },\n email: { type: 'email', inputMode: 'email' },\n phone: { type: 'tel', inputMode: 'tel' },\n password: { type: 'password', inputMode: 'text' },\n} as const;\n\nexport const Input: ReactComponent<typeof InputManifest> = ({\n value,\n placeholder,\n label,\n hint,\n error,\n prefix,\n suffix,\n type = 'text',\n maxLength,\n disabled,\n onChange,\n onSubmit,\n}) => {\n const { colors } = useTheme();\n const [text, typeText] = useTypedText(value, onChange !== undefined);\n const box = useFieldBox(error, disabled);\n return (\n <Field label={label} hint={hint} error={error}>\n <span\n className=\"dot-input\"\n style={{\n ...box.style,\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.medium,\n padding: '0 14px',\n }}\n >\n {prefix ? <span style={{ color: colors.subtle }}>{prefix}</span> : null}\n <input\n {...HTML_TYPES[type]}\n value={text}\n placeholder={placeholder}\n maxLength={maxLength}\n disabled={disabled}\n aria-invalid={error ? true : undefined}\n onFocus={box.onFocus}\n onBlur={box.onBlur}\n onChange={(event) => {\n const next = event.currentTarget.value;\n typeText(next);\n onChange?.(createEvent('change', { value: next }));\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && onSubmit) {\n onSubmit(createEvent('submit', { value: text }));\n }\n }}\n style={{\n flexGrow: 1,\n minWidth: 0,\n padding: '12px 0',\n border: 'none',\n outline: 'none',\n background: 'transparent',\n color: 'inherit',\n font: 'inherit',\n }}\n />\n {suffix ? <span style={{ color: colors.subtle }}>{suffix}</span> : null}\n </span>\n </Field>\n );\n};\n","import type { List as ListManifest, ListItem as ListItemManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\nimport type { ReactNode } from 'react';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { IconGraphic } from './icon';\nimport { CARD_RADIUS_SCALE, FONT_SIZE, ICON_SIZE, SPACE } from './tokens';\n\nexport const List: ReactComponent<typeof ListManifest> = ({ children }) => {\n const { colors, radius } = useTheme();\n // Rows are drawn in the surface color, so the 1px gaps between them show as lines.\n return (\n <div\n className=\"dot-list\"\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n overflow: 'hidden',\n borderRadius: radius * CARD_RADIUS_SCALE,\n border: `1px solid ${colors.border}`,\n background: colors.border,\n }}\n >\n {children}\n </div>\n );\n};\n\nexport const ListItem: ReactComponent<typeof ListItemManifest> = ({\n title,\n subtitle,\n value,\n icon,\n image,\n onTap,\n children,\n}) => {\n const { colors, radius } = useTheme();\n let leading: ReactNode = null;\n if (image) {\n leading = (\n <img\n src={image}\n alt=\"\"\n width={40}\n height={40}\n style={{ borderRadius: radius, objectFit: 'cover', flexShrink: 0 }}\n />\n );\n } else if (icon) {\n leading = (\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 36,\n height: 36,\n borderRadius: '50%',\n background: colors.muted,\n flexShrink: 0,\n }}\n >\n <IconGraphic name={icon} size={ICON_SIZE.medium} color={colors.text} />\n </span>\n );\n }\n let trailing: ReactNode = children;\n if (!trailing && value) {\n trailing = <span style={{ color: colors.subtle }}>{value}</span>;\n }\n const handleClick = onTap ? () => onTap(createEvent('tap')) : undefined;\n return (\n <div\n className=\"dot-list-item\"\n role={onTap ? 'button' : undefined}\n onClick={handleClick}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 16px',\n background: colors.surface,\n fontSize: FONT_SIZE.body,\n cursor: onTap ? 'pointer' : undefined,\n }}\n >\n {leading}\n <span style={{ display: 'flex', flexDirection: 'column', flexGrow: 1, minWidth: 0 }}>\n {title ? <span style={{ fontWeight: 500 }}>{title}</span> : null}\n {subtitle ? (\n <span style={{ fontSize: FONT_SIZE.caption, color: colors.subtle }}>{subtitle}</span>\n ) : null}\n </span>\n {trailing ? (\n <span style={{ display: 'flex', alignItems: 'center', gap: SPACE.small, flexShrink: 0 }}>\n {trailing}\n </span>\n ) : null}\n {onTap ? (\n <IconGraphic name=\"chevron-right\" size={ICON_SIZE.small} color={colors.subtle} />\n ) : null}\n </div>\n );\n};\n","// Runs a Web Animation where the browser has them; the DOM that tests run in doesn't.\nexport function animate(\n element: HTMLElement | null,\n keyframes: Keyframe[],\n options: KeyframeAnimationOptions,\n): Animation | undefined {\n if (!element || typeof element.animate !== 'function') {\n return undefined;\n }\n return element.animate(keyframes, options);\n}\n","import type { Sheet as SheetManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\nimport type { ReactNode } from 'react';\nimport { useEffect, useRef } from 'react';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { animate } from './animate';\nimport { CARD_RADIUS_SCALE, FONT_SIZE, SPACE } from './tokens';\n\nconst SLIDE_UP: Keyframe[] = [{ transform: 'translateY(100%)' }, { transform: 'translateY(0)' }];\n\ninterface SheetPanelProps {\n open: boolean;\n title: string | undefined;\n onClose: () => void;\n children: ReactNode;\n}\n\n// The panel and the dimmed page behind it, which Sheet and Select share.\nexport function SheetPanel({ open, title, onClose, children }: SheetPanelProps) {\n const { colors, radius } = useTheme();\n const panel = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (open) {\n animate(panel.current, SLIDE_UP, { duration: 200, easing: 'ease-out' });\n }\n }, [open]);\n if (!open) {\n return null;\n }\n const corner = radius * CARD_RADIUS_SCALE;\n return (\n <div\n className=\"dot-sheet\"\n onClick={onClose}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 100,\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'flex-end',\n background: 'rgba(0, 0, 0, 0.4)',\n }}\n >\n <div\n ref={panel}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n // Taps inside the panel don't close it.\n onClick={(event) => event.stopPropagation()}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: SPACE.medium,\n maxHeight: '85vh',\n overflowY: 'auto',\n padding: `${SPACE.large}px ${SPACE.large}px 24px`,\n borderTopLeftRadius: corner,\n borderTopRightRadius: corner,\n background: colors.surface,\n color: colors.text,\n }}\n >\n {title ? (\n <span style={{ fontSize: FONT_SIZE.body, fontWeight: 600, textAlign: 'center' }}>\n {title}\n </span>\n ) : null}\n {children}\n </div>\n </div>\n );\n}\n\nexport const Sheet: ReactComponent<typeof SheetManifest> = ({\n open = false,\n title,\n onClose,\n children,\n}) => (\n <SheetPanel open={open} title={title} onClose={() => onClose?.(createEvent('close'))}>\n {children}\n </SheetPanel>\n);\n","import type { Option as OptionManifest, Select as SelectManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\nimport { createContext, useContext, useState } from 'react';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { Field } from './field';\nimport { useFieldBox } from './field-box';\nimport { IconGraphic } from './icon';\nimport { SheetPanel } from './sheet';\nimport { FONT_SIZE, ICON_SIZE, SPACE } from './tokens';\n\n// Select shows its options twice: in the field, where only the chosen one shows its label, and in\n// the sheet, where each is a row to choose.\ninterface OptionPlace {\n inField: boolean;\n value: string | undefined;\n choose: ((value: string) => void) | undefined;\n}\n\nconst OptionPlaceContext = createContext<OptionPlace>({\n inField: false,\n value: undefined,\n choose: undefined,\n});\n\nexport const Select: ReactComponent<typeof SelectManifest> = ({\n value,\n label,\n placeholder,\n hint,\n error,\n disabled,\n onChange,\n children,\n}) => {\n const { colors } = useTheme();\n const [open, setOpen] = useState(false);\n const box = useFieldBox(error, disabled);\n const choose = (next: string) => {\n setOpen(false);\n onChange?.(createEvent('change', { value: next }));\n };\n return (\n <>\n <Field label={label} hint={hint} error={error}>\n <button\n type=\"button\"\n className=\"dot-select\"\n disabled={disabled}\n onClick={() => setOpen(true)}\n onFocus={box.onFocus}\n onBlur={box.onBlur}\n style={{\n font: 'inherit',\n ...box.style,\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.medium,\n width: '100%',\n padding: '12px 14px',\n textAlign: 'start',\n cursor: disabled ? 'default' : 'pointer',\n }}\n >\n <span style={{ flexGrow: 1 }}>\n {value ? (\n <OptionPlaceContext.Provider value={{ inField: true, value, choose: undefined }}>\n {children}\n </OptionPlaceContext.Provider>\n ) : (\n <span style={{ color: colors.subtle }}>{placeholder}</span>\n )}\n </span>\n <IconGraphic name=\"chevron-down\" size={ICON_SIZE.small} color={colors.subtle} />\n </button>\n </Field>\n <SheetPanel open={open} title={label} onClose={() => setOpen(false)}>\n <div role=\"listbox\" style={{ display: 'flex', flexDirection: 'column' }}>\n <OptionPlaceContext.Provider value={{ inField: false, value, choose }}>\n {children}\n </OptionPlaceContext.Provider>\n </div>\n </SheetPanel>\n </>\n );\n};\n\nexport const Option: ReactComponent<typeof OptionManifest> = ({ value, label }) => {\n const { colors } = useTheme();\n const place = useContext(OptionPlaceContext);\n const chosen = value !== undefined && value === place.value;\n if (place.inField) {\n return chosen ? <>{label}</> : null;\n }\n const { choose } = place;\n const select = choose && value !== undefined ? () => choose(value) : undefined;\n return (\n <button\n type=\"button\"\n className=\"dot-option\"\n role=\"option\"\n aria-selected={chosen}\n onClick={select}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '14px 4px',\n border: 'none',\n borderBottom: `1px solid ${colors.border}`,\n background: 'transparent',\n color: colors.text,\n font: 'inherit',\n fontSize: FONT_SIZE.body,\n fontWeight: chosen ? 600 : 400,\n textAlign: 'start',\n cursor: 'pointer',\n }}\n >\n <span>{label}</span>\n {chosen ? <IconGraphic name=\"check\" size={ICON_SIZE.medium} color={colors.primary} /> : null}\n </button>\n );\n};\n","import type { Skeleton as SkeletonManifest } from '@monimesl/dot-core';\nimport type { ReactNode } from 'react';\nimport { useEffect, useRef } from 'react';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { animate } from './animate';\nimport { SPACE } from './tokens';\n\nconst PULSE: Keyframe[] = [{ opacity: 1 }, { opacity: 0.4 }, { opacity: 1 }];\n\nconst LINE_HEIGHT = 12;\n\nexport const Skeleton: ReactComponent<typeof SkeletonManifest> = ({\n shape = 'text',\n lines = 1,\n height,\n}) => {\n const { colors, radius } = useTheme();\n const placeholder = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const pulse = animate(placeholder.current, PULSE, { duration: 1200, iterations: Infinity });\n return () => pulse?.cancel();\n }, []);\n\n let content: ReactNode;\n if (shape === 'circle') {\n const size = height ?? 40;\n content = (\n <div style={{ width: size, height: size, borderRadius: '50%', background: colors.muted }} />\n );\n } else if (shape === 'box') {\n content = (\n <div style={{ height: height ?? 80, borderRadius: radius, background: colors.muted }} />\n );\n } else {\n const count = Math.max(1, lines);\n content = Array.from({ length: count }, (_, index) => {\n // A paragraph's last line is shorter than the others.\n const last = count > 1 && index === count - 1;\n return (\n <div\n key={index}\n style={{\n width: last ? '60%' : '100%',\n height: LINE_HEIGHT,\n borderRadius: LINE_HEIGHT / 2,\n background: colors.muted,\n }}\n />\n );\n });\n }\n return (\n <div\n ref={placeholder}\n className=\"dot-skeleton\"\n aria-busy=\"true\"\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: SPACE.medium,\n // Text and boxes take the width they're given; a circle keeps its size.\n width: shape === 'circle' ? undefined : '100%',\n flexShrink: shape === 'circle' ? 0 : 1,\n }}\n >\n {content}\n </div>\n );\n};\n","import type { Text as TextManifest } from '@monimesl/dot-core';\nimport type { CSSProperties } from 'react';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { FONT_SIZE } from './tokens';\nimport { toneColor } from './tones';\n\nconst VARIANTS = {\n body: { fontSize: FONT_SIZE.body },\n caption: { fontSize: FONT_SIZE.caption },\n title: { fontSize: FONT_SIZE.title, fontWeight: 600 },\n} as const;\n\nconst WEIGHTS = { regular: 400, medium: 500, bold: 600 } as const;\n\nexport const Text: ReactComponent<typeof TextManifest> = ({\n variant = 'body',\n tone,\n weight,\n align,\n maxLines,\n children,\n}) => {\n const { colors } = useTheme();\n const style: CSSProperties = { ...VARIANTS[variant], textAlign: align };\n if (tone) {\n style.color = toneColor(colors, tone);\n }\n if (weight) {\n style.fontWeight = WEIGHTS[weight];\n }\n if (maxLines) {\n Object.assign(style, {\n display: '-webkit-box',\n WebkitLineClamp: maxLines,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n });\n }\n return (\n <span className=\"dot-text\" style={style}>\n {children}\n </span>\n );\n};\n","import type { TextArea as TextAreaManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\n\nimport type { ReactComponent } from '../types';\nimport { Field } from './field';\nimport { useFieldBox } from './field-box';\nimport { useTypedText } from './typed-text';\n\nexport const TextArea: ReactComponent<typeof TextAreaManifest> = ({\n value,\n placeholder,\n label,\n hint,\n error,\n rows = 3,\n maxLength,\n disabled,\n onChange,\n}) => {\n const [text, typeText] = useTypedText(value, onChange !== undefined);\n const box = useFieldBox(error, disabled);\n return (\n <Field label={label} hint={hint} error={error}>\n <textarea\n className=\"dot-text-area\"\n value={text}\n placeholder={placeholder}\n rows={rows}\n maxLength={maxLength}\n disabled={disabled}\n aria-invalid={error ? true : undefined}\n onFocus={box.onFocus}\n onBlur={box.onBlur}\n onChange={(event) => {\n const next = event.currentTarget.value;\n typeText(next);\n onChange?.(createEvent('change', { value: next }));\n }}\n style={{\n font: 'inherit',\n ...box.style,\n boxSizing: 'border-box',\n width: '100%',\n padding: '12px 14px',\n outline: 'none',\n resize: 'none',\n }}\n />\n </Field>\n );\n};\n","import type { Toast as ToastManifest } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\nimport { useEffect, useEffectEvent, useState } from 'react';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { IconGraphic } from './icon';\nimport { FONT_SIZE, ICON_SIZE, SPACE } from './tokens';\nimport { STATUS_ICONS, toneColor } from './tones';\n\nexport const Toast: ReactComponent<typeof ToastManifest> = ({\n message,\n tone = 'default',\n duration = 2500,\n onHide,\n}) => {\n const { colors, radius } = useTheme();\n const [hidden, setHidden] = useState(false);\n const [previousMessage, setPreviousMessage] = useState(message);\n // A new message shows, even after the one before it hid.\n if (message !== previousMessage) {\n setPreviousMessage(message);\n setHidden(false);\n }\n const hide = useEffectEvent(() => {\n setHidden(true);\n onHide?.(createEvent('hide'));\n });\n useEffect(() => {\n if (!message) {\n return undefined;\n }\n const timer = setTimeout(hide, duration);\n return () => clearTimeout(timer);\n }, [message, duration]);\n\n if (!message || hidden) {\n return null;\n }\n return (\n <div\n className=\"dot-toast\"\n role=\"status\"\n style={{\n position: 'fixed',\n top: SPACE.large,\n left: '50%',\n transform: 'translateX(-50%)',\n zIndex: 110,\n display: 'flex',\n alignItems: 'center',\n gap: SPACE.medium,\n maxWidth: 'calc(100% - 32px)',\n width: 'max-content',\n padding: '10px 16px',\n borderRadius: radius,\n background: colors.primary,\n color: colors.surface,\n fontSize: FONT_SIZE.body,\n boxShadow: '0 4px 16px rgba(0, 0, 0, 0.2)',\n }}\n >\n {tone === 'default' ? null : (\n <IconGraphic\n name={STATUS_ICONS[tone]}\n size={ICON_SIZE.medium}\n color={toneColor(colors, tone)}\n />\n )}\n <span>{message}</span>\n </div>\n );\n};\n","import type {\n Checkbox as CheckboxManifest,\n Radio as RadioManifest,\n RadioGroup as RadioGroupManifest,\n Switch as SwitchManifest,\n} from '@monimesl/dot-core';\nimport type { DotEvent } from '@monimesl/dot-core';\nimport { createEvent } from '@monimesl/dot-core';\nimport type { CSSProperties, ReactNode } from 'react';\nimport { createContext, useContext } from 'react';\n\nimport type { ResolvedColors } from '../theme';\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { FieldLabel } from './field';\nimport { IconGraphic } from './icon';\nimport { DISABLED_OPACITY, FONT_SIZE, ICON_SIZE, SPACE } from './tokens';\n\n// The whole row, label included, is one button, so a tap anywhere on it toggles.\nfunction rowStyle(colors: ResolvedColors, disabled: boolean | undefined): CSSProperties {\n return {\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n width: '100%',\n padding: '6px 0',\n border: 'none',\n background: 'transparent',\n color: colors.text,\n font: 'inherit',\n fontSize: FONT_SIZE.body,\n textAlign: 'start',\n opacity: disabled ? DISABLED_OPACITY : 1,\n cursor: disabled ? 'default' : 'pointer',\n };\n}\n\nfunction changeTo(checked: boolean, onChange: ((event: DotEvent) => void) | undefined) {\n return onChange ? () => onChange(createEvent('change', { checked })) : undefined;\n}\n\n// The box of a Checkbox, or the circle of a Radio.\nfunction ChoiceMark({\n round,\n checked,\n children,\n}: {\n round: boolean;\n checked: boolean;\n children: ReactNode;\n}) {\n const { colors } = useTheme();\n // A checked box fills in; a chosen circle shows a dot inside instead.\n const filled = checked && !round;\n return (\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n width: 22,\n height: 22,\n boxSizing: 'border-box',\n borderRadius: round ? '50%' : 6,\n border: `2px solid ${checked ? colors.primary : colors.subtle}`,\n background: filled ? colors.primary : 'transparent',\n }}\n >\n {children}\n </span>\n );\n}\n\nexport const Switch: ReactComponent<typeof SwitchManifest> = ({\n checked = false,\n label,\n disabled,\n onChange,\n}) => {\n const { colors } = useTheme();\n return (\n <button\n type=\"button\"\n className=\"dot-switch\"\n role=\"switch\"\n aria-checked={checked}\n disabled={disabled}\n onClick={changeTo(!checked, onChange)}\n style={{ ...rowStyle(colors, disabled), justifyContent: 'space-between' }}\n >\n {label ? <span>{label}</span> : null}\n <span\n style={{\n position: 'relative',\n flexShrink: 0,\n width: 44,\n height: 26,\n borderRadius: 13,\n background: checked ? colors.primary : colors.subtle,\n transition: 'background 0.2s',\n }}\n >\n <span\n style={{\n position: 'absolute',\n top: 2,\n left: checked ? 20 : 2,\n width: 22,\n height: 22,\n borderRadius: '50%',\n background: colors.surface,\n transition: 'left 0.2s',\n }}\n />\n </span>\n </button>\n );\n};\n\nexport const Checkbox: ReactComponent<typeof CheckboxManifest> = ({\n checked = false,\n label,\n disabled,\n onChange,\n}) => {\n const { colors } = useTheme();\n return (\n <button\n type=\"button\"\n className=\"dot-checkbox\"\n role=\"checkbox\"\n aria-checked={checked}\n disabled={disabled}\n onClick={changeTo(!checked, onChange)}\n style={rowStyle(colors, disabled)}\n >\n <ChoiceMark round={false} checked={checked}>\n {checked ? (\n <IconGraphic name=\"check\" size={ICON_SIZE.small} color={colors.surface} />\n ) : null}\n </ChoiceMark>\n {label ? <span>{label}</span> : null}\n </button>\n );\n};\n\ninterface RadioChoice {\n value: string | undefined;\n disabled: boolean;\n choose: ((value: string) => void) | undefined;\n}\n\nconst RadioGroupContext = createContext<RadioChoice>({\n value: undefined,\n disabled: true,\n choose: undefined,\n});\n\nexport const RadioGroup: ReactComponent<typeof RadioGroupManifest> = ({\n value,\n label,\n disabled = false,\n onChange,\n children,\n}) => {\n const choose = onChange\n ? (next: string) => onChange(createEvent('change', { value: next }))\n : undefined;\n return (\n <div\n className=\"dot-radio-group\"\n role=\"radiogroup\"\n aria-label={label}\n style={{ display: 'flex', flexDirection: 'column', gap: SPACE.small }}\n >\n {label ? <FieldLabel>{label}</FieldLabel> : null}\n <RadioGroupContext.Provider value={{ value, disabled, choose }}>\n {children}\n </RadioGroupContext.Provider>\n </div>\n );\n};\n\nexport const Radio: ReactComponent<typeof RadioManifest> = ({ value, label, disabled }) => {\n const { colors } = useTheme();\n const group = useContext(RadioGroupContext);\n const selected = value !== undefined && value === group.value;\n const inactive = disabled || group.disabled;\n const { choose } = group;\n const select = choose && value !== undefined ? () => choose(value) : undefined;\n return (\n <button\n type=\"button\"\n className=\"dot-radio\"\n role=\"radio\"\n aria-checked={selected}\n disabled={inactive}\n onClick={select}\n style={rowStyle(colors, inactive)}\n >\n <ChoiceMark round checked={selected}>\n {selected ? (\n <span\n style={{ width: 10, height: 10, borderRadius: '50%', background: colors.primary }}\n />\n ) : null}\n </ChoiceMark>\n {label ? <span>{label}</span> : null}\n </button>\n );\n};\n","import { createEvent } from '@monimesl/dot-core';\nimport type { View as ViewManifest } from '@monimesl/dot-core';\n\nimport { useTheme } from '../theme';\nimport type { ReactComponent } from '../types';\nimport { CARD_RADIUS_SCALE, SPACE } from './tokens';\n\nconst ALIGN = {\n stretch: 'stretch',\n start: 'flex-start',\n center: 'center',\n end: 'flex-end',\n} as const;\n\nconst JUSTIFY = {\n start: 'flex-start',\n center: 'center',\n end: 'flex-end',\n between: 'space-between',\n} as const;\n\nexport const View: ReactComponent<typeof ViewManifest> = ({\n direction = 'column',\n gap = 'medium',\n align = 'stretch',\n justify = 'start',\n wrap = false,\n grow = false,\n padding,\n paddingTop,\n paddingStart,\n paddingEnd,\n paddingBottom,\n variant = 'plain',\n onTap,\n children,\n}) => {\n const { colors, radius } = useTheme();\n const card = variant === 'card';\n const allSides = padding ?? (card ? 'large' : 'none');\n const handleClick = onTap ? () => onTap(createEvent('tap')) : undefined;\n return (\n <div\n className=\"dot-view\"\n onClick={handleClick}\n style={{\n display: 'flex',\n flexDirection: direction,\n gap: SPACE[gap],\n alignItems: ALIGN[align],\n justifyContent: JUSTIFY[justify],\n flexWrap: wrap ? 'wrap' : undefined,\n flexGrow: grow ? 1 : undefined,\n // Lets a growing view shrink below its content's width, so long text wraps.\n minWidth: grow ? 0 : undefined,\n paddingTop: SPACE[paddingTop ?? allSides],\n paddingInlineStart: SPACE[paddingStart ?? allSides],\n paddingInlineEnd: SPACE[paddingEnd ?? allSides],\n paddingBottom: SPACE[paddingBottom ?? allSides],\n borderRadius: card ? radius * CARD_RADIUS_SCALE : undefined,\n background: card ? colors.surface : undefined,\n border: card ? `1px solid ${colors.border}` : undefined,\n cursor: onTap ? 'pointer' : undefined,\n }}\n >\n {children}\n </div>\n );\n};\n","import type { BuiltinReactComponents } from '../types';\nimport { Button } from './button';\nimport { Divider } from './divider';\nimport { Badge, Notice, ProgressBar } from './feedback';\nimport { Footer } from './footer';\nimport { Icon } from './icon';\nimport { Image } from './image';\nimport { Input } from './input';\nimport { List, ListItem } from './list';\nimport { Option, Select } from './select';\nimport { Sheet } from './sheet';\nimport { Skeleton } from './skeleton';\nimport { Spinner } from './spinner';\nimport { Text } from './text';\nimport { TextArea } from './text-area';\nimport { Toast } from './toast';\nimport { Checkbox, Radio, RadioGroup, Switch } from './toggles';\nimport { View } from './view';\n\nexport const builtins: BuiltinReactComponents = {\n Badge,\n Button,\n Checkbox,\n Divider,\n Footer,\n Icon,\n Image,\n Input,\n List,\n ListItem,\n Notice,\n Option,\n ProgressBar,\n Radio,\n RadioGroup,\n Select,\n Sheet,\n Skeleton,\n Spinner,\n Switch,\n Text,\n TextArea,\n Toast,\n View,\n};\n","import type { ComponentType, ReactNode } from 'react';\nimport { toList, toText } from '@monimesl/dot-core';\nimport type { RenderContext } from '@monimesl/dot-core';\nimport type { PageController } from '@monimesl/dot-webview';\nimport { createElement, Fragment, useMemo, useSyncExternalStore } from 'react';\n\nexport type ComponentMap = Readonly<Record<string, ComponentType<Record<string, unknown>>>>;\n\ninterface PageRootProps {\n page: PageController;\n components: ComponentMap;\n}\n\nexport function PageRoot({ page, components }: PageRootProps) {\n const state = useSyncExternalStore(page.subscribe, page.getState);\n const context = useMemo<RenderContext<ReactNode>>(\n () => ({\n h(type, props, ...children) {\n const component = components[type];\n if (!component) {\n throw new Error(`The renderer has no component registered for tag '<${type}>'`);\n }\n return createElement(component, props, ...children);\n },\n text: toText,\n on: (handler, data) => page.on(handler, data),\n each: (items, render, key) =>\n createElement(\n Fragment,\n null,\n toList(items).map((item, index) =>\n createElement(\n Fragment,\n { key: key ? String(key(item, index)) : index },\n ...render(item, index),\n ),\n ),\n ),\n }),\n [page, components],\n );\n if (!state) {\n return null;\n }\n return page.viewRenderer(state, context);\n}\n","import type { Theme } from '@monimesl/dot-core';\nimport type { ComponentType, ReactNode } from 'react';\nimport { useMemo, useSyncExternalStore } from 'react';\nimport type { DotContext, PageController } from '@monimesl/dot-webview';\n\nimport { PageRoot } from './page-root';\nimport type { ComponentMap } from './page-root';\nimport { FONT_FAMILY, resolveTheme, ThemeContext, useTheme } from './theme';\n\nexport type Wrapper = ComponentType<{ theme: Theme; children: ReactNode }>;\n\ninterface RootProps {\n page: PageController;\n dotContext: DotContext;\n components: ComponentMap;\n wrapper: Wrapper | undefined;\n}\n\nexport function Root({ page, dotContext, components, wrapper: Wrapper }: RootProps) {\n const theme = useSyncExternalStore(dotContext.theme.subscribe, dotContext.theme.get);\n const systemContext = useSyncExternalStore(\n dotContext.systemContext.subscribe,\n dotContext.systemContext.get,\n );\n const resolved = useMemo(\n () => resolveTheme(theme, systemContext.scheme),\n [theme, systemContext.scheme],\n );\n const content = <PageRoot page={page} components={components} />;\n\n return (\n <ThemeContext.Provider value={resolved}>\n {Wrapper ? (\n <Wrapper theme={{ ...theme, scheme: resolved.scheme }}>{content}</Wrapper>\n ) : (\n <DefaultSurface>{content}</DefaultSurface>\n )}\n </ThemeContext.Provider>\n );\n}\n\nfunction DefaultSurface({ children }: { children: ReactNode }) {\n const { colors } = useTheme();\n return (\n <div\n className=\"dot-surface\"\n style={{\n minHeight: '100vh',\n display: 'flex',\n flexDirection: 'column',\n background: colors.background,\n color: colors.text,\n fontFamily: FONT_FAMILY,\n }}\n >\n {children}\n </div>\n );\n}\n","import type { Renderer } from '@monimesl/dot-webview';\nimport type { JSXElementConstructor } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport { builtins } from './components';\nimport type { ComponentMap } from './page-root';\nimport type { Wrapper } from './root';\nimport { Root } from './root';\nimport type { BuiltinReactComponents } from './types';\n\nexport interface ReactRendererOptions {\n components?: Partial<BuiltinReactComponents> &\n Readonly<Record<string, JSXElementConstructor<never>>>;\n wrapper?: Wrapper;\n}\n\nexport function reactRenderer({ components = {}, wrapper }: ReactRendererOptions = {}): Renderer {\n const registry = { ...builtins, ...components } as unknown as ComponentMap;\n\n return {\n name: 'react',\n mount(container, page, dotContext) {\n const root = createRoot(container);\n root.render(\n <Root page={page} dotContext={dotContext} components={registry} wrapper={wrapper} />,\n );\n return () => root.unmount();\n },\n };\n}\n","export type { Wrapper } from './root';\nexport { builtins } from './components';\nimport { reactRenderer } from './renderer';\n\nexport type { ReactRendererOptions } from './renderer';\n\nexport { resolveTheme, useTheme } from './theme';\nexport type { ResolvedColors, ResolvedTheme } from './theme';\n\nexport type { BuiltinReactComponents, ReactComponent, ReactComponents } from './types';\n\nexport default reactRenderer;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monimesl/dot-renderer-react",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.3",
4
4
  "description": "React renderer for Dot webviews",
5
5
  "type": "module",
6
6
  "repository": {
@@ -24,10 +24,11 @@
24
24
  "main": "./dist/index.js",
25
25
  "types": "./dist/index.d.ts",
26
26
  "dependencies": {
27
+ "lucide": "^1.48.0",
27
28
  "react": "^19.3.0",
28
29
  "react-dom": "^19.3.0",
29
- "@monimesl/dot-core": "0.1.0-alpha.2",
30
- "@monimesl/dot-webview": "0.1.0-alpha.2"
30
+ "@monimesl/dot-core": "0.1.0-alpha.3",
31
+ "@monimesl/dot-webview": "0.1.0-alpha.3"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@testing-library/react": "^16.3.3",
@@ -40,7 +41,7 @@
40
41
  "tsdown": "^0.23.0",
41
42
  "typescript": "^5.9.3",
42
43
  "vitest": "^5.0.1",
43
- "@monimesl/dot-service": "0.1.0-alpha.2"
44
+ "@monimesl/dot-service": "0.1.0-alpha.3"
44
45
  },
45
46
  "publishConfig": {
46
47
  "access": "public"