@redvars/peacock
v4.2.1
Published
The foundation for beautiful user interfaces
Maintainers
Readme
Peacock
The foundation for beautiful user interfaces.
Peacock gives you the tools and foundation to build beautiful, usable product interfaces. It’s the system you use to craft your own component library.
What is Peacock?
Peacock is more than just a collection of components; it is an aesthetic philosophy. Like its avian namesake, it provides the core elements (the primitives) that allow the full, vibrant display (the design) to be unveiled.
Opinionated Beauty: We deliver pre-styled, beautiful components that follow modern design trends, significantly reducing the boilerplate needed to achieve a professional look.
Foundation First: Similar to projects like shadcn/ui, Peacock focuses on providing the foundational primitives, ensuring maximum flexibility for customization without sacrificing initial polish.
Works in any framework: The components are custom elements, so they work in plain HTML and every framework. React, Vue and Angular get packages with typed components and two-way binding (see Frameworks).
Key Features
Vibrant & Consistent Design System: Every component—from buttons and cards to complex data tables—shares a cohesive, high-quality visual language.
Highly Extensible: The component structure is designed for easy overwriting and theme customization, allowing you to quickly adapt the style to your specific brand identity.
Built for Accessibility: Focus on semantic HTML and proper ARIA attributes to ensure that your beautiful interfaces are accessible to all users.
Responsive by Default: Components are built with responsiveness baked in, guaranteeing a graceful display across all screen sizes and devices.
Documentation
Visit https://peacock.redvars.com to view the documentation.
Getting Started
<head>
<!-- Default font : Noto Sans and Noto Sans Mono -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:[email protected]&family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@redvars/[email protected]/dist/assets/styles.css"></link>
<script type='module'
src='https://cdn.jsdelivr.net/npm/@redvars/[email protected]/dist/loader.js'></script>
</head>
<wc-button>Button</wc-button>Frameworks
Each framework package is generated from custom-elements.json. It has typed props and events, two-way binding on fields and toggles, and it registers the elements you import, so no loader.js is needed:
| Package | Framework | Two-way binding |
|:--|:--|:--|
| @redvars/peacock-react | React 18 and 19 | value / checked with onInput / onChange |
| @redvars/peacock-vue | Vue 3.3+ | v-model |
| @redvars/peacock-angular | Angular 17+ | ngModel, formControl, formControlName |
npm install @redvars/peacock @redvars/peacock-reactimport '@redvars/peacock/styles.css';
import { Button, Input } from '@redvars/peacock-react';
<Input label="Name" value={name} onInput={event => setName(event.detail.value)} />See peacock.redvars.com/frameworks for each framework.
Icons without the CDN
loader.js fetches icons from cdn.jsdelivr.net. For a page that must stay on its own origin, such as an intranet or a page whose content security policy allows only connect-src 'self', serve the package's dist/ folder yourself and load loader-full.js instead. It loads the same components, and fetches Material Symbols from the copy it ships in dist/icons/material-symbols/:
<script type='module' src='/assets/peacock/dist/loader-full.js'></script>To keep icons somewhere else, call setIconBase('material-symbols', '/my/icons/') before the first icon renders; the folder holds one <name>.svg per icon.
wc-code-editor stays on the origin too: Monaco is bundled in the package and loaded when the first editor appears, and its language workers are dist/monaco/*.worker.js, which the page loads from beside the component. Serve the whole dist/ folder.
Translating Peacock's own text
Components render some text of their own: icon-button labels, screen-reader text, empty states, "3 selected". Every string has an English default, and setPeacockStrings replaces them for the whole page. Entries you leave out stay English, a string with values is a function, and connected components re-render.
import { setPeacockStrings } from 'https://cdn.jsdelivr.net/npm/@redvars/[email protected]/dist/loader.js';
setPeacockStrings({
dismiss: 'Fermer',
noItems: 'Aucun élément',
selectedCount: count => `${count} sélectionné(s)`,
});defaultStrings lists every key. Components that render many strings (table, pagination, select, date picker, calendar, charts, code and rich-text editors, condition builder) also take a strings property that overrides the page's strings for that one instance.
Numbers and dates are formatted with Intl in a locale resolved per component: its locale property, else the lang of the nearest ancestor (across shadow roots), else <html lang>, else the browser's language.
AI: an assistant inside your app
Peacock has components for an assistant that works inside your pages: summaries that cite their sources, a chat panel, suggested values and drafts the person confirms, and answers shown as charts and tables (see AI below). Peacock never calls a model. Components show the AI state your app passes in, such as a field's suggestion or a summary's streamed value, and the few features that ask for text (ghost text, rewriting a selection, a sentence turned into filters) call one provider you register:
import { setPeacockAi } from 'https://cdn.jsdelivr.net/npm/@redvars/[email protected]/dist/loader.js';
setPeacockAi({
provider: {
// Each method is optional; a feature appears only when its method is there. `transform` and
// `summarize` return an async iterable of text chunks. Every request carries an AbortSignal.
complete: ({ before, after, signal }) => myModel.complete(before, after, { signal }), // ghost text: a string or null
transform: ({ action, text, instruction, signal }) => myModel.stream(action, text, instruction, { signal }), // rewrites
summarize: ({ kind, text, signal }) => myModel.stream('summarize', text, kind, { signal }),
parse: ({ target, text, schema, signal }) => myModel.json(target, text, schema, { signal }), // filters, conditions
},
});setPeacockAi({ enabled: false })turns AI off for the page: every marker, button and menu entry that refers to the assistant disappears, and each page still works.features: { summarize: false }turns off one capability, andno-aiturns it off for one element.- Everything the assistant wrote is marked with
wc-ai-badgeand can show why. Writes are drafts: a suggested value is filled in and marked until the person edits or submits it, ghost text needs Tab, a rewrite needs Accept, and awc-draft-cardneeds Confirm. - A field with
sensitiveis never sent to the provider, and password and PIN fields never are. - Model text is never run or parsed as HTML: it shows through
wc-markdownorwc-generative-view, which renders only an allow-listed set of components and props.generativeViewSchema()returns that set as a JSON Schema for your model service.
ADR-030002 records the decisions.
Forms and validation
Fields and toggles are form-associated and validate like native controls: required and each control's own rules (email, min/max, unreadable dates) block form submission, :invalid matches, and checkValidity(), reportValidity(), setCustomValidity(), validity and validationMessage work as on <input>. A field shows its message once the value is committed or the form is submitted. Fields fire input and change as CustomEvent<{ value }>; checkboxes, switches and radios fire change with { checked, value }. Fields default to size="sm", the height of a default button.
Right to left
Set dir="rtl" on the page or any container. Components lay out with logical CSS properties, so they mirror; npm run lint:css rejects physical left/right properties in component styles.
Density
Set data-density="comfortable" or "compact" on the page or any container (it needs styles.css). Each step takes 4px off the height of buttons, icon buttons, fields and table rows inside it.
High contrast
In Windows high contrast (forced-colors: active), selected and current items are outlined in the system highlight color, and checkboxes, radios, switches and the tab indicator are drawn with system colors.
Loader options
loader.js?stylesalso loadsstyles.css.loader.jswrapsElement.prototype.attachShadowonce, so Peacock components rendered inside any shadow root load automatically. To leaveattachShadowalone, loadloader.js?no-shadow-watchand callloadComponents(shadowRoot)(exported fromloader.js) for each shadow root that contains Peacock components.- If a
wc-*tag is already defined by other code, for example a second copy of Peacock, the loader keeps that definition and logs one warning.
Components
Every component below ships in 4.0, except the AI group, which arrives in the next release. Each name links to its page on peacock.redvars.com, with live demos and the API reference. Upgrading from 3.x? Read the migration guide.
Layout and app shell
App shell wc-app-shell ·
App bar wc-app-bar ·
Page header wc-page-header ·
Container wc-container ·
Stack wc-stack ·
Grid wc-grid ·
Card wc-card ·
Accordion wc-accordion ·
Resizable panels wc-resizable-panels ·
Scroll area wc-scroll-area ·
Divider wc-divider
Buttons
Button wc-button ·
Link button wc-link-button ·
Icon button wc-icon-button ·
FAB wc-fab ·
Button group wc-button-group ·
Dropdown button wc-dropdown-button ·
Split button wc-split-button ·
Segmented button wc-segmented-button-group ·
Copy button wc-copy-button
Navigation
Navigation drawer wc-navigation-drawer ·
Navigation rail wc-navigation-rail ·
Navigation bar wc-navigation-bar ·
Breadcrumb wc-breadcrumb ·
Tabs wc-tabs ·
Pagination wc-pagination ·
Stepper wc-stepper ·
Anchor nav wc-anchor-nav ·
Toolbar wc-toolbar ·
Menu wc-menu ·
Command palette wc-command-palette ·
Workspace switcher wc-workspace-switcher ·
User menu wc-user-menu ·
Link wc-link
Text inputs
Input wc-input ·
Password field wc-password-field ·
Password rules wc-password-rules ·
Number field wc-number-field ·
Currency field wc-currency-field ·
Phone field wc-phone-field ·
URL field wc-url-field ·
Textarea wc-textarea ·
Mention input wc-mention-input ·
PIN input wc-pin-input ·
Search wc-search ·
Inline edit wc-inline-edit
Selection
Select wc-select ·
Listbox wc-listbox ·
Checkbox wc-checkbox ·
Checkbox group wc-checkbox-group ·
Radio wc-radio, wc-radio-group ·
Switch wc-switch ·
Slider wc-slider ·
Rating wc-rating ·
Chip set wc-chip-set ·
Transfer list wc-transfer-list ·
Tree wc-tree
Date and time
Date field wc-date-field ·
Date range field wc-date-range-field ·
Date picker wc-date-picker ·
Time field wc-time-field ·
Time picker wc-time-picker ·
Date time field wc-datetime-field ·
Calendar wc-calendar ·
Clock wc-clock ·
Relative time wc-relative-time
Forms
Form wc-form ·
Fieldset wc-fieldset ·
Field wc-field ·
File upload wc-file-upload ·
Signature pad wc-signature-pad ·
Color field wc-color-field ·
Color picker wc-color-picker ·
Condition builder wc-condition-builder ·
Filter bar wc-filter-bar
Data display
Table wc-table ·
List wc-list ·
Virtual list wc-virtual-list ·
Description list wc-description-list ·
Stat wc-stat ·
Sparkline wc-sparkline ·
Kanban wc-kanban ·
Timeline wc-timeline ·
JSON viewer wc-json-viewer ·
Diff viewer wc-diff-viewer ·
Code highlighter wc-code-highlighter ·
Number counter wc-number-counter ·
Image wc-image ·
SVG wc-svg ·
Icon wc-icon ·
Keyboard key wc-kbd
Charts
Area wc-chart-area ·
Bar wc-chart-bar ·
Line wc-chart-line ·
Pie wc-chart-pie ·
Doughnut wc-chart-doughnut
People and status
Avatar wc-avatar ·
Avatar group wc-avatar-group ·
Presence indicator wc-presence-indicator ·
Badge wc-badge ·
Tag wc-tag ·
Chip wc-chip ·
Status indicator wc-status-indicator ·
Discussion wc-discussion
Feedback
Alert wc-alert ·
Banner wc-banner ·
Snackbar wc-snackbar ·
Notification manager wc-notification-manager ·
Notification center wc-notification-center ·
Illustration wc-illustration ·
Skeleton wc-skeleton ·
Circular progress wc-circular-progress ·
Linear progress wc-linear-progress ·
Redvars loader wc-redvars-loader
Overlays
Modal wc-modal ·
Confirm dialog wc-confirm-dialog ·
Side sheet wc-side-sheet ·
Bottom sheet wc-bottom-sheet ·
Popover wc-popover ·
Tooltip wc-tooltip ·
Hover card wc-hover-card ·
Tour wc-tour
Editors
Code editor wc-code-editor ·
HTML editor wc-html-editor ·
Markdown editor wc-markdown-editor ·
Markdown wc-markdown ·
Comment composer wc-comment-composer ·
Document editor wc-document-editor ·
Diagram wc-diagram
AI
AI badge wc-ai-badge ·
AI summary wc-ai-summary ·
Assistant panel wc-assistant-panel ·
Chat thread wc-chat-thread ·
Chat message wc-chat-message ·
Prompt input wc-prompt-input ·
Assistant steps wc-assistant-steps ·
Draft card wc-draft-card ·
Generative view wc-generative-view ·
Citation wc-citation ·
Typing indicator wc-typing-indicator
Existing components gain AI features too: suggested values on every field and suggest() on wc-form, ghost text in wc-textarea, the rich-text editors and wc-code-editor, Ask in wc-search and wc-command-palette, filters and conditions from a sentence in wc-filter-bar and wc-condition-builder, and summary and insight slots in wc-discussion, wc-notification-center, wc-stat and the charts.
Primitives
Ripple wc-ripple ·
Elevation wc-elevation ·
Focus ring wc-focus-ring
📄 License
Peacock is open-source software licensed under the Apache-2.0 License.
Made with 💖 by Redvars.
