@x12i/fieldkit 1.0.0
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/LICENSE +21 -0
- package/README.md +153 -0
- package/dist/index.cjs +662 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +186 -0
- package/dist/index.d.ts +186 -0
- package/dist/index.js +609 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/theme.tsx","../src/infer.ts","../src/resolve.ts","../src/icons.tsx","../src/components/FieldRenderer.tsx","../src/components/RecordView.tsx"],"sourcesContent":["import * as React from 'react';\n\n/** Named tones the palette guarantees. A theme can rename their hexes; consumer\n * toneMaps point AT these names (e.g. { REQUIRE_INFORMATION: 'amber' }), never at hex. */\nexport const TONE_PALETTE = {\n neutral: '#8B96A3',\n amber: '#E8A33D',\n rose: '#E2564F',\n green: '#59B87B',\n blue: '#6FA8DC',\n violet: '#9B8CDB',\n teal: '#4FB6A8',\n} as const;\n\nexport type ToneName = keyof typeof TONE_PALETTE;\n\nconst HASHABLE_TONES: ToneName[] = ['amber', 'rose', 'green', 'blue', 'violet', 'teal'];\n\n/** Deterministic fallback so an enum value nobody mapped yet still gets a stable,\n * distinct color instead of falling back to the same neutral gray every time. */\nexport function hashTone(value: string): ToneName {\n let h = 0;\n for (let i = 0; i < value.length; i++) h = (h * 31 + value.charCodeAt(i)) >>> 0;\n return HASHABLE_TONES[h % HASHABLE_TONES.length];\n}\n\n/** `colors.accent` and every value in `tonePalette` must be 6-digit hex ('#rrggbb'):\n * FieldRenderer and RecordView tint them for badges/boxes by appending 2 hex digits\n * of alpha ('${hex}24'), which only produces valid CSS for that format. The rest of\n * `colors` is used as-is and accepts any valid CSS color. */\nexport interface FieldKitTheme {\n colors: {\n background: string;\n surface: string;\n surfaceMuted: string;\n border: string;\n textPrimary: string;\n textSecondary: string;\n textMuted: string;\n accent: string;\n };\n fonts: {\n heading: string;\n body: string;\n mono: string;\n };\n radii: {\n sm: string;\n md: string;\n lg: string;\n pill: string;\n };\n tonePalette: Record<string, string>;\n}\n\nexport const defaultTheme: FieldKitTheme = {\n colors: {\n background: '#0A0E13',\n surface: '#10161D',\n surfaceMuted: '#0D1218',\n border: 'rgba(255,255,255,0.07)',\n textPrimary: '#F4F6F8',\n textSecondary: '#C7CDD3',\n textMuted: '#5B6672',\n accent: '#4FB6A8',\n },\n fonts: {\n heading: \"'Space Grotesk', ui-sans-serif, sans-serif\",\n body: \"'IBM Plex Sans', ui-sans-serif, sans-serif\",\n mono: \"'IBM Plex Mono', ui-monospace, monospace\",\n },\n radii: { sm: '5px', md: '8px', lg: '14px', pill: '999px' },\n tonePalette: TONE_PALETTE,\n};\n\nexport type FieldKitThemeOverride = {\n [K in keyof FieldKitTheme]?: Partial<FieldKitTheme[K]>;\n};\n\nfunction mergeTheme(base: FieldKitTheme, override?: FieldKitThemeOverride): FieldKitTheme {\n if (!override) return base;\n return {\n colors: { ...base.colors, ...override.colors },\n fonts: { ...base.fonts, ...override.fonts },\n radii: { ...base.radii, ...override.radii },\n tonePalette: { ...base.tonePalette, ...override.tonePalette } as Record<string, string>,\n };\n}\n\nconst ThemeContext = React.createContext<FieldKitTheme>(defaultTheme);\n\nexport interface FieldKitProviderProps {\n theme?: FieldKitThemeOverride;\n children: React.ReactNode;\n}\n\n/** Wrap your app (or just the part that uses fieldkit) in this to change colors,\n * fonts, or radii. Anything you don't override keeps the default. */\nexport function FieldKitProvider({ theme, children }: FieldKitProviderProps) {\n const parent = React.useContext(ThemeContext);\n const merged = React.useMemo(() => mergeTheme(parent, theme), [parent, theme]);\n return <ThemeContext.Provider value={merged}>{children}</ThemeContext.Provider>;\n}\n\nexport function useFieldKitTheme(): FieldKitTheme {\n return React.useContext(ThemeContext);\n}\n\nexport function toneHex(theme: FieldKitTheme, toneKey: string | undefined): string {\n if (!toneKey) return theme.tonePalette.neutral ?? TONE_PALETTE.neutral;\n return theme.tonePalette[toneKey] ?? TONE_PALETTE.neutral;\n}\n","import type { ClassifySignal, FieldKind, FieldRule } from './types';\n\n/** camelCase / snake_case -> \"Title Case\", used both for auto-labeling leftover\n * fields and for humanizing enum values (\"REQUIRE_INFORMATION\" -> \"Require Information\"). */\nexport function labelFromKey(key: string): string {\n const spaced = key\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/_/g, ' ')\n .toLowerCase();\n return spaced\n .split(' ')\n .filter(Boolean)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\n/** Default severity heuristic for a 'signals' field: sentences that assert something\n * is unresolved/unknown/missing read as a warning; everything else as a plain note.\n * Override via RecordView's `classifySignal` prop if your domain needs sharper rules. */\nexport const defaultClassifySignal: ClassifySignal = (text) => {\n const t = text.toLowerCase();\n const flagged = t.includes('unresolved') || t.includes('unknown') || t.includes('missing');\n return flagged ? 'warn' : 'info';\n};\n\nconst ENUM_LIKE = /^[A-Z0-9]+(_[A-Z0-9]+)*$/;\n\n/** The leftover handler: infers a render kind from the VALUE's shape alone, for any\n * key your FieldRules map doesn't (yet) cover. Same kinds as the curated map — this\n * is a safety net, not a second taxonomy. */\nexport function inferRule(key: string, value: unknown): FieldRule {\n const label = labelFromKey(key);\n const as = ((): FieldKind => {\n if (value === null || value === undefined || value === '') return 'empty';\n if (typeof value === 'boolean') return 'flag';\n if (typeof value === 'number') return 'stat';\n if (typeof value === 'string') {\n if (ENUM_LIKE.test(value)) return 'pill';\n if (value.length > 70 || /[.!?]\\s/.test(value)) return 'lead';\n if (!value.includes(' ') && value.length > 12) return 'mono';\n return 'text';\n }\n if (Array.isArray(value)) {\n if (value.length === 0) return 'empty';\n if (value.every((v) => typeof v === 'string')) {\n if ((value as string[]).every((v) => /\\?\\s*$/.test(v))) return 'qa';\n if ((value as string[]).some((v) => v.split(' ').length > 6)) return 'bullets';\n return 'tags';\n }\n return 'json';\n }\n return 'json';\n })();\n return { label, as };\n}\n","import { hashTone } from './theme';\nimport { labelFromKey, defaultClassifySignal } from './infer';\nimport type { ClassifySignal, FieldRule, ResolvedField, ToneMap } from './types';\n\nexport interface ResolveOptions {\n isLeftover?: boolean;\n classifySignal?: ClassifySignal;\n toneMap?: ToneMap;\n}\n\nfunction resolveTone(value: string, toneMap?: ToneMap): string {\n return toneMap?.[value] ?? hashTone(value);\n}\n\n/** Turns one (key, value, rule) triple into everything FieldRenderer needs — the one\n * place that understands what each FieldKind's payload looks like. Used identically\n * for curated fields (rule from your FieldRules map) and leftovers (rule from inferRule). */\nexport function resolveField(\n key: string,\n value: unknown,\n rule: FieldRule,\n options: ResolveOptions = {}\n): ResolvedField {\n const label = rule.label ?? labelFromKey(key);\n const classifySignal = options.classifySignal ?? defaultClassifySignal;\n const base: ResolvedField = {\n key,\n label,\n kind: rule.as,\n isLeftover: options.isLeftover ?? false,\n };\n\n switch (rule.as) {\n case 'lead':\n return { ...base, text: String(value ?? '') };\n case 'bullets':\n return { ...base, items: ((value as string[]) ?? []).map((t) => ({ text: t })) };\n case 'signals':\n return {\n ...base,\n items: ((value as string[]) ?? []).map((t) => {\n const s = classifySignal(t);\n return { text: t, warn: s === 'warn', info: s === 'info' };\n }),\n };\n case 'qa':\n return { ...base, items: ((value as string[]) ?? []).map((t) => ({ text: t })) };\n case 'pill': {\n const raw = String(value ?? '');\n return { ...base, pillText: labelFromKey(raw.toLowerCase()), toneKey: resolveTone(raw, options.toneMap) };\n }\n case 'mono':\n return { ...base, value: String(value ?? '') };\n case 'text':\n return { ...base, value: String(value ?? '') };\n case 'flag':\n return { ...base, flagOn: !!value, flagText: value ? 'Yes' : 'No' };\n case 'stat':\n return { ...base, value: String(value ?? '') };\n case 'tags':\n return { ...base, items: ((value as string[]) ?? []).map((t) => ({ text: t })) };\n case 'empty':\n return base;\n case 'json':\n default:\n return { ...base, kind: 'json', value: JSON.stringify(value, null, 2) };\n }\n}\n","import * as React from 'react';\n\nexport interface IconProps {\n size?: number;\n color?: string;\n style?: React.CSSProperties;\n}\n\nconst base = (size: number, color: string, style?: React.CSSProperties): React.SVGProps<SVGSVGElement> => ({\n width: size,\n height: size,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: color,\n strokeWidth: 1.8,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n style,\n});\n\nexport function CheckIcon({ size = 15, color = 'currentColor', style }: IconProps) {\n return (\n <svg {...base(size, color, style)}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M8 12.3l2.6 2.6L16 9.3\" />\n </svg>\n );\n}\n\nexport function WarningIcon({ size = 15, color = '#E8A33D', style }: IconProps) {\n return (\n <svg {...base(size, color, style)}>\n <path d=\"M12 3 2 21h20L12 3z\" />\n <path d=\"M12 9.5v5\" />\n <circle cx=\"12\" cy=\"17.2\" r=\"0.9\" fill={color} stroke=\"none\" />\n </svg>\n );\n}\n\nexport function InfoIcon({ size = 15, color = '#7C8894', style }: IconProps) {\n return (\n <svg {...base(size, color, style)}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <line x1=\"12\" y1=\"10.5\" x2=\"12\" y2=\"16.2\" />\n <circle cx=\"12\" cy=\"7.6\" r=\"0.9\" fill={color} stroke=\"none\" />\n </svg>\n );\n}\n\nexport function QuestionIcon({ size = 15, color = 'currentColor', style }: IconProps) {\n return (\n <svg {...base(size, color, style)}>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M9.5 9.3a2.5 2.5 0 1 1 3.5 2.3c-.9.5-1 1-1 1.9\" />\n <circle cx=\"12\" cy=\"17\" r=\"0.9\" fill={color} stroke=\"none\" />\n </svg>\n );\n}\n\nexport function ChevronDownIcon({ size = 14, color = 'currentColor', style }: IconProps) {\n return (\n <svg {...base(size, color, style)}>\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n );\n}\n","import * as React from 'react';\nimport { toneHex, useFieldKitTheme } from '../theme';\nimport { CheckIcon, InfoIcon, QuestionIcon, WarningIcon } from '../icons';\nimport type { ResolvedField } from '../types';\n\nfunction assertNever(x: never): never {\n throw new Error('Unhandled FieldKind: ' + JSON.stringify(x));\n}\n\nexport interface FieldRendererProps {\n field: ResolvedField;\n /** 'content' = the full-weight treatment (bigger text, icons, tinted boxes) for\n * primary content. 'compact' = the label-over-value treatment used for diagnostics\n * and leftovers. Both cover all twelve kinds — nothing renders blank because of\n * which tier a field ended up in. */\n variant?: 'content' | 'compact';\n /** Renders the field's label above its value. RecordView turns this off when it\n * wants to draw the label itself (e.g. inside a shared row layout). */\n showLabel?: boolean;\n}\n\n/** Renders exactly one resolved field. This is the only place that knows what each\n * FieldKind looks like — every tier (content / diagnostics / leftovers) calls the\n * same component, so a kind can never be supported in one place and forgotten in\n * another the way three separate hand-written blocks could silently drift apart. */\nexport function FieldRenderer({ field, variant = 'compact', showLabel = true }: FieldRendererProps) {\n const theme = useFieldKitTheme();\n const isContent = variant === 'content';\n\n const labelNode = showLabel ? (\n <span\n style={{\n fontFamily: theme.fonts.heading,\n fontSize: isContent ? 11.5 : 10.5,\n fontWeight: 600,\n letterSpacing: '0.08em',\n textTransform: 'uppercase',\n color: theme.colors.textMuted,\n }}\n >\n {field.label}\n </span>\n ) : null;\n\n let body: React.ReactNode;\n\n switch (field.kind) {\n case 'lead':\n body = (\n <p\n style={{\n margin: 0,\n fontSize: isContent ? 15 : 13,\n lineHeight: 1.6,\n color: isContent ? theme.colors.textSecondary : theme.colors.textMuted,\n }}\n >\n {field.text}\n </p>\n );\n break;\n\n case 'bullets':\n body = (\n <div style={{ display: 'flex', flexDirection: 'column', gap: isContent ? 10 : 6 }}>\n {field.items?.map((item, i) =>\n isContent ? (\n <div key={i} style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>\n <CheckIcon size={15} color={theme.colors.accent} style={{ flexShrink: 0, marginTop: 3 }} />\n <span style={{ fontSize: 14, lineHeight: 1.55, color: theme.colors.textSecondary }}>{item.text}</span>\n </div>\n ) : (\n <div key={i} style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}>\n <span style={{ color: theme.colors.textMuted, fontSize: 13 }}>–</span>\n <span style={{ fontSize: 13, lineHeight: 1.5, color: theme.colors.textMuted }}>{item.text}</span>\n </div>\n )\n )}\n </div>\n );\n break;\n\n case 'signals':\n body = (\n <div style={{ display: 'flex', flexDirection: 'column', gap: isContent ? 8 : 6 }}>\n {field.items?.map((item, i) => (\n <div\n key={i}\n style={{\n display: 'flex',\n gap: 10,\n alignItems: 'flex-start',\n background: theme.colors.surfaceMuted,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: isContent ? 8 : 6,\n padding: isContent ? '12px 14px' : '8px 10px',\n }}\n >\n {item.warn && <WarningIcon size={isContent ? 15 : 13} style={{ flexShrink: 0, marginTop: 2 }} />}\n {item.info && <InfoIcon size={isContent ? 15 : 13} style={{ flexShrink: 0, marginTop: 2 }} />}\n <span\n style={{\n fontSize: isContent ? 13.5 : 13,\n lineHeight: 1.55,\n color: isContent ? theme.colors.textSecondary : theme.colors.textMuted,\n }}\n >\n {item.text}\n </span>\n </div>\n ))}\n </div>\n );\n break;\n\n case 'qa':\n body = (\n <div\n style={\n isContent\n ? {\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n background: `${theme.colors.accent}12`,\n border: `1px solid ${theme.colors.accent}33`,\n borderRadius: 10,\n padding: '14px 16px',\n }\n : { display: 'flex', flexDirection: 'column', gap: 6 }\n }\n >\n {field.items?.map((item, i) => (\n <div key={i} style={{ display: 'flex', gap: isContent ? 10 : 8, alignItems: 'flex-start' }}>\n {isContent ? (\n <QuestionIcon size={15} color={theme.colors.accent} style={{ flexShrink: 0, marginTop: 2 }} />\n ) : (\n <span style={{ color: theme.colors.accent, fontSize: 13, fontWeight: 600 }}>?</span>\n )}\n <span\n style={{\n fontSize: isContent ? 14 : 13,\n lineHeight: 1.55,\n color: isContent ? theme.colors.textSecondary : theme.colors.textMuted,\n }}\n >\n {item.text}\n </span>\n </div>\n ))}\n </div>\n );\n break;\n\n case 'pill': {\n const hex = toneHex(theme, field.toneKey);\n body = (\n <span\n style={{\n alignSelf: 'flex-start',\n padding: '3px 9px',\n borderRadius: theme.radii.sm,\n fontSize: 11,\n fontWeight: 600,\n fontFamily: theme.fonts.heading,\n textTransform: 'uppercase',\n background: `${hex}24`,\n color: hex,\n border: `1px solid ${hex}55`,\n }}\n >\n {field.pillText}\n </span>\n );\n break;\n }\n\n case 'mono':\n body = (\n <span style={{ fontFamily: theme.fonts.mono, fontSize: isContent ? 13 : 12.5, color: theme.colors.textMuted }}>\n {field.value}\n </span>\n );\n break;\n\n case 'text':\n body = (\n <span\n style={{\n fontSize: isContent ? 14 : 13,\n lineHeight: 1.55,\n color: isContent ? theme.colors.textSecondary : theme.colors.textMuted,\n }}\n >\n {field.value}\n </span>\n );\n break;\n\n case 'flag': {\n const hex = field.flagOn ? theme.tonePalette.green ?? '#59B87B' : theme.colors.textMuted;\n body = (\n <span\n style={{\n alignSelf: 'flex-start',\n padding: '3px 9px',\n borderRadius: theme.radii.sm,\n fontSize: 11,\n fontWeight: 600,\n fontFamily: theme.fonts.heading,\n textTransform: 'uppercase',\n background: `${hex}24`,\n color: hex,\n border: `1px solid ${hex}55`,\n }}\n >\n {field.flagText}\n </span>\n );\n break;\n }\n\n case 'stat':\n body = (\n <span style={{ fontFamily: theme.fonts.mono, fontSize: isContent ? 16 : 15, color: theme.colors.textSecondary }}>\n {field.value}\n </span>\n );\n break;\n\n case 'tags':\n body = (\n <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>\n {field.items?.map((item, i) => (\n <span\n key={i}\n style={{\n background: theme.colors.surfaceMuted,\n color: theme.colors.textMuted,\n border: `1px solid ${theme.colors.border}`,\n padding: '3px 9px',\n borderRadius: theme.radii.sm,\n fontSize: 11.5,\n }}\n >\n {item.text}\n </span>\n ))}\n </div>\n );\n break;\n\n case 'empty':\n body = <span style={{ fontSize: 13, color: theme.colors.textMuted, opacity: 0.6 }}>— not provided —</span>;\n break;\n\n case 'json':\n body = (\n <pre\n style={{\n margin: 0,\n fontFamily: theme.fonts.mono,\n fontSize: 11.5,\n color: theme.colors.textMuted,\n whiteSpace: 'pre-wrap',\n background: theme.colors.background,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radii.sm,\n padding: '10px 12px',\n }}\n >\n {field.value}\n </pre>\n );\n break;\n\n default:\n return assertNever(field.kind);\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: isContent ? 12 : 6 }}>\n {labelNode}\n {body}\n </div>\n );\n}\n","import * as React from 'react';\nimport { useFieldKitTheme } from '../theme';\nimport { inferRule } from '../infer';\nimport { resolveField } from '../resolve';\nimport { FieldRenderer } from './FieldRenderer';\nimport { ChevronDownIcon, WarningIcon } from '../icons';\nimport type { BannerContent, ClassifySignal, FieldRules, ToneMap } from '../types';\n\nexport interface RecordViewProps {\n /** The record to render. Any shape — only `fieldRules` + the key lists below decide meaning. */\n record: Record<string, unknown>;\n /** Your metadata map: field name -> how to render it. Extend this whenever you want a\n * field promoted out of the leftover bucket. */\n fieldRules: FieldRules;\n /** Keys rendered as primary content, in order, using the full-weight FieldRenderer variant. */\n contentKeys: string[];\n /** Keys rendered inside the collapsible diagnostics panel, using the compact variant. */\n diagnosticKeys: string[];\n /** Keys handled entirely by your own `header` render prop — excluded from generic\n * rendering (title, status, timestamps: whatever your header needs). */\n identityKeys?: string[];\n /** Renders the card's header (title, status pill, meta row, …). Domain-specific by\n * nature, so fieldkit doesn't guess at it. */\n header?: (record: Record<string, unknown>) => React.ReactNode;\n /** Derives an optional attention banner from the record — e.g. promote a broken\n * pipeline state to the top instead of leaving it buried in diagnostics. */\n banner?: (record: Record<string, unknown>) => BannerContent | null;\n /** Overrides the default warn/info heuristic used by 'signals' fields. */\n classifySignal?: ClassifySignal;\n /** Maps your domain's enum values (statuses, quality flags, …) to tone names. Anything\n * not listed here still gets a stable color via a deterministic hash, never a crash. */\n toneMap?: ToneMap;\n defaultDiagnosticsOpen?: boolean;\n diagnosticsLabel?: string;\n diagnosticsHint?: string;\n style?: React.CSSProperties;\n}\n\n/** Renders a record's content fields, plus a collapsible panel holding both the\n * curated diagnostic fields AND anything left over — every key in `record` ends up\n * somewhere, never silently dropped. */\nexport function RecordView({\n record,\n fieldRules,\n contentKeys,\n diagnosticKeys,\n identityKeys = [],\n header,\n banner,\n classifySignal,\n toneMap,\n defaultDiagnosticsOpen = false,\n diagnosticsLabel = 'Diagnostics',\n diagnosticsHint = 'Every other field this record reports, curated and unmapped alike',\n style,\n}: RecordViewProps) {\n const theme = useFieldKitTheme();\n const [open, setOpen] = React.useState(defaultDiagnosticsOpen);\n\n const contentFields = React.useMemo(\n () => contentKeys.map((key) => resolveField(key, record[key], fieldRules[key], { classifySignal, toneMap })),\n [record, fieldRules, contentKeys, classifySignal, toneMap]\n );\n\n const diagnosticFields = React.useMemo(\n () => diagnosticKeys.map((key) => resolveField(key, record[key], fieldRules[key], { classifySignal, toneMap })),\n [record, fieldRules, diagnosticKeys, classifySignal, toneMap]\n );\n\n const leftoverFields = React.useMemo(() => {\n const known = new Set([...Object.keys(fieldRules), ...identityKeys]);\n return Object.keys(record)\n .filter((k) => !known.has(k))\n .map((k) => resolveField(k, record[k], inferRule(k, record[k]), { isLeftover: true, classifySignal, toneMap }));\n }, [record, fieldRules, identityKeys, classifySignal, toneMap]);\n\n const bannerContent = banner ? banner(record) : null;\n\n return (\n <div\n style={{\n background: theme.colors.surface,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radii.lg,\n padding: '36px 40px',\n display: 'flex',\n flexDirection: 'column',\n gap: 26,\n fontFamily: theme.fonts.body,\n color: theme.colors.textPrimary,\n ...style,\n }}\n >\n {header?.(record)}\n\n {bannerContent && (\n <div\n style={{\n background: `${theme.tonePalette.rose ?? '#E2564F'}14`,\n border: `1px solid ${theme.tonePalette.rose ?? '#E2564F'}48`,\n borderRadius: 10,\n padding: '16px 18px',\n display: 'flex',\n gap: 12,\n alignItems: 'flex-start',\n }}\n >\n <WarningIcon size={19} color={theme.tonePalette.rose ?? '#E2564F'} style={{ flexShrink: 0, marginTop: 2 }} />\n <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>\n <span style={{ fontFamily: theme.fonts.heading, fontSize: 14, fontWeight: 600, color: theme.colors.textPrimary }}>\n {bannerContent.title}\n </span>\n <span style={{ fontSize: 13.5, lineHeight: 1.55, color: theme.colors.textSecondary }}>{bannerContent.body}</span>\n {bannerContent.tags && bannerContent.tags.length > 0 && (\n <div style={{ display: 'flex', gap: 6, marginTop: 2, flexWrap: 'wrap' }}>\n {bannerContent.tags.map((t, i) => (\n <span\n key={i}\n style={{\n background: `${theme.tonePalette.rose ?? '#E2564F'}24`,\n color: theme.tonePalette.rose ?? '#E2564F',\n border: `1px solid ${theme.tonePalette.rose ?? '#E2564F'}55`,\n padding: '3px 8px',\n borderRadius: 5,\n fontFamily: theme.fonts.heading,\n fontSize: 10.5,\n fontWeight: 600,\n letterSpacing: '0.04em',\n textTransform: 'uppercase',\n }}\n >\n {t}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n )}\n\n {contentFields.map((field) => (\n <FieldRenderer key={field.key} field={field} variant=\"content\" />\n ))}\n\n {(diagnosticFields.length > 0 || leftoverFields.length > 0) && (\n <>\n <div style={{ height: 1, background: theme.colors.border }} />\n\n <button\n onClick={() => setOpen((v) => !v)}\n style={{\n all: 'unset',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n boxSizing: 'border-box',\n }}\n >\n <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <span style={{ fontFamily: theme.fonts.heading, fontSize: 12.5, fontWeight: 600, letterSpacing: '0.04em', color: theme.colors.textSecondary }}>\n {diagnosticsLabel}\n </span>\n <span style={{ fontSize: 11.5, color: theme.colors.textMuted }}>{diagnosticsHint}</span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{ fontSize: 12, color: theme.colors.textMuted }}>{open ? 'Hide' : 'Show'}</span>\n <ChevronDownIcon\n size={14}\n color={theme.colors.textMuted}\n style={{ transform: open ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 120ms ease' }}\n />\n </div>\n </button>\n\n {open && (\n <div\n style={{\n background: theme.colors.surfaceMuted,\n border: `1px solid ${theme.colors.border}`,\n borderRadius: theme.radii.md,\n padding: '20px 22px',\n display: 'flex',\n flexDirection: 'column',\n gap: 18,\n }}\n >\n {diagnosticFields.length > 0 && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>\n {diagnosticFields.map((field) => (\n <FieldRenderer key={field.key} field={field} variant=\"compact\" />\n ))}\n </div>\n )}\n\n {leftoverFields.length > 0 && (\n <>\n <div style={{ height: 1, borderTop: `1px dashed ${theme.colors.border}` }} />\n <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>\n <span\n style={{\n fontFamily: theme.fonts.heading,\n fontSize: 10.5,\n fontWeight: 600,\n letterSpacing: '0.08em',\n textTransform: 'uppercase',\n color: theme.colors.textMuted,\n }}\n >\n Additional Fields\n </span>\n <span style={{ fontSize: 11, color: theme.colors.textMuted, opacity: 0.7 }}>\n Not in fieldRules yet — rendered generically from each value's shape\n </span>\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>\n {leftoverFields.map((field) => (\n <FieldRenderer key={field.key} field={field} variant=\"compact\" />\n ))}\n </div>\n </>\n )}\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["base","base","jsx","jsx","jsxs","React","jsx","jsxs","_a","_b","_c"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@x12i/fieldkit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Metadata-driven React components for rendering structured records as polished UI — a small toolbox of field renderers, a rules map you own, and a shape-based fallback for anything the map doesn't cover yet.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.cjs"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/x12i/fieldkit.git",
|
|
27
|
+
"directory": "packages/fieldkit"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/x12i/fieldkit#readme",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/x12i/fieldkit/issues"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"react": ">=18",
|
|
35
|
+
"react-dom": ">=18"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/react": "^18.3.5",
|
|
39
|
+
"@types/react-dom": "^18.3.0",
|
|
40
|
+
"react": "^18.3.1",
|
|
41
|
+
"react-dom": "^18.3.1",
|
|
42
|
+
"tsup": "^8.2.4",
|
|
43
|
+
"typescript": "^5.5.4"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsup",
|
|
47
|
+
"dev": "tsup --watch",
|
|
48
|
+
"typecheck": "tsc --noEmit"
|
|
49
|
+
}
|
|
50
|
+
}
|