Skip to content
HN On Hacker News ↗

declarative-forms

▲ 12 points 1 comments by WolfOliver 3d ago HN discussion ↗

Pangram verdict · v3.3

We believe that this entire text is AI.

99 %

AI likelihood · overall

AI
0% human-written 100% AI-generated
SEGMENTS · HUMAN 0 of 1
SEGMENTS · AI 1 of 1
WORD COUNT 620
PEAK AI % 99% · §1
Analyzed
Aug 21
backend: pangram/v3.3
Segments scanned
1 windows
avg 620 words each
Distribution
0 / 100%
human / AI fraction
Verdict
AI
Pangram v3.3

Article text · 620 words · 1 segments analyzed

Human AI-generated
§1 AI · 99%

tsimport 'declarative-forms/styles.css'; import { DeclarativeForm, html } from 'declarative-forms'; // Pretend this is your API. Any options function may be async. const reviewersOf = async (team) => { await new Promise((resolve) => setTimeout(resolve, 500)); return ( { design: ['Ada Lovelace', 'Grace Hopper', 'Lin Chen'], infra: ['Radia Perlman', 'Alan Turing'], }[team] ?? [] ); }; // A button in the dialog below opens this one, so it appears on top of it. // Its own list then opens a third dialog on top of that. const openSchedule = (release) => new DeclarativeForm({ fields: [ { name: 'when', kind: 'cards', displayName: 'Publish', defaultValue: 'now', cards: [ { value: 'now', content: html('<b>Immediately</b><br>on confirm') }, { value: 'at', content: html('<b>At a set time</b><br>your timezone') }, ], }, { name: 'at', type: 'datetime-local', displayName: 'Moment', isActive: ({ data }) => data['when'] === 'at', }, { name: 'freezes', kind: 'array', displayName: 'Never publish during', newButtonLabel: 'Add window', of: [ { name: 'reason', displayName: 'Reason', placeholder: 'Conference' }, { name: 'until', type: 'date', displayName: 'Until' }, ], renderEntry: (entry) => `${entry['reason']} — until ${entry['until']}`, isValidRecord: (entry) => Boolean(entry['reason'] && entry['until']), suggested: [{ reason: 'Company all-hands', until: '2026-09-01' }], }, { name: 'recap', kind: 'message', // The values of every open dialog, outermost first. message: ({ data, stackData }) => html(`Publishing <b>${stackData[0]['title'] || 'this release'}</b> ${data['when'] === 'now' ? 'as soon as you confirm' : 'later'}.`), }, ], buttons: { Apply: { id: 'apply', action: (values) => { const at = values['when'] === 'now' ? 'Immediately' : values['at']; release.field('publishAt').setValue(at); void release.update(); }, }, }, onCancel: () => {}, }).openInModal(); const release = new DeclarativeForm({ fields: [ // `tab` groups fields. The tab bar builds itself, and hides a tab when // none of its fields is active. { name: 'title', displayName: 'Release title', tab: 'Notes', placeholder: 'Sunrise 2.0', tooltip: 'Shown at the top of the changelog', }, { name: 'notes', kind: 'textarea', displayName: 'What changed', tab: 'Notes' }, { // Derived, and never shown. Recalculated before any button action runs. // Watch `slug` in the values panel above. name: 'slug', kind: 'computed', compute: ({ data }) => '/releases/' + String(data['title'] || 'untitled') .toLowerCase() .replace(/[^a-z0-9]+/g, '-'), }, { name: 'publishAt', displayName: 'Publish at', tab: 'Notes', defaultValue: 'Immediately', }, { name: 'visibility', kind: 'select', displayName: 'Visible to', tab: 'Audience', defaultValue: 'team', options: [ { value: 'team', label: 'One team' }, { value: 'company', label: 'Everyone here' }, { value: 'public', label: 'The public' }, ], }, { name: 'team', kind: 'select', displayName: 'Which team', tab: 'Audience', defaultValue: 'design', options: [ { value: 'design', label: 'Design' }, { value: 'infra', label: 'Infrastructure' }, ], // A hidden field disappears from getValues() completely. isActive: ({ data }) => data['visibility'] === 'team', }, { name: 'reviewers', kind: 'select', multiple: true, displayName: 'Sign-off from', tab: 'Audience', isActive: ({ data }) => data['visibility'] === 'team', reloadOnChangeOf: ['team'], // reloads, and ignores out-of-date answers options: ({ data }) => reviewersOf(data['team']), }, { name: 'announce', kind: 'checkbox', tab: 'Audience', label: 'Post to #releases when it goes live', }, { name: 'credits', kind: 'array', displayName: 'Credits', tab: 'Credits', newButtonLabel: 'Add person', of: [ { name: 'who', displayName: 'Name' }, { name: 'role', kind: 'select', displayName: 'Role', options: ['Author', 'Reviewer', 'Release manager'], defaultValue: 'Author', }, ], renderEntry: (entry) => `${entry['who']} — ${entry['role']}`, isValidRecord: (entry) => String(entry['who'] ?? '').trim() !== '', suggested: [{ who: 'Ada Lovelace', role: 'Author' }], }, ], buttons: { Publish: { id: 'publish', // The button stays disabled until this returns true. May be async. isActive: ({ data }) => Boolean(data['title']) && data['credits']?.length > 0, action: (values) => console.log(values), }, 'Schedule…': { id: 'schedule', class: 'secondary', doNotCloseModal: true, // this dialog stays open underneath action: () => openSchedule(release), }, }, onCancel: () => {}, }); release.openInModal();