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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions packages/json-render-ui/src/JsonRender.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ export const Gallery = story({
elements: {
root: { type: 'Stack', props: { gap: 12 }, children: ['title', 'row', 'card', 'progress', 'table', 'tree'] },
title: { type: 'Text', props: { text: 'JSON-render gallery', variant: 'heading' }, children: [] },
row: { type: 'Stack', props: { direction: 'row', gap: 8 }, children: ['b1', 'b2', 'badge'] },
row: { type: 'Stack', props: { direction: 'row', gap: 8, wrap: true }, children: ['b1', 'b2', 'b3', 'b4', 'badge'] },
b1: { type: 'Button', props: { label: 'Primary', variant: 'primary' }, children: [] },
b2: { type: 'Button', props: { label: 'Ghost', variant: 'ghost', icon: 'plus' }, children: [] },
b2: { type: 'Button', props: { label: 'Secondary', variant: 'secondary' }, children: [] },
b3: { type: 'Button', props: { label: 'Ghost', variant: 'ghost', icon: 'ph:plus' }, children: [] },
b4: { type: 'Button', props: { label: 'Danger', variant: 'danger' }, children: [] },
badge: { type: 'Badge', props: { text: 'success', variant: 'success' }, children: [] },
card: { type: 'Card', props: { title: 'Details', collapsible: true }, children: ['kv'] },
kv: { type: 'KeyValueTable', props: { data: { name: 'devframe', version: '0.7.5' } }, children: [] },
Expand All @@ -49,6 +51,20 @@ export const Controls = story({
state: { name: '', enabled: true },
})

export const ComponentSurfaces = story({
root: 'root',
elements: {
root: { type: 'Stack', props: { gap: 12 }, children: ['openCard', 'collapsedCard', 'table'] },
openCard: { type: 'Card', props: { title: 'Raised panel', collapsible: true }, children: ['input', 'code', 'inlineCode'] },
input: { type: 'TextInput', props: { label: 'Sunken input', value: 'devframe' }, children: [] },
code: { type: 'CodeBlock', props: { filename: 'panel.ts', language: 'ts', code: 'export const material = "sunken"' }, children: [] },
inlineCode: { type: 'Text', props: { text: 'bg-panel-sunken', variant: 'code' }, children: [] },
collapsedCard: { type: 'Card', props: { title: 'Collapsed panel', collapsible: true, defaultCollapsed: true }, children: ['collapsedText'] },
collapsedText: { type: 'Text', props: { text: 'Hidden until expanded.' }, children: [] },
table: { type: 'DataTable', props: { rows: [{ layer: 'raised', alpha: '13%' }, { layer: 'sunken', alpha: '5%' }] }, children: [] },
},
})

export const Loading: StoryObj = story({ root: 'a', elements: { a: { type: 'Text', props: {}, children: [] } } }, { loading: true })

export const ConnectionError: StoryObj = story(
Expand Down
6 changes: 5 additions & 1 deletion packages/json-render-ui/src/components/Button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ export const Button: JrComponent<ButtonProps> = ({ props, on }) => {
ActionButton,
{
variant: buttonVariant[variant] ?? 'action',
size: 'sm',
disabled: props.disabled,
loading: props.loading,
// `danger` isn't an ActionButton variant — override the primary tint.
class: variant === 'danger' ? 'bg-red! color-white! border-red! hover:bg-red/90!' : undefined,
class: [
'h-8 px-2.5!',
variant === 'danger' ? 'bg-red! color-white! border-red! hover:bg-red/90!' : undefined,
],
onClick: () => on('press').emit(),
},
// Render the dynamic Icon in the slot (ActionButton's own `icon` prop is a
Expand Down
8 changes: 4 additions & 4 deletions packages/json-render-ui/src/components/Card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ export const Card: JrComponent<CardProps> = ({ props, children, loading }) => {
: (children as any)

if (props.collapsible) {
return h(LayoutCard, { padding: false }, () => h('details', { open: !props.defaultCollapsed }, [
h('summary', { class: `${headerClass} cursor-pointer select-none list-none` }, [
return h(LayoutCard, { padding: false, class: 'bg-panel-raised!' }, () => h('details', { class: 'group', open: !props.defaultCollapsed }, [
h('summary', { class: `${headerClass} cursor-pointer select-none list-none [&::-webkit-details-marker]:hidden` }, [
h('span', props.title ?? ''),
h('span', { class: 'color-faint text-xs' }, '▾'),
h('span', { 'class': 'i-ph:caret-right size-4 shrink-0 color-muted transition-transform group-open:rotate-90', 'aria-hidden': 'true' }),
]),
h('div', { class: 'p4' }, [body]),
]))
}

return h(LayoutCard, { padding: false }, () => [
return h(LayoutCard, { padding: false, class: 'bg-panel-raised!' }, () => [
props.title ? h('div', { class: headerClass }, props.title) : null,
h('div', { class: 'p4' }, [body]),
])
Expand Down
4 changes: 2 additions & 2 deletions packages/json-render-ui/src/components/CodeBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ interface CodeBlockProps {

export const CodeBlock: JrComponent<CodeBlockProps> = ({ props }) => {
const header = props.filename || props.language
? h('div', { class: 'flex items-center justify-between px2 py1 border-b border-base bg-secondary text-xs color-faint' }, [
? h('div', { class: 'flex items-center justify-between px2 py1 border-b border-base bg-panel-raised text-xs color-faint' }, [
h('span', props.filename ?? ''),
props.language ? h('span', { class: 'font-mono uppercase' }, props.language) : null,
])
: null
const preStyle = props.height != null ? { maxHeight: `${props.height}px` } : undefined
return h('div', { 'class': 'rounded border border-base overflow-hidden bg-base', 'data-language': props.language }, [
return h('div', { 'class': 'rounded border border-base overflow-hidden bg-panel-sunken', 'data-language': props.language }, [
header,
h(
'pre',
Expand Down
6 changes: 3 additions & 3 deletions packages/json-render-ui/src/components/DataTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ export const DataTable: JrComponent<DataTableProps> = ({ props, on, bindings, lo
const [, setSelected] = useBoundProp<unknown>(undefined, bindings?.value)
const wrapperStyle = props.height != null ? { maxHeight: `${props.height}px` } : undefined

return h('div', { class: 'rounded border border-base overflow-auto', style: wrapperStyle }, [
return h('div', { class: 'rounded border border-base overflow-auto bg-panel-sunken', style: wrapperStyle }, [
h('table', { class: 'w-full text-sm border-collapse' }, [
h('thead', { class: 'sticky top-0 bg-secondary' }, [
h('thead', { class: 'sticky top-0 bg-panel-raised' }, [
h('tr', columns.map(col =>
h('th', { class: 'text-left px2 py1.5 color-muted font-medium border-b border-base' }, col.label ?? col.key))),
]),
h('tbody', rows.map((row, index) =>
h('tr', {
class: 'border-b border-base hover:bg-secondary cursor-pointer',
class: 'border-b border-base hover:bg-panel-raised cursor-pointer',
onClick: () => {
// Deliver row + index into bound state, then fire the action.
setSelected({ row, index })
Expand Down
2 changes: 1 addition & 1 deletion packages/json-render-ui/src/components/Text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const textVariant: Record<string, { tag: string, class: string }> = {
subheading: { tag: 'h3', class: 'text-base font-medium' },
body: { tag: 'p', class: 'text-sm' },
caption: { tag: 'span', class: 'text-xs color-faint' },
code: { tag: 'code', class: 'text-sm font-mono bg-secondary rounded px1 py0.5' },
code: { tag: 'code', class: 'text-sm font-mono bg-panel-sunken rounded px1 py0.5' },
}

const colorClass: Record<string, string> = {
Expand Down
1 change: 1 addition & 0 deletions packages/json-render-ui/src/components/TextInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const TextInput: JrComponent<TextInputProps> = ({ props, on, bindings })
'placeholder': props.placeholder,
'type': props.type ?? 'text',
'disabled': props.disabled || props.loading,
'class': 'bg-panel-sunken!',
})
if (props.label) {
return h('label', { class: 'flex flex-col gap-1 text-sm color-muted' }, [
Expand Down
2 changes: 1 addition & 1 deletion packages/json-render-ui/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export const JsonRenderView = defineComponent({

const staticNote = !props.interactive
? h('div', {
class: 'rounded border border-base bg-secondary color-faint text-xs px2 py1 mb2',
class: 'rounded border border-base bg-panel-raised color-faint text-xs px2 py1 mb2',
}, 'Interactive actions are unavailable in static output.')
: null

Expand Down
2 changes: 2 additions & 0 deletions packages/json-render-ui/src/spa/uno.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export default defineConfig({
// classes need safelisting.
safelist: ['badge-color-green', 'badge-color-amber', 'badge-color-red', 'badge-color-blue'],
shortcuts: {
'bg-panel-raised': 'bg-hover',
'bg-panel-sunken': 'bg-code',
'z-nav': 'z-[30]',
'z-dropdown': 'z-[40]',
'z-tooltip': 'z-[45]',
Expand Down
2 changes: 2 additions & 0 deletions packages/json-render-ui/uno.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export default defineConfig({
// shadow-root surface/text tokens.
safelist: [...shadowSurfaceSafelist, 'badge-color-green', 'badge-color-amber', 'badge-color-red', 'badge-color-blue'],
shortcuts: {
'bg-panel-raised': 'bg-hover',
'bg-panel-sunken': 'bg-code',
Comment thread
dvcolomban marked this conversation as resolved.
'z-nav': 'z-[30]',
'z-dropdown': 'z-[40]',
'z-tooltip': 'z-[45]',
Expand Down
Loading