Improve accessibility across layouts, components, and forms (#2799)

This commit is contained in:
Paweł Kuna authored and GitHub committed 2026-08-05 23:40:37 +02:00
1 parent 17d2363ef2
commit 1effe221cb
160 files changed
+1494 -1092

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
---
"@tabler/preview": patch
---
Converted `<a href="#">` controls that only trigger JavaScript (dropdown toggles, toast dismiss, modal and carousel controls) into real `<button>` elements so they work with the keyboard, and removed `tabindex="-1"` from navbar toggles and links that were wrongly skipped when tabbing.
+5
View File
@@ -0,0 +1,5 @@
---
"@tabler/preview": patch
---
Added missing ARIA roles and states to `Pagination`, `NavSegmented`, `Accordion`, `Steps`, tab components, `Modal`, `Offcanvas` and `CarouselCard`, including `aria-current`, `aria-controls`, `aria-labelledby`, `aria-modal` and `role="tabpanel"`, and fixed a bug where the active `Steps` index was never highlighted because it compared a string prop to a number.
@@ -0,0 +1,5 @@
---
"@tabler/core": patch
---
Fixed keyboard focus indicators that were invisible or removed on `.btn-action`, `.switch-icon`, calendar dates and the toast close button, added `prefers-reduced-motion` and `forced-colors` support, stopped overriding the browser's default root font size, and enlarged the `.btn-close` touch target to `24px`.
+5
View File
@@ -0,0 +1,5 @@
---
"@tabler/preview": patch
---
Added `aria-label` to the `Datepicker` month-navigation buttons and made the `Dropzone` upload area keyboard-operable with `role="button"`, `tabindex="0"` and an `Enter`/`Space` handler.
@@ -0,0 +1,5 @@
---
"@tabler/preview": patch
---
Wrapped radio and checkbox groups in form demos, `ThemeSettings`, `onboarding` and modal content with `<fieldset>` and `<legend>` so screen readers announce the group's purpose before each option.
@@ -0,0 +1,5 @@
---
"@tabler/preview": patch
---
Wired every form label to its control with matching `for`/`id` pairs, added `aria-invalid` and `aria-describedby` to validation demos, added correct `autocomplete` tokens to auth and payment forms, and gave the password show/hide toggle in `InputGroup` a working `aria-pressed` state.
+6
View File
@@ -0,0 +1,6 @@
---
"@tabler/preview": patch
"@tabler/docs": patch
---
Fixed the "Skip to main content" link so it becomes visible on keyboard focus, added missing `<main>` landmarks to layouts that had none, gave the sidebar and docs navigation `<nav aria-label>` landmarks instead of unlabeled `<div>`s, and fixed heading hierarchy and duplicate page `<title>`s across several preview pages.
@@ -0,0 +1,5 @@
---
"@tabler/preview": patch
---
Added a `label` prop to `Flag`, `Payment`, `StatusDot`, `Trending` and the `Avatar` status badge so color-only indicators get a real accessible name, added `role="img"` and `aria-label` to `Chart`, `Map` and `MapVector` containers, and made the `label` prop on `Chart` required.
+2 -1
View File
@@ -7,7 +7,8 @@ switchesTriggerList.map(function (switchTriggerEl: HTMLElement) {
switchTriggerEl.addEventListener('click', (e: MouseEvent) => {
e.stopPropagation()
switchTriggerEl.classList.toggle('active')
const active = switchTriggerEl.classList.toggle('active')
switchTriggerEl.setAttribute('aria-pressed', active ? 'true' : 'false')
})
})
// js-docs-end switch-icon-init
+1
View File
@@ -41,6 +41,7 @@
@forward 'layout/page';
@forward 'layout/footer';
@forward 'layout/dark';
@forward 'layout/accessibility';
@forward 'ui/accordion';
@forward 'ui/alerts';
+5 -1
View File
@@ -1014,7 +1014,11 @@ $focus-ring-width: 0.25rem !default;
$focus-ring-opacity: 0.25 !default;
$focus-ring-color: color-mix(in srgb, var(--#{$prefix}primary) #{math.percentage($focus-ring-opacity)}, transparent) !default;
$focus-ring-blur: 0 !default;
$focus-ring-box-shadow: 0 0 $focus-ring-blur $focus-ring-width $focus-ring-color !default;
// Inner 2px solid ring keeps the indicator above the 3:1 non-text contrast minimum;
// the translucent halo preserves the soft look
$focus-ring-box-shadow:
0 0 0 2px var(--#{$prefix}primary),
0 0 $focus-ring-blur $focus-ring-width $focus-ring-color !default;
// Transitions
$transition-base: all 0.2s ease-in-out !default;
+42
View File
@@ -0,0 +1,42 @@
@use '../config' as *;
// Forced-colors (Windows High Contrast) support: the UA strips box-shadow there,
// and Tabler's focus indicator is shadow-based, so restore an outline-drawn one.
@media (forced-colors: active) {
:focus-visible {
outline: 2px solid Highlight;
outline-offset: 2px;
}
// .btn-close is drawn with a mask + background-color and would disappear
.btn-close {
forced-color-adjust: none;
}
}
@media (prefers-reduced-motion: reduce) {
// Decorative looping animations are dropped entirely
.badge-blink,
.status-dot-animated::before,
.status-indicator-animated .status-indicator-circle,
.icon-pulse,
.icon-tada,
.icon-rotate,
.card-gradient-animated,
.btn-animate-icon-pulse .icon,
.btn-animate-icon-shake .icon,
.btn-animate-icon-tada .icon,
.wave-1,
.wave-2,
.wave-3 {
animation: none !important;
}
// Loading indicators still convey state, so slow them down instead of stopping
.loader::after,
.btn-loading::after,
.progress-bar-indeterminate::before,
.animated-dots::after {
animation-duration: 3s !important;
}
}
+17
View File
@@ -1,5 +1,22 @@
@use '../config' as *;
// Skip-to-content link: hidden via .visually-hidden-focusable until keyboard focus reveals it
.skip-link {
position: fixed;
top: 0;
inset-inline-start: 0;
z-index: $zindex-tooltip;
padding: 0.5rem 1rem;
background: var(--#{$prefix}primary);
color: var(--#{$prefix}primary-fg, #fff);
text-decoration: none;
&:focus-visible {
outline: 2px solid var(--#{$prefix}primary);
outline-offset: 2px;
}
}
.page {
display: flex;
flex-direction: column;
+1 -1
View File
@@ -2,7 +2,7 @@
:root,
:host {
font-size: 16px;
// No fixed root font-size: rem sizing must track the user's browser preference (WCAG 1.4.4)
height: 100%;
}
+3 -1
View File
@@ -67,7 +67,9 @@
@mixin focus-ring($show-border: false) {
outline: 0;
box-shadow: 0 0 $focus-ring-blur $focus-ring-width color-transparent(var(--#{$prefix}primary), 0.25);
box-shadow:
0 0 0 2px var(--#{$prefix}primary),
0 0 $focus-ring-blur $focus-ring-width color-transparent(var(--#{$prefix}primary), 0.25);
@if ($show-border) {
border-color: color-transparent(var(--#{$prefix}primary), 0.25);
+6 -2
View File
@@ -113,7 +113,9 @@
@include expect() {
.t {
outline: 0;
box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--tblr-primary) 25%, transparent);
box-shadow:
0 0 0 2px var(--tblr-primary),
0 0 0 0.25rem color-mix(in srgb, var(--tblr-primary) 25%, transparent);
}
}
}
@@ -129,7 +131,9 @@
@include expect() {
.t {
outline: 0;
box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--tblr-primary) 25%, transparent);
box-shadow:
0 0 0 2px var(--tblr-primary),
0 0 0 0.25rem color-mix(in srgb, var(--tblr-primary) 25%, transparent);
border-color: color-mix(in srgb, var(--tblr-primary) 25%, transparent);
}
}
+7 -1
View File
@@ -278,11 +278,17 @@
content: none;
}
&:focus {
&:focus:not(:focus-visible) {
outline: none;
box-shadow: none;
}
&:focus-visible {
outline: 2px solid var(--#{$prefix}primary);
outline-offset: -2px;
box-shadow: none;
}
&:hover,
&.show {
color: var(--#{$prefix}body-color);
+5 -1
View File
@@ -59,7 +59,6 @@
background: 0 0;
border: var(--#{$prefix}border-width) var(--#{$prefix}border-style) transparent;
@include border-radius(var(--#{$prefix}border-radius-pill));
outline: 0;
@include transition(background $transition-time, border $transition-time, box-shadow 0.32s, color $transition-time);
&:hover {
@@ -68,6 +67,11 @@
background: #fefeff;
border-color: var(--#{$prefix}border-color);
}
&:focus-visible {
outline: 2px solid var(--#{$prefix}primary);
outline-offset: 2px;
}
}
.date-today {
+12
View File
@@ -21,6 +21,18 @@
opacity: var(--#{$prefix}btn-close-opacity);
cursor: pointer;
display: block;
position: relative;
// Invisible overlay extending the hit area to a 24x24px minimum touch target
&:before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: max(100%, 24px);
height: max(100%, 24px);
transform: translate(-50%, -50%);
}
&:hover {
color: var(--#{$prefix}btn-close-color);
+6 -1
View File
@@ -17,10 +17,15 @@
opacity: $btn-disabled-opacity;
}
&:focus {
&:focus:not(:focus-visible) {
outline: none;
}
&:focus-visible {
outline: 2px solid var(--#{$prefix}primary);
outline-offset: 2px;
}
svg {
display: block;
width: 100%;
+3 -1
View File
@@ -10,7 +10,9 @@
button[data-bs-dismiss='toast'],
button[data-dismiss='toast'] {
outline: none;
&:focus:not(:focus-visible) {
outline: none;
}
}
@include media-print {
+8 -6
View File
@@ -28,13 +28,13 @@ const menu = docs.menu as MenuSection[]
---
<!-- BEGIN DOCS MENU -->
<nav class="space-y space-y-5" id="menu">
<nav class="space-y space-y-5" id="menu" aria-label="Documentation">
{
menu.map((level1) => (
<div>
<Subheader class="mb-2">{level1.title}</Subheader>
{level1.children && level1.children.length > 0 && (
<nav class="nav nav-vertical">
<div class="nav nav-vertical">
{level1.children.map((level2) => {
const hasChildren = Boolean(level2.children && level2.children.length > 0)
// Expanded only for the group's own page or one of its direct children —
@@ -48,11 +48,13 @@ const menu = docs.menu as MenuSection[]
{level2.title} <span class="nav-link-toggle" />
</a>
) : (
<a class={`nav-link${expanded ? ' active' : ''}`}>{level2.title}</a>
<a class={`nav-link${expanded ? ' active' : ''}`} href={level2.url}>
{level2.title}
</a>
)}
{hasChildren && (
<nav class={`nav nav-vertical collapse${expanded ? ' show' : ''}`} id={`collapse-${slug(level2.url)}`}>
<div class={`nav nav-vertical collapse${expanded ? ' show' : ''}`} id={`collapse-${slug(level2.url)}`}>
{level2.children!.map((level3) => (
<div>
<a class={`nav-link${url === level3.url ? ' active' : ''}`} href={level3.url}>
@@ -60,12 +62,12 @@ const menu = docs.menu as MenuSection[]
</a>
</div>
))}
</nav>
</div>
)}
</div>
)
})}
</nav>
</div>
)}
</div>
))
+6 -6
View File
@@ -9,7 +9,7 @@ const changelogUrl = 'https://tabler.io/changelog'
---
<!-- BEGIN DOCS NAVBAR -->
<div class="navbar navbar-expand sticky-top">
<nav class="navbar navbar-expand sticky-top" aria-label="Docs">
<div class="container">
<div class="row flex-fill align-items-md-center">
<div class="col">
@@ -28,12 +28,12 @@ const changelogUrl = 'https://tabler.io/changelog'
</div>
<div class="col d-flex">
<ul class="navbar-nav ms-auto gap-2 align-items-center">
<div class="nav-item d-none d-md-block">
<li class="nav-item d-none d-md-block">
<a href={previewUrl} class="nav-link">Preview</a>
</div>
<div class="nav-item d-none d-md-block">
</li>
<li class="nav-item d-none d-md-block">
<a href={changelogUrl} class="nav-link">Changelog</a>
</div>
</li>
<li class="nav-item hide-theme-dark">
<a href="?theme=dark" class="btn btn-icon">
<Icon name="moon" />
@@ -58,5 +58,5 @@ const changelogUrl = 'https://tabler.io/changelog'
</div>
</div>
</div>
</div>
</nav>
<!-- END DOCS NAVBAR -->
+3 -3
View File
@@ -23,14 +23,14 @@ const illustrationsCount = 100
<!-- BEGIN DOCS TOC -->{
toc.length > 0 && (
<Fragment>
<h3>Table of Contents</h3>
<div class="nav nav-vertical" id="toc">
<h3 id="toc-heading">Table of Contents</h3>
<nav class="nav nav-vertical" id="toc" aria-labelledby="toc-heading">
{toc.map((item) => (
<a href={`#${item.id}`} class={`nav-link${item.level === 3 ? ' ms-3' : ''}`}>
{item.text}
</a>
))}
</div>
</nav>
</Fragment>
)
}
+3 -2
View File
@@ -182,6 +182,7 @@ const docsLinks = docs.links as DocsLink[];
</head>
<body class="d-flex flex-column" style="background: var(--tblr-bg-surface)">
<a href="#content" class="visually-hidden-focusable skip-link">Skip to main content</a>
<!-- BEGIN GLOBAL THEME SCRIPT -->
<script is:inline src="/dist/js/tabler-theme.js"></script>
<!-- END GLOBAL THEME SCRIPT -->
@@ -198,7 +199,7 @@ const docsLinks = docs.links as DocsLink[];
<div class="col-docs d-none d-lg-block border-end">
<div class="py-4">
<div class="space-y space-y-5">
<div class="nav nav-vertical">
<nav class="nav nav-vertical" aria-label="Resources">
{
docsLinks.map((link) => (
<a href={link.url} class="nav-link" target="_blank">
@@ -209,7 +210,7 @@ const docsLinks = docs.links as DocsLink[];
</a>
))
}
</div>
</nav>
<div class="flex-fill">
<DocsMenu url={docsUrl} />
</div>
+8 -7
View File
@@ -7,7 +7,7 @@ import CaptureScript from '@shared/components/CaptureScript.astro'
---
<SingleLayout title="2-Step Verification">
<form class="card card-md" action="./" method="get" autocomplete="off" novalidate>
<form class="card card-md" action="./" method="get" novalidate>
<div class="card-body">
<h2 class="card-title card-title-lg text-center mb-4">Authenticate Your Account</h2>
@@ -15,15 +15,16 @@ import CaptureScript from '@shared/components/CaptureScript.astro'
Please confirm your account by entering the authorization code sent to <strong>+1 856-672-8552</strong>.
</p>
<div class="my-5">
<fieldset class="my-5 border-0 p-0 m-0">
<legend class="visually-hidden">Verification code</legend>
<div class="row g-4">
{
Array.from({ length: 2 }).map(() => (
Array.from({ length: 2 }).map((_, group) => (
<div class="col">
<div class="row g-2">
{Array.from({ length: 3 }).map(() => (
{Array.from({ length: 3 }).map((_, i) => (
<div class="col">
<input type="text" class="form-control form-control-lg text-center px-3 py-3" maxlength="1" inputmode="numeric" pattern="[0-9]*" data-code-input />
<input type="text" class="form-control form-control-lg text-center px-3 py-3" maxlength="1" inputmode="numeric" pattern="[0-9]*" data-code-input aria-label={`Digit ${group * 3 + i + 1}`} autocomplete={group === 0 && i === 0 ? 'one-time-code' : undefined} />
</div>
))}
</div>
@@ -31,12 +32,12 @@ import CaptureScript from '@shared/components/CaptureScript.astro'
))
}
</div>
</div>
</fieldset>
<div class="my-4">
<label class="form-check">
<input type="checkbox" class="form-check-input" />
Dont't ask for codes again on this device
Don't ask for codes again on this device
</label>
</div>
+6 -6
View File
@@ -9,20 +9,20 @@ import flags from '@data/flags.json'
---
<SingleLayout title="2-Step Verification">
<form class="card card-md" action="./2-step-verification-code.html" method="get" autocomplete="off" novalidate>
<form class="card card-md" action="./2-step-verification-code.html" method="get" novalidate>
<div class="card-body">
<h2 class="card-title text-center mb-4">2-Step Verification</h2>
<FormGroup label="Country">
<select class="form-select">
{flags.map((country) => <option value="">{country.name}</option>)}
<FormGroup label="Country" for="verify-country">
<select class="form-select" id="verify-country" autocomplete="country-name">
{flags.map((country) => <option value={country.name}>{country.name}</option>)}
</select>
</FormGroup>
<FormGroup label="Your Phone Number" class="mb-4">
<FormGroup label="Your Phone Number" for="verify-phone" class="mb-4">
<div class="input-group">
<span class="input-group-text">+1</span>
<input type="text" class="form-control" placeholder="Enter phone number" />
<input type="tel" class="form-control" id="verify-phone" placeholder="Enter phone number" autocomplete="tel-national" />
</div>
</FormGroup>
+56 -39
View File
@@ -40,6 +40,22 @@ import Empty from '@ui/Empty.astro'
import NavSegmented from '@ui/NavSegmented.astro'
import ListGroup from '@ui/ListGroup.astro'
import ListGroupItem from '@ui/ListGroupItem.astro'
import payments from '@data/payments.json'
const paymentNames = Object.fromEntries((payments as { name: string; logo: string }[]).map((p) => [p.logo, p.name]))
const countryNames: Record<string, string> = {
us: 'United States',
gb: 'United Kingdom',
de: 'Germany',
fr: 'France',
pl: 'Poland',
es: 'Spain',
it: 'Italy',
nl: 'Netherlands',
ca: 'Canada',
au: 'Australia',
}
const codeExample = `// JavaScript example
function greetUser(name) {
@@ -209,22 +225,22 @@ function greetUser(name) {
<CardBody>
<div class="row">
<div class="col-md-6">
<FormGroup label="Text Input">
<input type="text" class="form-control" placeholder="Enter text" />
<FormGroup label="Text Input" for="all-elements-text-input">
<input type="text" class="form-control" id="all-elements-text-input" placeholder="Enter text" />
</FormGroup>
<FormGroup label="Email Input">
<input type="email" class="form-control" placeholder="Enter email" />
<FormGroup label="Email Input" for="all-elements-email-input">
<input type="email" class="form-control" id="all-elements-email-input" placeholder="Enter email" />
</FormGroup>
<FormGroup label="Password Input">
<input type="password" class="form-control" placeholder="Enter password" />
<FormGroup label="Password Input" for="all-elements-password-input">
<input type="password" class="form-control" id="all-elements-password-input" placeholder="Enter password" />
</FormGroup>
<FormGroup label="Select Dropdown">
<FormGroup label="Select Dropdown" for="select-demo-select">
<Select id="demo-select" values={['Option 1', 'Option 2', 'Option 3']} />
</FormGroup>
</div>
<div class="col-md-6">
<FormGroup label="Textarea">
<textarea class="form-control" rows="3" placeholder="Enter message"></textarea>
<FormGroup label="Textarea" for="all-elements-textarea">
<textarea class="form-control" id="all-elements-textarea" rows="3" placeholder="Enter message"></textarea>
</FormGroup>
<FormGroup label="Checkboxes">
<Check title="Option 1" type="checkbox" />
@@ -234,6 +250,7 @@ function greetUser(name) {
<Check title="Option 1" type="radio" name="radio-demo" />
<Check title="Option 2" type="radio" name="radio-demo" checked />
</FormGroup>
{/* Check.astro has no id prop to target with `for`; its own <label> already wraps the input, so it's self-labeled */}
<FormGroup label="Switch">
<Check title="Enable notifications" switch />
</FormGroup>
@@ -466,10 +483,10 @@ function greetUser(name) {
<CardBody>
<h4>Status Dots</h4>
<div class="mb-3">
<StatusDot color="success" />
<StatusDot color="warning" />
<StatusDot color="danger" />
<StatusDot color="info" animated />
<StatusDot color="success" label="Success" />
<StatusDot color="warning" label="Warning" />
<StatusDot color="danger" label="Danger" />
<StatusDot color="info" animated label="Info" />
</div>
<h4>Toast Notifications</h4>
@@ -540,38 +557,38 @@ function greetUser(name) {
<h4>Flags</h4>
<div class="mb-3">
<div class="d-flex flex-wrap gap-2">
<Flag flag="us" />
<Flag flag="gb" />
<Flag flag="de" />
<Flag flag="fr" />
<Flag flag="pl" />
<Flag flag="es" />
<Flag flag="it" />
<Flag flag="nl" />
<Flag flag="ca" />
<Flag flag="au" />
<Flag flag="us" label={countryNames.us} />
<Flag flag="gb" label={countryNames.gb} />
<Flag flag="de" label={countryNames.de} />
<Flag flag="fr" label={countryNames.fr} />
<Flag flag="pl" label={countryNames.pl} />
<Flag flag="es" label={countryNames.es} />
<Flag flag="it" label={countryNames.it} />
<Flag flag="nl" label={countryNames.nl} />
<Flag flag="ca" label={countryNames.ca} />
<Flag flag="au" label={countryNames.au} />
</div>
</div>
<h4>Payment Icons</h4>
<div class="mb-3">
<div class="d-flex flex-wrap gap-2">
<Payment payment="visa" />
<Payment payment="mastercard" />
<Payment payment="paypal" />
<Payment payment="americanexpress" />
<Payment payment="applepay" />
<Payment payment="google-pay" />
<Payment payment="stripe" />
<Payment payment="discover" />
<Payment payment="jcb" />
<Payment payment="maestro" />
<Payment payment="dinersclub" />
<Payment payment="bitcoin" />
<Payment payment="ethereum" />
<Payment payment="klarna" />
<Payment payment="venmo" />
<Payment payment="square" />
<Payment payment="visa" label={paymentNames.visa} />
<Payment payment="mastercard" label={paymentNames.mastercard} />
<Payment payment="paypal" label={paymentNames.paypal} />
<Payment payment="americanexpress" label={paymentNames.americanexpress} />
<Payment payment="applepay" label={paymentNames.applepay} />
<Payment payment="google-pay" label={paymentNames['google-pay']} />
<Payment payment="stripe" label={paymentNames.stripe} />
<Payment payment="discover" label={paymentNames.discover} />
<Payment payment="jcb" label={paymentNames.jcb} />
<Payment payment="maestro" label={paymentNames.maestro} />
<Payment payment="dinersclub" label={paymentNames.dinersclub} />
<Payment payment="bitcoin" label={paymentNames.bitcoin} />
<Payment payment="ethereum" label={paymentNames.ethereum} />
<Payment payment="klarna" label={paymentNames.klarna} />
<Payment payment="venmo" label={paymentNames.venmo} />
<Payment payment="square" label={paymentNames.square} />
</div>
</div>
</CardBody>
+1
View File
@@ -5,5 +5,6 @@ import Empty from '@ui/Empty.astro'
---
<DefaultLayout title="Blank page" pageMenu="base.blank" containerCentered>
<h1 class="visually-hidden">Blank page</h1>
<Empty buttonText="Add your first client" buttonIcon="plus" illustration="computer-fix.svg" />
</DefaultLayout>
+2 -2
View File
@@ -56,7 +56,7 @@ const person3 = people[3]
<Avatar person={person0} />
</div>
<div class="col">
<div class="card-title">{person0.full_name}</div>
<h3 class="card-title">{person0.full_name}</h3>
<CardSubtitle as="div">{person0.job_title}</CardSubtitle>
</div>
</div>
@@ -106,7 +106,7 @@ const person3 = people[3]
<Avatar person={person3} />
</div>
<div class="col">
<div class="card-title">{person3.full_name}</div>
<h3 class="card-title">{person3.full_name}</h3>
<CardSubtitle as="div">{person3.job_title}</CardSubtitle>
</div>
</div>
+1 -1
View File
@@ -6,6 +6,6 @@ import changelog from '../../core/CHANGELOG.md?raw'
const changelogHtml = renderMarkdown(changelog)
---
<ProseLayout title="Changelog" pageMenu="changelog">
<ProseLayout title="Changelog" pageHeader="Changelog" pageMenu="changelog">
<Fragment set:html={changelogHtml} />
</ProseLayout>
+3 -2
View File
@@ -7,6 +7,7 @@ import Card from '@ui/Card.astro'
import CardHeader from '@ui/CardHeader.astro'
import CardBody from '@ui/CardBody.astro'
import chartsData from '@data/charts.json'
import { capitalize } from '@shared/lib/string-format'
const demoCharts = Object.entries(chartsData as Record<string, { demo?: boolean; name?: string }>).filter(([, chart]) => chart && chart.demo)
---
@@ -24,7 +25,7 @@ const demoCharts = Object.entries(chartsData as Record<string, { demo?: boolean;
<div class="col-12">
<Card>
<CardBody>
<Chart chartId="tasks-overview" height={20} />
<Chart chartId="tasks-overview" height={20} label="Tasks overview" />
</CardBody>
</Card>
</div>
@@ -35,7 +36,7 @@ const demoCharts = Object.entries(chartsData as Record<string, { demo?: boolean;
<Card>
{chart.name && <CardHeader title={chart.name} />}
<CardBody>
<Chart chartId={chartId} height={15} />
<Chart chartId={chartId} height={15} label={chart.name ?? capitalize(chartId.replace(/-/g, ' '))} />
</CardBody>
</Card>
</div>
+2 -2
View File
@@ -6,7 +6,7 @@ import CardTitle from '@ui/CardTitle.astro'
import Colorpicker from '@ui/Colorpicker.astro'
import site from '@data/site.json'
const colors = Object.values(site.colors) as { hex: string }[]
const colors = Object.values(site.colors) as { hex: string; title: string }[]
---
<DefaultLayout title="Color picker" pageHeader="Color picker" pageMenu="plugins.colorpicker" pageLibs={['coloris.js']}>
@@ -18,7 +18,7 @@ const colors = Object.values(site.colors) as { hex: string }[]
colors.map((color, index) => (
<div class="col-2">
<div>
<Colorpicker value={color.hex} id={index + 1} format="hex" />
<Colorpicker value={color.hex} id={index + 1} format="hex" ariaLabel={`${color.title} color value`} />
</div>
</div>
))
+8 -8
View File
@@ -125,13 +125,13 @@ const gradientColors = [...Object.keys(site.colors), 'inverted', 'white', 'trans
<form action="">
<div class="row g-4">
<div class="col">
<FormGroup label="From" class="">
<select class="form-select" name="color-from">
<FormGroup label="From" for="colors-gradient-from" class="">
<select class="form-select" name="color-from" id="colors-gradient-from">
{gradientColors.map((color) => <option value={color}>{color}</option>)}
</select>
</FormGroup>
<FormGroup label="To" class="mt-3">
<select class="form-select" name="color-to">
<FormGroup label="To" for="colors-gradient-to" class="mt-3">
<select class="form-select" name="color-to" id="colors-gradient-to">
{
gradientColors.map((color) => (
<option value={color} selected={color === 'transparent'}>
@@ -143,14 +143,14 @@ const gradientColors = [...Object.keys(site.colors), 'inverted', 'white', 'trans
</FormGroup>
</div>
<div class="col">
<FormGroup label="Via" class="">
<select class="form-select" name="color-via">
<FormGroup label="Via" for="colors-gradient-via" class="">
<select class="form-select" name="color-via" id="colors-gradient-via">
<option></option>
{gradientColors.map((color) => <option value={color}>{color}</option>)}
</select>
</FormGroup>
<FormGroup label="Direction" class="mt-3">
<select class="form-select" name="color-direction">
<FormGroup label="Direction" for="colors-gradient-direction" class="mt-3">
<select class="form-select" name="color-direction" id="colors-gradient-direction">
<option value="to-t">to top</option>
<option value="to-te">to top right</option>
<option value="to-r" selected>to right</option>
+1 -1
View File
@@ -210,7 +210,7 @@ const operationCurrencies = currencies.slice(0, 20)
</CardActions>
</CardHeader>
<CardBody>
<Chart chartId="dashboard-crypto-candlestick" height={28} />
<Chart chartId="dashboard-crypto-candlestick" height={28} label="LTC/BTC" />
</CardBody>
</Card>
</div>
+1 -1
View File
@@ -6,7 +6,7 @@ import faq from '@data/faq.json'
const categories = faq as { name: string; questions: { question: string }[] }[]
---
<DefaultLayout pageHeader="Frequently Asked Questions" actions="breadcrumb" pageMenu="extra.faq">
<DefaultLayout title="Frequently Asked Questions" pageHeader="Frequently Asked Questions" actions="breadcrumb" pageMenu="extra.faq">
<div class="card card-lg">
<div class="card-body">
<div class="space-y-4">
+1 -1
View File
@@ -12,7 +12,7 @@ const fillers = Array.from({ length: 21 })
<DefaultLayout title="Flags" pageHeader="Flags" pageMenu="addons.flags">
<Card>
<CardHeader>
<div class="card-title">List of all flags</div>
<h3 class="card-title">List of all flags</h3>
</CardHeader>
<CardBody class="p-0">
<div class="demo-icons-list-wrap">
+39 -21
View File
@@ -106,15 +106,15 @@ const countries = flags as { name: string }[]
<div>
<div class="input-icon">
<span class="input-icon-addon"><Icon name="user" /></span>
<input type="text" value="" class="form-control is-invalid" placeholder="Username" />
<div class="invalid-feedback">This throws the icon out of bounds when input element contains `is-invalid` class.</div>
<input type="text" value="" class="form-control is-invalid" placeholder="Username" aria-label="Username" aria-invalid="true" aria-describedby="username-invalid-feedback" />
<div class="invalid-feedback" id="username-invalid-feedback">This throws the icon out of bounds when input element contains `is-invalid` class.</div>
</div>
</div>
<div>
<div class="input-icon">
<span class="input-icon-addon"><Icon name="mail" /></span>
<input type="email" value="" class="form-control is-valid" placeholder="Email" />
<div class="valid-feedback">This email looks good!</div>
<input type="email" value="" class="form-control is-valid" placeholder="Email" aria-label="Email" aria-invalid="false" aria-describedby="email-valid-feedback" />
<div class="valid-feedback" id="email-valid-feedback">This email looks good!</div>
</div>
</div>
</form>
@@ -132,33 +132,51 @@ const countries = flags as { name: string }[]
<div class="space-y">
<div><h4>Personal Info</h4></div>
<div class="row row-cols-2 g-4">
<FormGroup label="First Name" class="">
<input type="text" placeholder="Enter first name" class="form-control" />
<FormGroup label="First Name" for="example-form-first-name" class="">
<input type="text" id="example-form-first-name" placeholder="Enter first name" class="form-control" autocomplete="given-name" />
</FormGroup>
<FormGroup label="Last Name" class="">
<input type="text" placeholder="Enter last name" class="form-control" />
<FormGroup label="Last Name" for="example-form-last-name" class="">
<input type="text" id="example-form-last-name" placeholder="Enter last name" class="form-control" autocomplete="family-name" />
</FormGroup>
<FormGroup label="Gender" class="">
<div><select class="form-select"><option>Male</option><option>Female</option><option>Others</option></select></div>
<FormGroup label="Gender" for="example-form-gender" class="">
<div>
<select class="form-select" id="example-form-gender">
<option>Male</option>
<option>Female</option>
<option>Others</option>
</select>
</div>
</FormGroup>
<FormGroup label="Date of Birth" class="">
<FormGroup label="Date of Birth" for="datepicker-birth-date" class="">
<div><Datepicker layout="icon" id="birth-date" /></div>
</FormGroup>
</div>
<FormGroup label="Category" class="">
<div><select class="form-select"><option>Category 1</option><option>Category 2</option><option>Category 3</option></select></div>
<FormGroup label="Category" for="example-form-category" class="">
<div>
<select class="form-select" id="example-form-category">
<option>Category 1</option>
<option>Category 2</option>
<option>Category 3</option>
</select>
</div>
</FormGroup>
<div><h4>Address</h4></div>
<FormGroup label="Street" class="">
<input type="text" class="form-control" />
<FormGroup label="Street" for="example-form-street" class="">
<input type="text" id="example-form-street" class="form-control" autocomplete="street-address" />
</FormGroup>
<div class="row row-cols-2 g-4">
<FormGroup label="City" class=""><input type="text" class="form-control" /></FormGroup>
<FormGroup label="State" class=""><input type="text" class="form-control" /></FormGroup>
<FormGroup label="Post Code" class=""><input type="text" class="form-control" /></FormGroup>
<FormGroup label="Country" class="">
<FormGroup label="City" for="example-form-city" class="">
<input type="text" id="example-form-city" class="form-control" autocomplete="address-level2" />
</FormGroup>
<FormGroup label="State" for="example-form-state" class="">
<input type="text" id="example-form-state" class="form-control" autocomplete="address-level1" />
</FormGroup>
<FormGroup label="Post Code" for="example-form-postcode" class="">
<input type="text" id="example-form-postcode" class="form-control" autocomplete="postal-code" />
</FormGroup>
<FormGroup label="Country" for="example-form-country" class="">
<div>
<select class="form-select">
<select class="form-select" id="example-form-country" autocomplete="country-name">
<option>--Select Country--</option>
{countries.map((country) => <option>{country.name}</option>)}
</select>
@@ -185,6 +203,6 @@ const countries = flags as { name: string }[]
</div>
</div>
<div class="col"><Payment /></div>
<div class="col"><Payment label="Visa" /></div>
</div>
</DefaultLayout>
+2 -1
View File
@@ -3,7 +3,8 @@ import DefaultLayout from '@shared/layouts/DefaultLayout.astro'
import CaptureScript from '@shared/components/CaptureScript.astro'
---
<DefaultLayout pageMenu="plugins.map-fullsize" pageLibs={['google-maps']} sidebar hideTopbar wrapperFull>
<DefaultLayout title="Full Size Map" pageMenu="plugins.map-fullsize" pageLibs={['google-maps']} sidebar hideTopbar wrapperFull>
<h1 class="visually-hidden">Full Size Map</h1>
<div class="map flex-fill" id="map-google"></div>
<!--
is:inline: google-maps loads via a deferred page-lib <script>; see
+1 -1
View File
@@ -24,7 +24,7 @@ const mapEntries = Object.entries(maps as Record<string, MapData>)
<div class="col-lg-6">
<Card>
<CardBody>
<div class="card-title">{data.title}</div>
<h3 class="card-title">{data.title}</h3>
<Map mapId={mapId} />
</CardBody>
</Card>
+1 -3
View File
@@ -24,8 +24,6 @@ import ChangePasswordModalContent from '@shared/components/modals/ChangePassword
import AddTaskModalContent from '@shared/components/modals/AddTaskModalContent.astro'
const cardClass = 'position-relative rounded d-block bg-surface-backdrop py-6 w-auto h-auto z-0'
// add-task bakes `show` into the class string (no `show` flag) → aria-hidden="true".
const addTaskClass = 'position-relative rounded d-block show bg-surface-backdrop py-6 w-auto h-auto z-0'
---
<DefaultLayout title="Modals" pageHeader="Modals" pageMenu="base.modals" pageLibs={['signature_pad', 'hugerte', 'litepicker']}>
@@ -152,7 +150,7 @@ const addTaskClass = 'position-relative rounded d-block show bg-surface-backdrop
</div>
<div>
<h3>Add task modal</h3>
<ModalInline class={addTaskClass} modalId="add-task">
<ModalInline class={cardClass} modalId="add-task" show>
<AddTaskModalContent />
</ModalInline>
</div>
+16 -13
View File
@@ -25,21 +25,21 @@ import FormGroup from '@ui/FormGroup.astro'
</div>
</nav>
<main class="py-5">
<main class="py-5" id="content">
<div class="container container-tight">
<div class="page-header">
<h1 class="page-title">Let's set up your account</h1>
</div>
<div class="card mt-5">
<div class="card-body space-y-4">
<FormGroup label="Full name" class="">
<input type="text" class="form-control" placeholder="Enter your full name" />
<FormGroup label="Full name" for="onboarding-full-name" class="">
<input type="text" class="form-control" id="onboarding-full-name" placeholder="Enter your full name" />
</FormGroup>
<FormGroup label="Company name" class="">
<input type="text" class="form-control" placeholder="Enter your company name" />
<FormGroup label="Company name" for="onboarding-company-name" class="">
<input type="text" class="form-control" id="onboarding-company-name" placeholder="Enter your company name" />
</FormGroup>
<FormGroup label="Role" class="">
<select class="form-select">
<FormGroup label="Role" for="onboarding-role" class="">
<select class="form-select" id="onboarding-role">
<option value="">Select your role</option>
<option value="developer">Developer</option>
<option value="designer">Designer</option>
@@ -48,7 +48,8 @@ import FormGroup from '@ui/FormGroup.astro'
<option value="other">Other</option>
</select>
</FormGroup>
<FormGroup label="Team size" class="">
<fieldset class="border-0 p-0 m-0">
<legend class="form-label float-none mb-0" style="font-size: inherit;">Team size</legend>
<div class="form-selectgroup">
<label class="form-selectgroup-item">
<input type="radio" name="team-size" value="1" class="form-selectgroup-input" checked />
@@ -67,8 +68,9 @@ import FormGroup from '@ui/FormGroup.astro'
<span class="form-selectgroup-label">50+ people</span>
</label>
</div>
</FormGroup>
<FormGroup label="What are you planning to use this for?" class="">
</fieldset>
<fieldset class="border-0 p-0 m-0">
<legend class="form-label float-none mb-0" style="font-size: inherit;">What are you planning to use this for?</legend>
<div class="form-check">
<input class="form-check-input" type="radio" value="personal" id="use-personal" checked />
<label class="form-check-label" for="use-personal"> Personal projects </label>
@@ -85,8 +87,9 @@ import FormGroup from '@ui/FormGroup.astro'
<input class="form-check-input" type="radio" value="learning" id="use-learning" />
<label class="form-check-label" for="use-learning"> Learning and experimentation </label>
</div>
</FormGroup>
<FormGroup label="How did you hear about us?" class="">
</fieldset>
<fieldset class="border-0 p-0 m-0">
<legend class="form-label float-none mb-0" style="font-size: inherit;">How did you hear about us?</legend>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="referral" value="search" id="ref-search" />
<label class="form-check-label" for="ref-search"> Search engine </label>
@@ -107,7 +110,7 @@ import FormGroup from '@ui/FormGroup.astro'
<input class="form-check-input" type="checkbox" name="referral" value="other" id="ref-other" />
<label class="form-check-label" for="ref-other"> Other </label>
</div>
</FormGroup>
</fieldset>
<div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="notifications" checked />
+2 -1
View File
@@ -3,7 +3,8 @@ import SingleLayout from '@shared/layouts/SingleLayout.astro'
import Progress from '@ui/Progress.astro'
---
<SingleLayout containerSize="slim" hideLogo>
<SingleLayout title="Page loader" containerSize="slim" hideLogo>
<h1 class="visually-hidden">Page loader</h1>
<div class="text-center">
<div class="mb-3">
<a href="." class="navbar-brand navbar-brand-autodark"><img src="./static/logo-small.svg" height="36" alt="" /></a>
+5 -5
View File
@@ -47,25 +47,25 @@ import Icon from '@ui/Icon.astro'
<span class="input-group-text">
<Payment payment="visa" size="xs" />
</span>
<input type="text" class="form-control" placeholder="0000 0000 0000 0000" autocomplete="off" id="card-number-addon" />
<input type="text" class="form-control" placeholder="0000 0000 0000 0000" autocomplete="cc-number" id="card-number" aria-required="true" />
</div>
</FormGroup>
<div class="row g-3">
<FormGroup label="Expiry Date" for="card-expiry" class="col-sm-6">
<input type="text" class="form-control" id="card-expiry" placeholder="MM/YY" inputmode="numeric" aria-required="true" maxlength="5" />
<input type="text" class="form-control" id="card-expiry" placeholder="MM/YY" inputmode="numeric" aria-required="true" maxlength="5" autocomplete="cc-exp" />
</FormGroup>
<FormGroup label="CVC" for="card-cvc" class="col-sm-6">
<input type="text" class="form-control" id="card-cvc" placeholder="CVC" inputmode="numeric" aria-required="true" maxlength="3" />
<input type="text" class="form-control" id="card-cvc" placeholder="CVC" inputmode="numeric" aria-required="true" maxlength="3" autocomplete="cc-csc" />
</FormGroup>
</div>
<FormGroup label="Name on Card" for="card-name" class="">
<input type="text" class="form-control" id="card-name" placeholder="Full name" aria-required="true" />
<input type="text" class="form-control" id="card-name" placeholder="Full name" aria-required="true" autocomplete="cc-name" />
</FormGroup>
<FormGroup label="Email" for="card-email" class="">
<input type="email" class="form-control" id="card-email" placeholder="you@example.com" aria-required="true" />
<input type="email" class="form-control" id="card-email" placeholder="you@example.com" aria-required="true" autocomplete="email" />
</FormGroup>
<div>
+2 -2
View File
@@ -14,7 +14,7 @@ const providers = payments as { name: string; logo: string }[]
<div class="col-12">
<Card>
<CardHeader>
<div class="card-title">Light version</div>
<h3 class="card-title">Light version</h3>
</CardHeader>
<CardBody>
<div class="row g-5 row-cols-5">
@@ -42,7 +42,7 @@ const providers = payments as { name: string; logo: string }[]
<div class="col-12">
<Card>
<CardHeader>
<div class="card-title">Dark version</div>
<h3 class="card-title">Dark version</h3>
</CardHeader>
<CardBody>
<div class="row g-5 row-cols-5">
+1 -2
View File
@@ -1,5 +1,4 @@
---
// front matter — the <title> falls back to the site default).
import DefaultLayout from '@shared/layouts/DefaultLayout.astro'
import PlaceholderCard1 from '@shared/components/cards/placeholder/Card1.astro'
import PlaceholderCard2 from '@shared/components/cards/placeholder/Card2.astro'
@@ -11,7 +10,7 @@ import PlaceholderCard6 from '@shared/components/cards/placeholder/Card6.astro'
const cols = [1, 2, 3, 4]
---
<DefaultLayout pageHeader="Placeholder" pageMenu="base.placeholder">
<DefaultLayout title="Placeholder" pageHeader="Placeholder" pageMenu="base.placeholder">
<div class="row row-cards">
{
cols.map(() => (
+14 -13
View File
@@ -94,54 +94,55 @@ import Trending from '@ui/Trending.astro'
<div class="row g-4">
<div class="col-md-6">
<h4 class="mb-3">Basic Datepicker</h4>
<FormGroup label="Default datepicker">
<FormGroup label="Default datepicker" for="datepicker-playground-default">
<Datepicker id="playground-default" value="2024-01-15" />
</FormGroup>
<FormGroup label="With icon">
<FormGroup label="With icon" for="datepicker-playground-icon">
<Datepicker id="playground-icon" layout="icon" value="2024-01-15" />
</FormGroup>
<FormGroup label="Icon prepend">
<FormGroup label="Icon prepend" for="datepicker-playground-icon-prepend">
<Datepicker id="playground-icon-prepend" layout="icon-prepend" value="2024-01-15" />
</FormGroup>
</div>
<div class="col-md-6">
<h4 class="mb-3">Datepicker Options</h4>
<FormGroup label="With date range (min/max)">
<FormGroup label="With date range (min/max)" for="datepicker-playground-range">
<Datepicker id="playground-range" value="2024-06-15" />
</FormGroup>
<FormGroup label="Multiple selection">
<FormGroup label="Multiple selection" for="datepicker-playground-multiple">
<Datepicker id="playground-multiple" value="2024-01-15" />
</FormGroup>
<FormGroup label="Date range selection">
<FormGroup label="Date range selection" for="datepicker-playground-range-selection">
<Datepicker id="playground-range-selection" value="2024-01-15" />
</FormGroup>
</div>
<div class="col-md-6">
<h4 class="mb-3">Placement Options</h4>
<FormGroup label="Left placement">
<FormGroup label="Left placement" for="datepicker-playground-placement-left">
<Datepicker id="playground-placement-left" value="2024-01-15" />
</FormGroup>
<FormGroup label="Center placement">
<FormGroup label="Center placement" for="datepicker-playground-placement-center">
<Datepicker id="playground-placement-center" value="2024-01-15" />
</FormGroup>
<FormGroup label="Right placement">
<FormGroup label="Right placement" for="datepicker-playground-placement-right">
<Datepicker id="playground-placement-right" value="2024-01-15" />
</FormGroup>
</div>
<div class="col-md-6">
<h4 class="mb-3">Advanced Options</h4>
<FormGroup label="Multiple months">
<FormGroup label="Multiple months" for="datepicker-playground-multiple-months">
<Datepicker id="playground-multiple-months" value="2024-01-15" />
</FormGroup>
<FormGroup label="Custom first weekday (Monday)">
<FormGroup label="Custom first weekday (Monday)" for="datepicker-playground-weekday">
<Datepicker id="playground-weekday" value="2024-01-15" />
</FormGroup>
<FormGroup label="With pre-selected dates">
<FormGroup label="With pre-selected dates" for="datepicker-playground-preselected">
<Datepicker id="playground-preselected" />
</FormGroup>
</div>
<div class="col-12">
<h4 class="mb-3">Inline Datepicker</h4>
{/* inline mode renders a calendar div with no backing text input — nothing to point `for` at */}
<FormGroup label="Inline calendar">
<Datepicker id="playground-inline" inline value="2024-01-15" />
</FormGroup>
@@ -156,7 +157,7 @@ import Trending from '@ui/Trending.astro'
<div class="col-8">
<Card>
<CardBody>
<p class="card-title mb-4">Cohort Statistics</p>
<h3 class="card-title mb-4">Cohort Statistics</h3>
<dl class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
<div class="col">
<Subheader as="dt">Total Users</Subheader>
+1 -1
View File
@@ -6,7 +6,7 @@ import NavbarLogo from '@shared/components/navbar/NavbarLogo.astro'
import { site } from '@shared/lib/site'
---
<BaseLayout pageLibs={['signature_pad']}>
<BaseLayout title="Screenshot" pageLibs={['signature_pad']}>
<style is:inline>
.screenshot {
width: 1024px;
+1 -2
View File
@@ -1,5 +1,4 @@
---
// front matter — only page-header)
import DefaultLayout from '@shared/layouts/DefaultLayout.astro'
import NavAside from '@shared/components/parts/NavAside.astro'
import GalleryPhoto from '@shared/components/cards/GalleryPhoto.astro'
@@ -9,7 +8,7 @@ import people from '@data/people.json'
const resultPhotos = photos.filter((photo) => photo.horizontal).slice(0, 18)
---
<DefaultLayout pageHeader="Search results" description="About 2,410 result (0.19 seconds)" pageMenu="extra.search-results">
<DefaultLayout title="Search results" pageHeader="Search results" description="About 2,410 result (0.19 seconds)" pageMenu="extra.search-results">
<div class="row g-4">
<div class="col-md-3">
<NavAside />
+1 -1
View File
@@ -4,7 +4,7 @@ import PricingCard from '@shared/components/cards/PricingCard.astro'
import PricingCardEnterprise from '@shared/components/cards/PricingCardEnterprise.astro'
---
<SettingsLayout active="settings-plan">
<SettingsLayout active="settings-plan" title="Plans">
<div class="card-body">
<h2 class="mb-4">Plans</h2>
+1 -1
View File
@@ -20,7 +20,7 @@ import photos from '@data/photos.json'
<SignInForm />
<div class="text-center text-secondary mt-3">
Don't have account yet? <a href="./sign-up.html" tabindex="-1">Sign up</a>
Don't have account yet? <a href="./sign-up.html">Sign up</a>
</div>
</div>
</div>
+2 -2
View File
@@ -57,7 +57,7 @@ const fillers = Array.from({ length: 21 })
<div class="col-12">
<Card>
<CardHeader>
<div class="card-title">Sign in with social media</div>
<h3 class="card-title">Sign in with social media</h3>
</CardHeader>
<CardBody>
<ButtonList>
@@ -77,7 +77,7 @@ const fillers = Array.from({ length: 21 })
<div class="col-12">
<Card>
<CardHeader>
<div class="card-title">List of all social media icons</div>
<h3 class="card-title">List of all social media icons</h3>
</CardHeader>
<CardBody class="p-0">
<div class="demo-icons-list-wrap">
+4 -4
View File
@@ -12,7 +12,7 @@ import CardBody from '@ui/CardBody.astro'
<div class="col-12">
<Card>
<CardBody>
<div class="h3 card-title">Basic</div>
<h3 class="card-title">Basic</h3>
<div><Rating value={4} /></div>
</CardBody>
</Card>
@@ -20,7 +20,7 @@ import CardBody from '@ui/CardBody.astro'
<div class="col-12">
<Card>
<CardBody>
<div class="h3 card-title">Different icon</div>
<h3 class="card-title">Different icon</h3>
<div class="space-y">
<Rating value={4} />
<Rating icon="heart" value={4} color="red" />
@@ -35,7 +35,7 @@ import CardBody from '@ui/CardBody.astro'
<div class="col-md-4">
<Card>
<CardBody>
<div class="h3 card-title">Custom colors</div>
<h3 class="card-title">Custom colors</h3>
<div class="space-y">
<Rating id="color" value={3} />
<Rating id="color-primary" color="primary" value={3} />
@@ -48,7 +48,7 @@ import CardBody from '@ui/CardBody.astro'
<div class="col-md-4">
<Card>
<CardBody>
<div class="h3 card-title">Custom sizes</div>
<h3 class="card-title">Custom sizes</h3>
<div class="space-y">
<Rating id="size-sm" value={3} size="sm" />
<Rating id="size-primary" value={3} />
+1 -1
View File
@@ -7,7 +7,7 @@ import AdvancedTable from '@ui/AdvancedTable.astro'
import Card from '@ui/Card.astro'
---
<DefaultLayout pageHeader="Tables" pageMenu="base.tables" pageLibs={['lists']}>
<DefaultLayout title="Tables" pageHeader="Tables" pageMenu="base.tables" pageLibs={['lists']}>
<div class="row row-cards">
<div class="col-lg-8">
<Card>
+9 -9
View File
@@ -118,30 +118,30 @@ const selectedPeople = [5, 6, 2, 3].map((id) => peopleList[id - 1])
<CaptureModal>
<Modal modalId="add-task">
<div class="modal-header">
<h4 class="modal-title">Add task</h4>
<h4 class="modal-title" id="modal-add-task-title">Add task</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<FormGroup label="Name">
<input type="text" class="form-control" placeholder="Task name" />
<FormGroup label="Name" for="tasks-list-add-task-name">
<input type="text" class="form-control" id="tasks-list-add-task-name" placeholder="Task name" />
</FormGroup>
<FormGroup label="Assigned To">
<select class="form-select">
<FormGroup label="Assigned To" for="tasks-list-add-task-assigned">
<select class="form-select" id="tasks-list-add-task-assigned">
<option value="">Select person</option>
{selectedPeople.map((person) => <option value={person.id}>{person.full_name}</option>)}
</select>
</FormGroup>
<FormGroup label="Priority">
<select class="form-select">
<FormGroup label="Priority" for="tasks-list-add-task-priority">
<select class="form-select" id="tasks-list-add-task-priority">
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</FormGroup>
<FormGroup label="Description">
<textarea class="form-control" rows="3" placeholder="Task description"></textarea>
<FormGroup label="Description" for="tasks-list-add-task-description">
<textarea class="form-control" id="tasks-list-add-task-description" rows="3" placeholder="Task description"></textarea>
</FormGroup>
</form>
</div>
+2 -2
View File
@@ -3,10 +3,10 @@ import SingleLayout from '@shared/layouts/SingleLayout.astro'
import Icon from '@ui/Icon.astro'
---
<SingleLayout>
<SingleLayout title="Trial ended">
<div class="card card-md">
<div class="card-body">
<h2 class="mb-3">Your free trial period has expired!</h2>
<h1 class="mb-3 fs-2">Your free trial period has expired!</h1>
<p class="text-secondary mb-4">If you want to continue to benefit from Tabler, it's time to upgrade your plan.</p>
+3 -3
View File
@@ -7,7 +7,7 @@ import CardBody from '@ui/CardBody.astro'
import CardTitle from '@ui/CardTitle.astro'
---
<DefaultLayout pageHeaderFile="uptime" pageMenu="extra.uptime" pageLibs={['apexcharts']}>
<DefaultLayout title="Uptime" pageHeaderFile="uptime" pageMenu="extra.uptime" pageLibs={['apexcharts']}>
<div class="row row-cards">
<div class="col-md-4">
<Card>
@@ -37,7 +37,7 @@ import CardTitle from '@ui/CardTitle.astro'
<Card>
<CardBody>
<CardTitle>Response times across regions in the last day</CardTitle>
<Chart chartId="uptime" height={15} />
<Chart chartId="uptime" height={15} label="Response times across regions in the last day" />
</CardBody>
</Card>
</div>
@@ -45,7 +45,7 @@ import CardTitle from '@ui/CardTitle.astro'
<Card>
<CardBody>
<CardTitle>Uptime incidents per day</CardTitle>
<Chart chartId="uptime-incidents" height={15} />
<Chart chartId="uptime-incidents" height={15} label="Uptime incidents per day" />
</CardBody>
</Card>
</div>
+4 -4
View File
@@ -24,12 +24,12 @@ import timezones from '@data/timezones.json'
<HrText text="your data" position="center" class="hr-text-spaceless" />
<div class="card-body">
<FormGroup label="Create your Tabler URL" hint="Choose a URL that describes you or your business in a concise way. Make it short and easy to remember so you can share links with ease.">
<InputGroup prepend="https://tabler.io/" inputClass="ps-1" flat />
<FormGroup label="Create your Tabler URL" for="wizard-url" hint="Choose a URL that describes you or your business in a concise way. Make it short and easy to remember so you can share links with ease.">
<InputGroup id="wizard-url" prepend="https://tabler.io/" inputClass="ps-1" flat />
</FormGroup>
<FormGroup label="Timezone" class="">
<select class="form-select mb-0">
<FormGroup label="Timezone" for="wizard-timezone" class="">
<select class="form-select mb-0" id="wizard-timezone">
{
timezones.map((timezone) => (
<option value={timezone.abbr} selected={timezone.abbr === 'CEDT'}>
+4 -4
View File
@@ -10,12 +10,12 @@ import FormGroup from '@ui/FormGroup.astro'
<DefaultLayout title="HugeRTE" pageHeader="HugeRTE" pageLibs={['hugerte']}>
<Card>
<CardBody>
<FormGroup label="Your name">
<input type="text" class="form-control" placeholder="Name" />
<FormGroup label="Your name" for="wysiwyg-name">
<input type="text" class="form-control" id="wysiwyg-name" placeholder="Name" />
</FormGroup>
<FormGroup label="Description">
<Wysiwyg />
<FormGroup label="Description" for="hugerte-description">
<Wysiwyg id="description" />
</FormGroup>
</CardBody>
</Card>
+1 -1
View File
@@ -73,7 +73,7 @@ const { rtl = false } = Astro.props
<div class="card">
<div class="card-body">
<CardTitle>Traffic summary</CardTitle>
<Chart chartId="mentions" size="lg" />
<Chart chartId="mentions" size="lg" label="Traffic summary" />
</div>
</div>
</div>
+2 -2
View File
@@ -7,7 +7,7 @@ import people from '@data/people.json'
const person = people[0]
---
<form class="card card-md" action="./" method="get" autocomplete="off" novalidate>
<form class="card card-md" action="./" method="get" novalidate>
<div class="card-body text-center">
<div class="mb-4">
<CardTitle as="h2">Account Locked</CardTitle>
@@ -20,7 +20,7 @@ const person = people[0]
</div>
<div class="mb-4">
<input type="password" class="form-control" placeholder="Password…" />
<input type="password" class="form-control" placeholder="Password…" aria-label="Password" autocomplete="current-password" />
</div>
<div>
+4 -4
View File
@@ -14,8 +14,8 @@ const tabs = ['Activity', 'Profile', 'Settings']
const tabsHtml = `
<!-- Cards navigation -->
<ul class="nav nav-tabs${bottom ? ' nav-tabs-bottom' : ''}">
${tabs.map((tab, i) => ` <li class="nav-item"><a href="#tab-${id}-${i + 1}" class="nav-link${i === 0 ? ' active' : ''}" data-bs-toggle="tab">${tab}</a></li>`).join('\n')}
<ul class="nav nav-tabs${bottom ? ' nav-tabs-bottom' : ''}" role="tablist">
${tabs.map((tab, i) => ` <li class="nav-item" role="presentation"><a href="#tab-${id}-${i + 1}" id="tab-${id}-${i + 1}-tab" class="nav-link${i === 0 ? ' active' : ''}" data-bs-toggle="tab" data-bs-target="#tab-${id}-${i + 1}" role="tab" aria-controls="tab-${id}-${i + 1}" aria-selected="${i === 0 ? 'true' : 'false'}">${tab}</a></li>`).join('\n')}
</ul>`
const tabsContentHtml = `
@@ -23,9 +23,9 @@ const tabsContentHtml = `
${tabs
.map(
(tab, i) => ` <!-- Content of card #${tab} -->
<div id="tab-${id}-${i + 1}" class="card tab-pane${i === 0 ? ' active show' : ''}">
<div id="tab-${id}-${i + 1}" class="card tab-pane${i === 0 ? ' active show' : ''}" role="tabpanel" aria-labelledby="tab-${id}-${i + 1}-tab">
<div class="card-body">
<div class="card-title">${tab}</div>
<h3 class="card-title">${tab}</h3>
<p class="text-secondary">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci, alias aliquid distinctio dolorem expedita, fugiat hic magni molestiae molestias odit.
</p>
+17 -9
View File
@@ -21,7 +21,7 @@ interface Props {
const { id: idProp, title = 'Carousel', indicators, indicatorsThumb, indicatorsThumbRatio, indicatorsDot, indicatorsVertical, controls, captions, offset = 0, limit = 5, fade } = Astro.props
const carouselId = idProp ?? 'carousel'
const filteredPhotos = (photos as { file: string; horizontal?: boolean }[]).filter((p) => p.horizontal)
const filteredPhotos = (photos as { file: string; title?: string; horizontal?: boolean }[]).filter((p) => p.horizontal)
const slides = filteredPhotos.slice(offset, offset + limit)
---
@@ -30,22 +30,30 @@ const slides = filteredPhotos.slice(offset, offset + limit)
<CardTitle>{title}</CardTitle>
</div>
<div class="card-body">
<div id={`carousel-${carouselId}`} class={`carousel slide${fade ? ' carousel-fade' : ''}`} data-bs-ride="carousel">
<div id={`carousel-${carouselId}`} class={`carousel slide${fade ? ' carousel-fade' : ''}`} data-bs-ride="carousel" aria-roledescription="carousel" aria-label={title}>
{
indicators && (
<div class={`carousel-indicators${indicatorsVertical ? ' carousel-indicators-vertical' : ''}${indicatorsDot ? ' carousel-indicators-dot' : indicatorsThumb ? ' carousel-indicators-thumb' : ''}`}>
{slides.map((photo, i) => (
<button type="button" data-bs-target={`#carousel-${carouselId}`} data-bs-slide-to={`${i}`} class={`${indicatorsThumbRatio ? ' ratio ratio-4x3' : ''}${i === 0 ? ' active' : ''}`} style={indicatorsThumb ? `background-image: url(./static/photos/${photo.file})` : undefined} />
<button
type="button"
data-bs-target={`#carousel-${carouselId}`}
data-bs-slide-to={`${i}`}
class={`${indicatorsThumbRatio ? ' ratio ratio-4x3' : ''}${i === 0 ? ' active' : ''}`}
style={indicatorsThumb ? `background-image: url(./static/photos/${photo.file})` : undefined}
aria-label={`Slide ${i + 1}`}
aria-current={i === 0 ? 'true' : undefined}
/>
))}
</div>
)
}
<div class="carousel-inner">
<div class="carousel-inner" aria-live="polite" aria-atomic="true">
{
slides.map((photo, i) => (
<div class={`carousel-item${i === 0 ? ' active' : ''}`}>
<img class="d-block w-100" alt="" src={`./static/photos/${photo.file}`} />
<img class="d-block w-100" alt={captions ? '' : (photo.title ?? '')} src={`./static/photos/${photo.file}`} />
{captions && (
<Fragment>
@@ -64,14 +72,14 @@ const slides = filteredPhotos.slice(offset, offset + limit)
{
controls && (
<Fragment>
<a class="carousel-control-prev" href={`#carousel-${carouselId}`} role="button" data-bs-slide="prev">
<button type="button" class="carousel-control-prev" data-bs-target={`#carousel-${carouselId}`} data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true" />
<span class="visually-hidden">Previous</span>
</a>
<a class="carousel-control-next" href={`#carousel-${carouselId}`} role="button" data-bs-slide="next">
</button>
<button type="button" class="carousel-control-next" data-bs-target={`#carousel-${carouselId}`} data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true" />
<span class="visually-hidden">Next</span>
</a>
</button>
</Fragment>
)
}
+8 -8
View File
@@ -9,13 +9,13 @@ const years = Array.from({ length: 11 }, (_, i) => 2020 + i)
<div class="card">
<div class="card-body">
<div class="mb-3">
<div class="form-label">Card number</div>
<input type="text" name="input-mask" class="form-control" data-mask="0000 0000 0000 0000" data-mask-visible="true" placeholder="0000 0000 0000 0000" autocomplete="off" />
<label class="form-label" for="credit-card-number">Card number</label>
<input type="text" name="input-mask" id="credit-card-number" class="form-control" data-mask="0000 0000 0000 0000" data-mask-visible="true" placeholder="0000 0000 0000 0000" autocomplete="cc-number" />
</div>
<div class="mb-3">
<div class="form-label">Card name</div>
<input type="text" class="form-control" />
<label class="form-label" for="credit-card-name">Card name</label>
<input type="text" id="credit-card-name" class="form-control" autocomplete="cc-name" />
</div>
<div class="row">
@@ -23,12 +23,12 @@ const years = Array.from({ length: 11 }, (_, i) => 2020 + i)
<FormGroup label="Expiration date">
<div class="row g-2">
<div class="col">
<select class="form-select">
<select class="form-select" aria-label="Expiration month" autocomplete="cc-exp-month">
{months.map((month) => <option value={month}>{month}</option>)}
</select>
</div>
<div class="col">
<select class="form-select">
<select class="form-select" aria-label="Expiration year" autocomplete="cc-exp-year">
{years.map((year) => <option value={year}>{year}</option>)}
</select>
</div>
@@ -37,8 +37,8 @@ const years = Array.from({ length: 11 }, (_, i) => 2020 + i)
</div>
<div class="col">
<div class="mb-3">
<div class="form-label">CVV</div>
<input type="number" class="form-control" />
<label class="form-label" for="credit-card-cvv">CVV</label>
<input type="number" id="credit-card-cvv" class="form-control" autocomplete="cc-csc" />
</div>
</div>
</div>
@@ -19,7 +19,7 @@ const rows = (commits as Commit[]).slice(0, 5)
<div class="card">
<div class="card-header border-0">
<div class="card-title">Development activity</div>
<h3 class="card-title">Development activity</h3>
</div>
<div class="position-relative">
<div class="position-absolute top-0 left-0 px-3 mt-1 w-75">
@@ -31,7 +31,7 @@ const rows = (commits as Commit[]).slice(0, 5)
</div>
</div>
</div>
<Chart chartId="development-activity" height={12} />
<Chart chartId="development-activity" height={12} label="Development activity" />
</div>
<div class="card-table table-responsive">
@@ -4,14 +4,14 @@ import Button from '@ui/Button.astro'
import FormGroup from '@ui/FormGroup.astro'
---
<form class="card card-md" action="./" method="get" autocomplete="off" novalidate>
<form class="card card-md" action="./" method="get" novalidate>
<div class="card-body">
<h2 class="card-title text-center mb-4">Forgot password</h2>
<p class="text-secondary mb-4">Enter your email address and your password will be reset and emailed to you.</p>
<FormGroup label="Email address">
<input type="email" class="form-control" placeholder="Enter email" />
<FormGroup label="Email address" for="forgot-password-email">
<input type="email" id="forgot-password-email" class="form-control" placeholder="Enter email" autocomplete="email" />
</FormGroup>
<FormFooter>
<Button text="Send me new password" block color="primary" icon="mail" />
+1 -1
View File
@@ -18,7 +18,7 @@ const entries = Object.entries(icons as Record<string, { svg?: Record<string, st
<div class="card">
<div class="card-header">
<div class="card-title">{title}</div>
<h3 class="card-title">{title}</h3>
</div>
<div class="card-body p-0">
<div class="demo-icons-list-wrap">
+5 -2
View File
@@ -5,6 +5,9 @@ import CardTitle from '@ui/CardTitle.astro'
import DropdownMenu from '@ui/DropdownMenu.astro'
import Pagination from '@ui/Pagination.astro'
import invoices from '@data/invoices.json'
import countries from '@data/countries.json'
const countryNames = Object.fromEntries((countries as { code: string; name: string }[]).map((c) => [c.code, c.name]))
---
<div class="card">
@@ -56,12 +59,12 @@ import invoices from '@data/invoices.json'
<span class="text-secondary">00{index + 1 + 1400}</span>
</td>
<td>
<a href="invoice.html" class="text-reset" tabindex="-1">
<a href="invoice.html" class="text-reset">
{invoice.name}
</a>
</td>
<td>
<Flag flag={invoice.country} size="xs" class="me-2" />
<Flag flag={invoice.country} size="xs" class="me-2" label={countryNames[invoice.country] ?? invoice.country.toUpperCase()} />
{invoice.client}
</td>
<td>{invoice['vat-no']}</td>
+1 -1
View File
@@ -26,5 +26,5 @@ import SignInForm from './SignInForm.astro'
</div>
<div class="text-center text-secondary mt-3">
Don't have account yet? <a href="./sign-up.html" tabindex="-1">Sign up</a>
Don't have account yet? <a href="./sign-up.html">Sign up</a>
</div>
+5 -5
View File
@@ -4,18 +4,18 @@ import FormGroup from '@ui/FormGroup.astro'
import InputGroup from '@ui/InputGroup.astro'
---
<form action="./" method="get" autocomplete="off" novalidate>
<FormGroup label="Email address">
<input type="email" class="form-control" placeholder="your@email.com" autocomplete="off" />
<form action="./" method="get" novalidate>
<FormGroup label="Email address" for="signin-email">
<input type="email" id="signin-email" class="form-control" placeholder="your@email.com" autocomplete="email" />
</FormGroup>
<div class="mb-2">
<label class="form-label">
<label class="form-label" for="signin-password">
Password
<span class="form-label-description">
<a href="./forgot-password.html">I forgot password</a>
</span>
</label>
<InputGroup type="password" placeholder="Your password" flat appendButton={[{ icon: 'eye', description: 'Show password' }]} />
<InputGroup type="password" id="signin-password" placeholder="Your password" autocomplete="current-password" flat appendButton={[{ icon: 'eye', description: 'Show password' }]} />
</div>
<div class="mb-2">
<label class="form-check">
+9 -9
View File
@@ -4,23 +4,23 @@ import InputGroup from '@ui/InputGroup.astro'
import FormGroup from '@ui/FormGroup.astro'
---
<form class="card card-md" action="./" method="get" autocomplete="off" novalidate>
<form class="card card-md" action="./" method="get" novalidate>
<div class="card-body">
<h2 class="card-title text-center mb-4">Create new account</h2>
<FormGroup label="Name">
<input type="text" class="form-control" placeholder="Enter name" />
<FormGroup label="Name" for="signup-name">
<input type="text" id="signup-name" class="form-control" placeholder="Enter name" autocomplete="name" />
</FormGroup>
<FormGroup label="Email address">
<input type="email" class="form-control" placeholder="Enter email" />
<FormGroup label="Email address" for="signup-email">
<input type="email" id="signup-email" class="form-control" placeholder="Enter email" autocomplete="email" />
</FormGroup>
<FormGroup label="Password">
<InputGroup type="password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat placeholder="Password" />
<FormGroup label="Password" for="signup-password">
<InputGroup type="password" id="signup-password" autocomplete="new-password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat placeholder="Password" />
</FormGroup>
<div class="mb-3">
<label class="form-check">
<input type="checkbox" class="form-check-input" />
<span class="form-check-label">Agree the <a href="./terms-of-service.html" tabindex="-1">terms and policy</a>.</span>
<span class="form-check-label">Agree the <a href="./terms-of-service.html">terms and policy</a>.</span>
</label>
</div>
@@ -31,5 +31,5 @@ import FormGroup from '@ui/FormGroup.astro'
</form>
<div class="text-center text-secondary mt-3">
Already have account? <a href="./sign-in.html" tabindex="-1">Sign in</a>
Already have account? <a href="./sign-in.html">Sign in</a>
</div>
+15 -15
View File
@@ -25,18 +25,18 @@ const paneClass = `tab-pane${animation ? ' fade' : ''}`
<div class="card">
<div class="card-header">
<ul class={navClass} data-bs-toggle="tabs">
<li class="nav-item">
<a href={`#tabs-home-${id}`} class="nav-link active" data-bs-toggle="tab">{icons && <Icon name="home" class={iconClass} />}{!hideText && 'Home'}</a>
<ul class={navClass} role="tablist" data-bs-toggle="tab">
<li class="nav-item" role="presentation">
<a href={`#tabs-home-${id}`} id={`tabs-home-${id}-tab`} class="nav-link active" data-bs-toggle="tab" data-bs-target={`#tabs-home-${id}`} role="tab" aria-controls={`tabs-home-${id}`} aria-selected="true">{icons && <Icon name="home" class={iconClass} />}{!hideText && 'Home'}</a>
</li>
<li class="nav-item">
<a href={`#tabs-profile-${id}`} class="nav-link" data-bs-toggle="tab">{icons && <Icon name="user" class={iconClass} />}{!hideText && 'Profile'}</a>
<li class="nav-item" role="presentation">
<a href={`#tabs-profile-${id}`} id={`tabs-profile-${id}-tab`} class="nav-link" data-bs-toggle="tab" data-bs-target={`#tabs-profile-${id}`} role="tab" aria-controls={`tabs-profile-${id}`} aria-selected="false">{icons && <Icon name="user" class={iconClass} />}{!hideText && 'Profile'}</a>
</li>
{
activity && (
<li class="nav-item">
<a href={`#tabs-activity-${id}`} class="nav-link" data-bs-toggle="tab">
<li class="nav-item" role="presentation">
<a href={`#tabs-activity-${id}`} id={`tabs-activity-${id}-tab`} class="nav-link" data-bs-toggle="tab" data-bs-target={`#tabs-activity-${id}`} role="tab" aria-controls={`tabs-activity-${id}`} aria-selected="false">
{icons && <Icon name="activity" class={iconClass} />}
{!hideText && 'Activity'}
</a>
@@ -46,8 +46,8 @@ const paneClass = `tab-pane${animation ? ' fade' : ''}`
{
disabled && (
<li class="nav-item">
<a href={`#tabs-activity-${id}`} class="nav-link disabled" data-bs-toggle="tab">
<li class="nav-item" role="presentation">
<a href={`#tabs-activity-${id}`} class="nav-link disabled" data-bs-toggle="tab" role="tab" aria-selected="false" aria-disabled="true" tabindex="-1">
{icons && <Icon name="x" class={iconClass} />}
{!hideText && 'Disabled'}
</a>
@@ -67,8 +67,8 @@ const paneClass = `tab-pane${animation ? ' fade' : ''}`
}
{
settings && (
<li class={`nav-item ${reverse ? 'me-auto' : 'ms-auto'}`}>
<a href={`#tabs-settings-${id}`} class="nav-link" title="Settings" data-bs-toggle="tab">
<li class={`nav-item ${reverse ? 'me-auto' : 'ms-auto'}`} role="presentation">
<a href={`#tabs-settings-${id}`} id={`tabs-settings-${id}-tab`} class="nav-link" title="Settings" data-bs-toggle="tab" data-bs-target={`#tabs-settings-${id}`} role="tab" aria-controls={`tabs-settings-${id}`} aria-selected="false">
<Icon name="settings" />
</a>
</li>
@@ -78,17 +78,17 @@ const paneClass = `tab-pane${animation ? ' fade' : ''}`
</div>
<div class="card-body">
<div class="tab-content">
<div class={`${paneClass} active show`} id={`tabs-home-${id}`}>
<div class={`${paneClass} active show`} id={`tabs-home-${id}`} role="tabpanel" aria-labelledby={`tabs-home-${id}-tab`}>
<h4>Home tab</h4>
<div>Cursus turpis vestibulum, dui in pharetra vulputate id sed non turpis ultricies fringilla at sed facilisis lacus pellentesque purus nibh</div>
</div>
<div class={paneClass} id={`tabs-profile-${id}`}>
<div class={paneClass} id={`tabs-profile-${id}`} role="tabpanel" aria-labelledby={`tabs-profile-${id}-tab`}>
<h4>Profile tab</h4>
<div>Fringilla egestas nunc quis tellus diam rhoncus ultricies tristique enim at diam, sem nunc amet, pellentesque id egestas velit sed</div>
</div>
{
settings && (
<div class={paneClass} id={`tabs-settings-${id}`}>
<div class={paneClass} id={`tabs-settings-${id}`} role="tabpanel" aria-labelledby={`tabs-settings-${id}-tab`}>
<h4>Settings tab</h4>
<div>Donec ac vitae diam amet vel leo egestas consequat rhoncus in luctus amet, facilisi sit mauris accumsan nibh habitant senectus</div>
</div>
@@ -96,7 +96,7 @@ const paneClass = `tab-pane${animation ? ' fade' : ''}`
}
{
activity && (
<div class={paneClass} id={`tabs-activity-${id}`}>
<div class={paneClass} id={`tabs-activity-${id}`} role="tabpanel" aria-labelledby={`tabs-activity-${id}-tab`}>
<h4>Activity tab</h4>
<div>Donec ac vitae diam amet vel leo egestas consequat rhoncus in luctus amet, facilisi sit mauris accumsan nibh habitant senectus</div>
</div>
+1 -1
View File
@@ -33,7 +33,7 @@ const photo = (photos as Photo[])[personId]
<Avatar size="xl" person={person} thumb />
</div>
<div class="card-body text-center">
<div class="card-title mb-1">{person.full_name}</div>
<h3 class="card-title mb-1">{person.full_name}</h3>
<div class="text-secondary">{person.job_title}</div>
</div>
</a>
+1 -1
View File
@@ -22,7 +22,7 @@ const person = (people as Person[])[personId]
<div class="mb-3">
<Avatar size="xl" person={person} />
</div>
<div class="card-title mb-1">{person.full_name}</div>
<h3 class="card-title mb-1">{person.full_name}</h3>
<div class="text-secondary">{person.job_title}</div>
</div>
<a href="#" class="card-btn">View full profile</a>
+1 -1
View File
@@ -26,7 +26,7 @@ const person = (people as Person[])[personId - 1]
<div class="card">
<div class="card-body">
<div class="card-title">{title}</div>
<h3 class="card-title">{title}</h3>
<div class="mb-2">
<Icon name="book" class="me-2 text-secondary" />
Went to: <strong>{person.university}</strong>
+5 -2
View File
@@ -20,12 +20,15 @@ interface Props {
const { limit = 10, offset = 0, title = 'Top users', class: className } = Astro.props
const colors = 'green,red,yellow,x,x'.split(',')
const statusLabels: Record<string, string> = { green: 'Online', red: 'Busy', yellow: 'Away', x: 'Offline' }
const rows = (people as Person[]).slice(offset, offset + limit).map((person, idx) => {
const index = idx + 1 // forloop.index (1-based)
const status = colors[randomNumber(index + 5, 0, colors.length - 1)]
return {
person,
status: colors[randomNumber(index + 5, 0, colors.length - 1)],
status,
statusLabel: statusLabels[status],
timeago: timeagoLabel(index, 6),
}
})
@@ -42,7 +45,7 @@ const rows = (people as Person[]).slice(offset, offset + limit).map((person, idx
<div class="col-6">
<div class="row g-3 align-items-center">
<a href="#" class="col-auto">
<Avatar person={row.person} status={row.status} />
<Avatar person={row.person} status={row.status} statusLabel={row.statusLabel} />
</a>
<div class="col text-truncate">
<a href="#" class="text-reset d-block text-truncate">
@@ -20,6 +20,6 @@ import Trending from '@ui/Trending.astro'
</div>
</div>
<Chart chartId="active-users" size="sm" />
<Chart chartId="active-users" size="sm" label="Active subscriptions" />
</div>
</div>
@@ -26,6 +26,6 @@ import Chart from '@ui/Chart.astro'
</div>
</div>
<Chart chartId="crm-mrr-overview" height={15} />
<Chart chartId="crm-mrr-overview" height={15} label="Monthly recurring revenue" />
</div>
</div>
@@ -20,6 +20,6 @@ import Trending from '@ui/Trending.astro'
</div>
</div>
<Chart chartId="new-clients" size="sm" />
<Chart chartId="new-clients" size="sm" label="New clients" />
</div>
</div>
@@ -7,12 +7,12 @@ const funnel = crmDashboard.pipeline_funnel
<div class="card h-100">
<div class="card-body">
<div class="card-title">
<h3 class="card-title">
<div class="d-flex align-items-center justify-content-between">
<div class="fw-medium">{funnel.title}</div>
<div class="text-secondary">{funnel.period}</div>
</div>
</div>
</h3>
<div class="d-flex flex-column gap-2">
{
funnel.items.map((item) => (
+1 -1
View File
@@ -20,5 +20,5 @@ import Trending from '@ui/Trending.astro'
</div>
</div>
</div>
<Chart chartId="revenue-bg" size="sm" class="rounded-bottom-3" />
<Chart chartId="revenue-bg" size="sm" class="rounded-bottom-3" label="Revenue" />
</div>
@@ -13,6 +13,6 @@ import DropdownDays from '@ui/DropdownDays.astro'
<DropdownDays id="social-referrals" label="Select time range for sales data" />
</div>
</div>
<Chart chartId="social-referrals" />
<Chart chartId="social-referrals" label="Social referrals" />
</div>
</div>
@@ -15,5 +15,5 @@ import Trending from '@ui/Trending.astro'
</div>
<div class="text-secondary mt-2">24,635 users increased from last month</div>
</div>
<Chart chartId="visitors" height={6} />
<Chart chartId="visitors" height={6} label="Total users" />
</div>
+13 -10
View File
@@ -10,6 +10,8 @@ interface Props {
const { horizontal = false, title = 'Basic form' } = Astro.props
const labelClass = horizontal ? 'col-3 col-form-label' : 'form-label'
// The card renders twice on demo pages (basic + horizontal), so ids need a suffix
const idSuffix = horizontal ? '-horizontal' : ''
---
<form class="card h-100">
@@ -18,25 +20,25 @@ const labelClass = horizontal ? 'col-3 col-form-label' : 'form-label'
</div>
<div class="card-body">
<div class:list={['mb-3', horizontal && 'row']}>
<label class={`${labelClass} required`}>Email address</label>
<label class={`${labelClass} required`} for={`form-layout-email${idSuffix}`}>Email address</label>
<div class={horizontal ? 'col' : undefined}>
<input type="email" class="form-control" aria-describedby="emailHelp" placeholder="Enter email" />
<FormHint as="small">We'll never share your email with anyone else.</FormHint>
<input type="email" id={`form-layout-email${idSuffix}`} class="form-control" aria-describedby={`form-layout-email-hint${idSuffix}`} aria-required="true" placeholder="Enter email" autocomplete="email" />
<FormHint as="small" id={`form-layout-email-hint${idSuffix}`}>We'll never share your email with anyone else.</FormHint>
</div>
</div>
<div class:list={['mb-3', horizontal && 'row']}>
<label class={`${labelClass} required`}>Password</label>
<label class={`${labelClass} required`} for={`form-layout-password${idSuffix}`}>Password</label>
<div class={horizontal ? 'col' : undefined}>
<input type="password" class="form-control" placeholder="Password" />
<FormHint as="small"> Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji. </FormHint>
<input type="password" id={`form-layout-password${idSuffix}`} class="form-control" aria-describedby={`form-layout-password-hint${idSuffix}`} aria-required="true" placeholder="Password" />
<FormHint as="small" id={`form-layout-password-hint${idSuffix}`}> Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji. </FormHint>
</div>
</div>
<div class:list={['mb-3', horizontal && 'row']}>
<label class={labelClass}>Select</label>
<label class={labelClass} for={`form-layout-select${idSuffix}`}>Select</label>
<div class={horizontal ? 'col' : undefined}>
<select class="form-select">
<select class="form-select" id={`form-layout-select${idSuffix}`}>
<option>Option 1</option>
<optgroup label="Optgroup 1">
<option>Option 1</option>
@@ -59,7 +61,8 @@ const labelClass = horizontal ? 'col-3 col-form-label' : 'form-label'
<div class={horizontal ? 'row' : 'mb-3'}>
<label class={horizontal ? 'col-3 col-form-label pt-0' : 'form-label'}>Checkboxes</label>
<div class={horizontal ? 'col' : undefined}>
<fieldset class={horizontal ? 'col' : undefined}>
<legend class="visually-hidden">Checkboxes</legend>
<label class="form-check">
<input class="form-check-input" type="checkbox" checked />
<span class="form-check-label">Option 1</span>
@@ -72,7 +75,7 @@ const labelClass = horizontal ? 'col-3 col-form-label' : 'form-label'
<input class="form-check-input" type="checkbox" disabled />
<span class="form-check-label">Option 3</span>
</label>
</div>
</fieldset>
</div>
</div>
<div class="card-footer">
+13 -13
View File
@@ -12,28 +12,28 @@ import FormGroup from '@ui/FormGroup.astro'
<CardTitle>Payment Method</CardTitle>
<CardSubtitle class="mb-4">All transactions are secure and encrypted</CardSubtitle>
<FormGroup label="Name on Card">
<input type="text" class="form-control" placeholder="John Doe" />
<FormGroup label="Name on Card" for="payment-form-name">
<input type="text" id="payment-form-name" class="form-control" placeholder="John Doe" autocomplete="cc-name" />
</FormGroup>
<div class="row">
<div class="col-8">
<FormGroup label="Card Number">
<input type="text" class="form-control" placeholder="1234 5678 9012 3456" />
<FormHint as="small">Enter your 16-digit number.</FormHint>
<FormGroup label="Card Number" for="payment-form-number">
<input type="text" id="payment-form-number" class="form-control" placeholder="1234 5678 9012 3456" autocomplete="cc-number" aria-describedby="payment-form-number-hint" />
<FormHint as="small" id="payment-form-number-hint">Enter your 16-digit number.</FormHint>
</FormGroup>
</div>
<div class="col-4">
<FormGroup label="CVV">
<input type="text" class="form-control" placeholder="123" />
<FormGroup label="CVV" for="payment-form-cvv">
<input type="text" id="payment-form-cvv" class="form-control" placeholder="123" autocomplete="cc-csc" />
</FormGroup>
</div>
</div>
<div class="row">
<div class="col-6">
<FormGroup label="Month">
<select class="form-select">
<FormGroup label="Month" for="payment-form-exp-month">
<select id="payment-form-exp-month" class="form-select" autocomplete="cc-exp-month">
<option value="">MM</option>
<option value="1">January</option>
<option value="2">February</option>
@@ -51,8 +51,8 @@ import FormGroup from '@ui/FormGroup.astro'
</FormGroup>
</div>
<div class="col-6">
<FormGroup label="Year">
<select class="form-select">
<FormGroup label="Year" for="payment-form-exp-year">
<select id="payment-form-exp-year" class="form-select" autocomplete="cc-exp-year">
<option value="">YYYY</option>
<option value="2025">2025</option>
<option value="2026">2026</option>
@@ -79,8 +79,8 @@ import FormGroup from '@ui/FormGroup.astro'
<hr class="my-4" />
<FormGroup label="Comments">
<textarea class="form-control" rows="3" placeholder="Add any additional comments"></textarea>
<FormGroup label="Comments" for="payment-form-comments">
<textarea id="payment-form-comments" class="form-control" rows="3" placeholder="Add any additional comments"></textarea>
</FormGroup>
<div class="mt-4">
+18 -18
View File
@@ -15,25 +15,25 @@ const states = (selects as { states: { options: Record<string, { name: string; s
<div class="form-control-plaintext">Input value</div>
</FormGroup>
<FormGroup label="Text">
<input type="text" class="form-control" name="example-text-input" placeholder="Input placeholder" />
<FormGroup label="Text" for="fe1-text">
<input type="text" class="form-control" id="fe1-text" name="example-text-input" placeholder="Input placeholder" />
</FormGroup>
<FormGroup label="Password">
<input type="text" class="form-control" name="example-password-input" placeholder="Input placeholder" />
<FormGroup label="Password" for="fe1-password">
<input type="text" class="form-control" id="fe1-password" name="example-password-input" placeholder="Input placeholder" />
</FormGroup>
<FormGroup label="Disabled">
<input type="text" class="form-control" name="example-disabled-input" placeholder="Disabled..." value="Well, she turned me into a newt." disabled />
<FormGroup label="Disabled" for="fe1-disabled">
<input type="text" class="form-control" id="fe1-disabled" name="example-disabled-input" placeholder="Disabled..." value="Well, she turned me into a newt." disabled />
</FormGroup>
<FormGroup label="Readonly">
<input type="text" class="form-control" name="example-disabled-input" placeholder="Readonly..." value="Well, how'd you become king, then?" readonly />
<FormGroup label="Readonly" for="fe1-readonly">
<input type="text" class="form-control" id="fe1-readonly" name="example-disabled-input" placeholder="Readonly..." value="Well, how'd you become king, then?" readonly />
</FormGroup>
<FormGroup label="Required" required>
<input type="text" class="form-control" name="example-required-input" placeholder="Required..." />
<FormGroup label="Required" required for="fe1-required">
<input type="text" class="form-control" id="fe1-required" name="example-required-input" placeholder="Required..." aria-required="true" />
</FormGroup>
<FormGroup label="Textarea" description="56/100">
<textarea class="form-control" name="example-textarea-input" rows="6" placeholder="Content..">Oh! Come and see the violence inherent in the system! Help, help, I'm being repressed! We shall say 'Ni' again to you, if you do not appease us. I'm not a witch. I'm not a witch. Camelot!</textarea>
<FormGroup label="Textarea" description="56/100" for="fe1-textarea">
<textarea class="form-control" id="fe1-textarea" name="example-textarea-input" rows="6" placeholder="Content..">Oh! Come and see the violence inherent in the system! Help, help, I'm being repressed! We shall say 'Ni' again to you, if you do not appease us. I'm not a witch. I'm not a witch. Camelot!</textarea>
</FormGroup>
<div class="mb-3">
@@ -81,9 +81,9 @@ const states = (selects as { states: { options: Record<string, { name: string; s
<input type="text" class="form-control" aria-label="Text input with dropdown button" />
</div>
</FormGroup>
<FormGroup label="Input group buttons">
<FormGroup label="Input group buttons" for="fe1-input-group-buttons">
<div class="input-group">
<input type="text" class="form-control" />
<input type="text" class="form-control" id="fe1-input-group-buttons" />
<button type="button" class="btn">Action</button>
<button data-bs-toggle="dropdown" type="button" class="btn dropdown-toggle dropdown-toggle-split"></button>
<div class="dropdown-menu dropdown-menu-end">
@@ -122,10 +122,10 @@ const states = (selects as { states: { options: Record<string, { name: string; s
<input type="text" value="" class="form-control" placeholder="Loading…" />
</div>
</FormGroup>
<FormGroup label="Separated inputs">
<FormGroup label="Separated inputs" for="fe1-separated-input">
<div class="row g-2">
<div class="col">
<input type="text" class="form-control" placeholder="Search for…" />
<input type="text" class="form-control" id="fe1-separated-input" placeholder="Search for…" />
</div>
<div class="col-auto">
<a href="#" class="btn btn-icon" aria-label="Button">
@@ -135,10 +135,10 @@ const states = (selects as { states: { options: Record<string, { name: string; s
</div>
</FormGroup>
<FormGroup label="Input with help icon">
<FormGroup label="Input with help icon" for="fe1-help-icon-input">
<div class="row g-2">
<div class="col">
<input type="text" class="form-control" placeholder="Search for…" />
<input type="text" class="form-control" id="fe1-help-icon-input" placeholder="Search for…" />
</div>
<div class="col-auto align-self-center">
<span class="form-help" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="<p>ZIP Code must be US or CDN format. You can use an extended ZIP+4 code to determine address more accurately.</p><p class='mb-0'><a href='#'>USP ZIP codes lookup tools</a></p>" data-bs-html="true">?</span>
+22 -20
View File
@@ -1,6 +1,7 @@
---
import Icon from '@ui/Icon.astro'
import FormGroup from '@ui/FormGroup.astro'
import InputGroup from '@ui/InputGroup.astro'
---
<FormGroup label="Form control rounded">
@@ -14,8 +15,8 @@ import FormGroup from '@ui/FormGroup.astro'
</div>
</FormGroup>
<FormGroup label="Form control flush">
<input type="text" class="form-control form-control-flush" name="Form control flush" placeholder="Text.." />
<FormGroup label="Form control flush" for="fe2-form-control-flush">
<input type="text" class="form-control form-control-flush" id="fe2-form-control-flush" name="Form control flush" placeholder="Text.." />
</FormGroup>
<FormGroup label="Input group">
@@ -52,45 +53,46 @@ import FormGroup from '@ui/FormGroup.astro'
</div>
</FormGroup>
<FormGroup label="Input with prepended text">
<FormGroup label="Input with prepended text" for="fe2-prepended-text">
<div class="input-group input-group-flat">
<span class="input-group-text">https://tabler.io/users/</span>
<input type="text" class="form-control ps-0" value="yourfancyusername" autocomplete="off" />
<input type="text" class="form-control ps-0" id="fe2-prepended-text" value="yourfancyusername" autocomplete="off" />
</div>
</FormGroup>
<FormGroup label="Input with appended text">
<FormGroup label="Input with appended text" for="fe2-appended-text">
<div class="input-group input-group-flat">
<input type="text" class="form-control text-end pe-0" value="yourfancydomain" autocomplete="off" />
<input type="text" class="form-control text-end pe-0" id="fe2-appended-text" value="yourfancydomain" autocomplete="off" />
<span class="input-group-text">.tabler.io</span>
</div>
</FormGroup>
<FormGroup label="Input with appended link">
<div class="input-group input-group-flat">
<input type="password" class="form-control" value="ultrastrongpassword" autocomplete="off" />
<span class="input-group-text">
<a href="#" class="input-group-link">Show password</a>
</span>
</div>
<FormGroup label="Input with appended link" for="fe2-appended-link">
<InputGroup type="password" id="fe2-appended-link" value="ultrastrongpassword" flat appendButton={[{ icon: 'eye', description: 'Show password' }]} />
</FormGroup>
<FormGroup label="Input with appended kbd">
<FormGroup label="Input with appended kbd" for="fe2-appended-kbd">
<div class="input-group input-group-flat">
<input type="text" class="form-control" autocomplete="off" />
<input type="text" class="form-control" id="fe2-appended-kbd" autocomplete="off" />
<span class="input-group-text">
<kbd>ctrl + K</kbd>
</span>
</div>
</FormGroup>
<FormGroup label="Input with appended icon links">
<FormGroup label="Input with appended icon links" for="fe2-appended-icon-links">
<div class="input-group input-group-flat">
<input type="text" class="form-control" autocomplete="off" />
<input type="text" class="form-control" id="fe2-appended-icon-links" autocomplete="off" />
<span class="input-group-text">
<a href="#" class="link-secondary" title="Clear search" data-bs-toggle="tooltip"><Icon name="x" /></a>
<a href="#" class="link-secondary ms-2" title="Search settings" data-bs-toggle="tooltip"><Icon name="adjustments" /></a>
<a href="#" class="link-secondary ms-2 disabled" title="Add notification" data-bs-toggle="tooltip"><Icon name="bell" /></a>
<button type="button" class="link-secondary border-0 bg-transparent p-0" title="Clear search" aria-label="Clear search" data-bs-toggle="tooltip">
<Icon name="x" />
</button>
<button type="button" class="link-secondary ms-2 border-0 bg-transparent p-0" title="Search settings" aria-label="Search settings" data-bs-toggle="tooltip">
<Icon name="adjustments" />
</button>
<button type="button" class="link-secondary ms-2 border-0 bg-transparent p-0" title="Add notification" aria-label="Add notification" data-bs-toggle="tooltip" disabled>
<Icon name="bell" />
</button>
</span>
</div>
</FormGroup>
+57 -47
View File
@@ -14,75 +14,85 @@ const blueHex = (site as { colors: { blue: { hex: string } } }).colors.blue.hex
---
<FormGroup label="Image Check">
<div class="row g-2">
{
imageChecks.map((photo, i) => {
const index = i + 1
return (
<div class="col-6 col-sm-4">
<label class="form-imagecheck mb-2">
<input name="form-imagecheck" type="checkbox" value={index} class="form-imagecheck-input" checked={index === 2 || index === 4 || index === 7} />
<span class="form-imagecheck-figure">
<img src={`./static/photos/${photo.file}`} alt={photo.title} class="form-imagecheck-image" />
</span>
</label>
</div>
)
})
}
</div>
<fieldset>
<legend class="visually-hidden">Image Check</legend>
<div class="row g-2">
{
imageChecks.map((photo, i) => {
const index = i + 1
return (
<div class="col-6 col-sm-4">
<label class="form-imagecheck mb-2">
<input name="form-imagecheck" type="checkbox" value={index} class="form-imagecheck-input" checked={index === 2 || index === 4 || index === 7} />
<span class="form-imagecheck-figure">
<img src={`./static/photos/${photo.file}`} alt={photo.title} class="form-imagecheck-image" />
</span>
</label>
</div>
)
})
}
</div>
</fieldset>
</FormGroup>
<FormGroup label="Image Check Radio">
<div class="row g-2">
{
imageRadios.map((photo, i) => {
const index = i + 1
return (
<div class="col-6 col-sm-4">
<label class="form-imagecheck mb-2">
<input name="form-imagecheck-radio" type="radio" value={index} class="form-imagecheck-input" checked={index === 2 || index === 4 || index === 7} />
<span class="form-imagecheck-figure">
<img src={`./static/photos/${photo.file}`} alt={photo.title} class="form-imagecheck-image" />
</span>
</label>
</div>
)
})
}
</div>
<fieldset>
<legend class="visually-hidden">Image Check Radio</legend>
<div class="row g-2">
{
imageRadios.map((photo, i) => {
const index = i + 1
return (
<div class="col-6 col-sm-4">
<label class="form-imagecheck mb-2">
<input name="form-imagecheck-radio" type="radio" value={index} class="form-imagecheck-input" checked={index === 2 || index === 4 || index === 7} />
<span class="form-imagecheck-figure">
<img src={`./static/photos/${photo.file}`} alt={photo.title} class="form-imagecheck-image" />
</span>
</label>
</div>
)
})
}
</div>
</fieldset>
</FormGroup>
<InputColor label="Color Input Check" type="checkbox" />
<InputColor label="Color Input Radio" name="color-rounded" rounded />
<FormGroup label="Color picker">
<input type="color" class="form-control form-control-color" value={blueHex} title="Choose your color" />
<FormGroup label="Color picker" for="fe3-color-picker">
<input type="color" id="fe3-color-picker" class="form-control form-control-color" value={blueHex} title="Choose your color" />
</FormGroup>
{
[false, true].map((lite) => (
<FormGroup label={`Validation States${lite ? ' (lite)' : ''}`}>
<input type="text" class:list={['form-control is-valid', lite && 'is-valid-lite', 'mb-2']} placeholder="Valid State.." />
<input type="text" class:list={['form-control is-invalid', lite && 'is-invalid-lite']} placeholder="Invalid State.." />
{!lite && <div class="invalid-feedback">Invalid feedback</div>}
<input type="text" class:list={['form-control is-valid', lite && 'is-valid-lite', 'mb-2']} placeholder="Valid State.." aria-invalid="false" />
<input type="text" class:list={['form-control is-invalid', lite && 'is-invalid-lite']} placeholder="Invalid State.." aria-invalid="true" aria-describedby={!lite ? 'validation-invalid-feedback' : undefined} />
{!lite && (
<div class="invalid-feedback" id="validation-invalid-feedback">
Invalid feedback
</div>
)}
</FormGroup>
))
}
<label class="form-label">Form fieldset</label>
<fieldset class="form-fieldset">
<FormGroup label="Full name" required>
<input type="text" class="form-control" autocomplete="off" />
<FormGroup label="Full name" required for="fe3-fieldset-name">
<input type="text" id="fe3-fieldset-name" class="form-control" autocomplete="name" aria-required="true" />
</FormGroup>
<FormGroup label="Company" required>
<input type="text" class="form-control" autocomplete="off" />
<FormGroup label="Company" required for="fe3-fieldset-company">
<input type="text" id="fe3-fieldset-company" class="form-control" autocomplete="organization" aria-required="true" />
</FormGroup>
<FormGroup label="Email" required>
<input type="email" class="form-control" autocomplete="off" />
<FormGroup label="Email" required for="fe3-fieldset-email">
<input type="email" id="fe3-fieldset-email" class="form-control" autocomplete="email" aria-required="true" />
</FormGroup>
<FormGroup label="Phone number">
<input type="tel" class="form-control" autocomplete="off" />
<FormGroup label="Phone number" for="fe3-fieldset-phone">
<input type="tel" id="fe3-fieldset-phone" class="form-control" autocomplete="tel" />
</FormGroup>
<label class="form-check">
<input type="checkbox" class="form-check-input" />
+288 -255
View File
@@ -6,309 +6,342 @@ import Avatar from '@ui/Avatar.astro'
---
<FormGroup label="Simple selectgroup">
<div class="form-selectgroup">
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="HTML" class="form-selectgroup-input" checked />
<span class="form-selectgroup-label">HTML</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="CSS" class="form-selectgroup-input" />
<span class="form-selectgroup-label">CSS</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="PHP" class="form-selectgroup-input" />
<span class="form-selectgroup-label">PHP</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="JavaScript" class="form-selectgroup-input" />
<span class="form-selectgroup-label">JavaScript</span>
</label>
</div>
<fieldset>
<legend class="visually-hidden">Simple selectgroup</legend>
<div class="form-selectgroup">
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="HTML" class="form-selectgroup-input" checked />
<span class="form-selectgroup-label">HTML</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="CSS" class="form-selectgroup-input" />
<span class="form-selectgroup-label">CSS</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="PHP" class="form-selectgroup-input" />
<span class="form-selectgroup-label">PHP</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="JavaScript" class="form-selectgroup-input" />
<span class="form-selectgroup-label">JavaScript</span>
</label>
</div>
</fieldset>
</FormGroup>
<FormGroup label="Icon input">
<div class="form-selectgroup">
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="sun" class="form-selectgroup-input" checked />
<span class="form-selectgroup-label"><Icon name="sun" /></span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="moon" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="moon" /></span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="cloud-rain" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="cloud-rain" /></span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="cloud" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="cloud" /></span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="Other" class="form-selectgroup-input" />
<span class="form-selectgroup-label">Other</span>
</label>
</div>
<fieldset>
<legend class="visually-hidden">Icon input</legend>
<div class="form-selectgroup">
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="sun" class="form-selectgroup-input" checked />
<span class="form-selectgroup-label"><Icon name="sun" /></span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="moon" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="moon" /></span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="cloud-rain" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="cloud-rain" /></span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="cloud" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="cloud" /></span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="Other" class="form-selectgroup-input" />
<span class="form-selectgroup-label">Other</span>
</label>
</div>
</fieldset>
</FormGroup>
<FormGroup label="Selectgroup with icons and text">
<div class="form-selectgroup">
<label class="form-selectgroup-item">
<input type="radio" name="icons" value="home" class="form-selectgroup-input" checked />
<span class="form-selectgroup-label"><Icon name="home" class="me-1" /> Home</span>
</label>
<label class="form-selectgroup-item">
<input type="radio" name="icons" value="user" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="user" class="me-1" /> User</span>
</label>
<label class="form-selectgroup-item">
<input type="radio" name="icons" value="circle" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="circle" class="me-1" /> Circle</span>
</label>
<label class="form-selectgroup-item">
<input type="radio" name="icons" value="square" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="square" class="me-1" /> Square</span>
</label>
</div>
<fieldset>
<legend class="visually-hidden">Selectgroup with icons and text</legend>
<div class="form-selectgroup">
<label class="form-selectgroup-item">
<input type="radio" name="icons" value="home" class="form-selectgroup-input" checked />
<span class="form-selectgroup-label"><Icon name="home" class="me-1" /> Home</span>
</label>
<label class="form-selectgroup-item">
<input type="radio" name="icons" value="user" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="user" class="me-1" /> User</span>
</label>
<label class="form-selectgroup-item">
<input type="radio" name="icons" value="circle" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="circle" class="me-1" /> Circle</span>
</label>
<label class="form-selectgroup-item">
<input type="radio" name="icons" value="square" class="form-selectgroup-input" />
<span class="form-selectgroup-label"><Icon name="square" class="me-1" /> Square</span>
</label>
</div>
</fieldset>
</FormGroup>
<FormGroup label="Different style">
<div class="form-selectgroup form-selectgroup-pills">
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="HTML" class="form-selectgroup-input" checked />
<span class="form-selectgroup-label">HTML</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="CSS" class="form-selectgroup-input" />
<span class="form-selectgroup-label">CSS</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="PHP" class="form-selectgroup-input" />
<span class="form-selectgroup-label">PHP</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="JavaScript" class="form-selectgroup-input" />
<span class="form-selectgroup-label">JavaScript</span>
</label>
</div>
<fieldset>
<legend class="visually-hidden">Different style</legend>
<div class="form-selectgroup form-selectgroup-pills">
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="HTML" class="form-selectgroup-input" checked />
<span class="form-selectgroup-label">HTML</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="CSS" class="form-selectgroup-input" />
<span class="form-selectgroup-label">CSS</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="PHP" class="form-selectgroup-input" />
<span class="form-selectgroup-label">PHP</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="name" value="JavaScript" class="form-selectgroup-input" />
<span class="form-selectgroup-label">JavaScript</span>
</label>
</div>
</fieldset>
</FormGroup>
<FormGroup label="Payment method">
<div class="form-selectgroup form-selectgroup-boxes d-flex flex-column">
<label class="form-selectgroup-item flex-fill">
<input type="radio" name="form-payment" value="visa" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
<fieldset>
<legend class="visually-hidden">Payment method</legend>
<div class="form-selectgroup form-selectgroup-boxes d-flex flex-column">
<label class="form-selectgroup-item flex-fill">
<input type="radio" name="form-payment" value="visa" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div>
<span class="payment payment-provider-visa payment-xs me-2"></span>
ending in <strong>7998</strong>
</div>
</div>
<div>
<span class="payment payment-provider-visa payment-xs me-2"></span>
ending in <strong>7998</strong>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="radio" name="form-payment" value="mastercard" class="form-selectgroup-input" checked />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div>
<span class="payment payment-provider-mastercard payment-xs me-2"></span>
ending in <strong>1000</strong>
</div>
</div>
</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="radio" name="form-payment" value="mastercard" class="form-selectgroup-input" checked />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="radio" name="form-payment" value="paypal" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div>
<span class="payment payment-provider-paypal payment-xs me-2"></span>
</div>
</div>
<div>
<span class="payment payment-provider-mastercard payment-xs me-2"></span>
ending in <strong>1000</strong>
</div>
</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="radio" name="form-payment" value="paypal" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div>
<span class="payment payment-provider-paypal payment-xs me-2"></span>
</div>
</div>
</label>
</div>
</label>
</div>
</fieldset>
</FormGroup>
<FormGroup label="Project Manager">
<div class="form-selectgroup form-selectgroup-boxes d-flex flex-column">
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="1" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/000m.jpg" class="me-3" />
<div>
<div class="fw-medium">Paweł Kuna</div>
<div class="text-secondary">UI Designer</div>
<fieldset>
<legend class="visually-hidden">Project Manager</legend>
<div class="form-selectgroup form-selectgroup-boxes d-flex flex-column">
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="1" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/000m.jpg" class="me-3" />
<div>
<div class="fw-medium">Paweł Kuna</div>
<div class="text-secondary">UI Designer</div>
</div>
</div>
</div>
</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="2" class="form-selectgroup-input" checked />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/052f.jpg" class="me-3" />
<div>
<div class="fw-medium">Jeffie Lewzey</div>
<div class="text-secondary">Chemical Engineer</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="2" class="form-selectgroup-input" checked />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/052f.jpg" class="me-3" />
<div>
<div class="fw-medium">Jeffie Lewzey</div>
<div class="text-secondary">Chemical Engineer</div>
</div>
</div>
</div>
</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="3" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/002m.jpg" class="me-3" />
<div>
<div class="fw-medium">Mallory Hulme</div>
<div class="text-secondary">Geologist IV</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="3" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/002m.jpg" class="me-3" />
<div>
<div class="fw-medium">Mallory Hulme</div>
<div class="text-secondary">Geologist IV</div>
</div>
</div>
</div>
</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="4" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/003m.jpg" class="me-3" />
<div>
<div class="fw-medium">Dunn Slane</div>
<div class="text-secondary">Research Nurse</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="4" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/003m.jpg" class="me-3" />
<div>
<div class="fw-medium">Dunn Slane</div>
<div class="text-secondary">Research Nurse</div>
</div>
</div>
</div>
</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="5" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/000f.jpg" class="me-3" />
<div>
<div class="fw-medium">Emmy Levet</div>
<div class="text-secondary">VP Product Management</div>
</label>
<label class="form-selectgroup-item flex-fill">
<input type="checkbox" name="form-project-manager[]" value="5" class="form-selectgroup-input" />
<div class="form-selectgroup-label d-flex align-items-center p-3">
<div class="me-3">
<span class="form-selectgroup-check"></span>
</div>
<div class="form-selectgroup-label-content d-flex align-items-center">
<Avatar src="static/avatars/000f.jpg" class="me-3" />
<div>
<div class="fw-medium">Emmy Levet</div>
<div class="text-secondary">VP Product Management</div>
</div>
</div>
</div>
</div>
</label>
</div>
</label>
</div>
</fieldset>
</FormGroup>
<FormGroup label="Buttons group">
<ButtonGroup class="w-100">
<input type="radio" class="btn-check" name="btn-radio-basic" id="btn-radio-basic-1" autocomplete="off" checked />
<label for="btn-radio-basic-1" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">1 min</label>
<input type="radio" class="btn-check" name="btn-radio-basic" id="btn-radio-basic-2" autocomplete="off" />
<label for="btn-radio-basic-2" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">5 min</label>
<input type="radio" class="btn-check" name="btn-radio-basic" id="btn-radio-basic-3" autocomplete="off" />
<label for="btn-radio-basic-3" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">10 min</label>
<input type="radio" class="btn-check" name="btn-radio-basic" id="btn-radio-basic-4" autocomplete="off" />
<label for="btn-radio-basic-4" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">30 min</label>
</ButtonGroup>
<fieldset>
<legend class="visually-hidden">Buttons group</legend>
<ButtonGroup class="w-100">
<input type="radio" class="btn-check" name="btn-radio-basic" id="btn-radio-basic-1" autocomplete="off" checked />
<label for="btn-radio-basic-1" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">1 min</label>
<input type="radio" class="btn-check" name="btn-radio-basic" id="btn-radio-basic-2" autocomplete="off" />
<label for="btn-radio-basic-2" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">5 min</label>
<input type="radio" class="btn-check" name="btn-radio-basic" id="btn-radio-basic-3" autocomplete="off" />
<label for="btn-radio-basic-3" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">10 min</label>
<input type="radio" class="btn-check" name="btn-radio-basic" id="btn-radio-basic-4" autocomplete="off" />
<label for="btn-radio-basic-4" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">30 min</label>
</ButtonGroup>
</fieldset>
</FormGroup>
<FormGroup label="Buttons group with dropdown">
<ButtonGroup class="w-100">
<input type="radio" class="btn-check" name="btn-radio-dropdown" id="btn-radio-dropdown-1" autocomplete="off" checked />
<label for="btn-radio-dropdown-1" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Option 1</label>
<input type="radio" class="btn-check" name="btn-radio-dropdown" id="btn-radio-dropdown-2" autocomplete="off" />
<label for="btn-radio-dropdown-2" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Option 2</label>
<ButtonGroup>
<input type="radio" class="btn-check" name="btn-radio-dropdown" id="btn-radio-dropdown-dropdown" autocomplete="off" />
<label for="btn-radio-dropdown-dropdown" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Other </label>
<div class="dropdown-menu">
<a class="dropdown-item" href="#"> Action </a>
<a class="dropdown-item" href="#"> Another action </a>
</div>
<div class="dropdown-menu dropdown-menu-end">
<a class="dropdown-item" href="#"> Option 4 </a>
<a class="dropdown-item" href="#"> Option 5 </a>
<a class="dropdown-item" href="#"> Option 6 </a>
</div>
<fieldset>
<legend class="visually-hidden">Buttons group with dropdown</legend>
<ButtonGroup class="w-100">
<input type="radio" class="btn-check" name="btn-radio-dropdown" id="btn-radio-dropdown-1" autocomplete="off" checked />
<label for="btn-radio-dropdown-1" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Option 1</label>
<input type="radio" class="btn-check" name="btn-radio-dropdown" id="btn-radio-dropdown-2" autocomplete="off" />
<label for="btn-radio-dropdown-2" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Option 2</label>
<ButtonGroup>
<input type="radio" class="btn-check" name="btn-radio-dropdown" id="btn-radio-dropdown-dropdown" autocomplete="off" />
<label for="btn-radio-dropdown-dropdown" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Other </label>
<div class="dropdown-menu">
<a class="dropdown-item" href="#"> Action </a>
<a class="dropdown-item" href="#"> Another action </a>
</div>
<div class="dropdown-menu dropdown-menu-end">
<a class="dropdown-item" href="#"> Option 4 </a>
<a class="dropdown-item" href="#"> Option 5 </a>
<a class="dropdown-item" href="#"> Option 6 </a>
</div>
</ButtonGroup>
</ButtonGroup>
</ButtonGroup>
</fieldset>
</FormGroup>
<div class="row">
<div class="col">
<FormGroup label="Vertical buttons group">
<ButtonGroup vertical={true} class="w-100">
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-1" autocomplete="off" checked />
<label for="btn-radio-vertical-1" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 1</label>
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-2" autocomplete="off" />
<label for="btn-radio-vertical-2" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 2</label>
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-3" autocomplete="off" />
<label for="btn-radio-vertical-3" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 3</label>
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-4" autocomplete="off" />
<label for="btn-radio-vertical-4" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 4</label>
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-5" autocomplete="off" />
<label for="btn-radio-vertical-5" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 5</label>
</ButtonGroup>
<fieldset>
<legend class="visually-hidden">Vertical buttons group</legend>
<ButtonGroup vertical={true} class="w-100">
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-1" autocomplete="off" checked />
<label for="btn-radio-vertical-1" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 1</label>
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-2" autocomplete="off" />
<label for="btn-radio-vertical-2" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 2</label>
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-3" autocomplete="off" />
<label for="btn-radio-vertical-3" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 3</label>
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-4" autocomplete="off" />
<label for="btn-radio-vertical-4" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 4</label>
<input type="radio" class="btn-check" name="btn-radio-vertical" id="btn-radio-vertical-5" autocomplete="off" />
<label for="btn-radio-vertical-5" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 5</label>
</ButtonGroup>
</fieldset>
</FormGroup>
</div>
<div class="col">
<FormGroup label="Vertical with dropdown">
<ButtonGroup vertical={true} class="w-100">
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-1" autocomplete="off" checked />
<label for="btn-radio-vertical-dropdown-1" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 1</label>
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-2" autocomplete="off" />
<label for="btn-radio-vertical-dropdown-2" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 2</label>
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-3" autocomplete="off" />
<label for="btn-radio-vertical-dropdown-3" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 3</label>
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-4" autocomplete="off" />
<label for="btn-radio-vertical-dropdown-4" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 4</label>
<ButtonGroup>
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-dropdown" autocomplete="off" />
<label for="btn-radio-vertical-dropdown-dropdown" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Other </label>
<div class="dropdown-menu">
<a class="dropdown-item" href="#"> Action </a>
<a class="dropdown-item" href="#"> Another action </a>
</div>
<div class="dropdown-menu dropdown-menu-end">
<a class="dropdown-item" href="#"> Option 4 </a>
<a class="dropdown-item" href="#"> Option 5 </a>
<a class="dropdown-item" href="#"> Option 6 </a>
</div>
<fieldset>
<legend class="visually-hidden">Vertical with dropdown</legend>
<ButtonGroup vertical={true} class="w-100">
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-1" autocomplete="off" checked />
<label for="btn-radio-vertical-dropdown-1" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 1</label>
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-2" autocomplete="off" />
<label for="btn-radio-vertical-dropdown-2" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 2</label>
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-3" autocomplete="off" />
<label for="btn-radio-vertical-dropdown-3" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 3</label>
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-4" autocomplete="off" />
<label for="btn-radio-vertical-dropdown-4" {...{ type: 'button' } as unknown as astroHTML.JSX.LabelHTMLAttributes} class="btn">Button 4</label>
<ButtonGroup>
<input type="radio" class="btn-check" name="btn-radio-vertical-dropdown" id="btn-radio-vertical-dropdown-dropdown" autocomplete="off" />
<label for="btn-radio-vertical-dropdown-dropdown" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Other </label>
<div class="dropdown-menu">
<a class="dropdown-item" href="#"> Action </a>
<a class="dropdown-item" href="#"> Another action </a>
</div>
<div class="dropdown-menu dropdown-menu-end">
<a class="dropdown-item" href="#"> Option 4 </a>
<a class="dropdown-item" href="#"> Option 5 </a>
<a class="dropdown-item" href="#"> Option 6 </a>
</div>
</ButtonGroup>
</ButtonGroup>
</ButtonGroup>
</fieldset>
</FormGroup>
</div>
</div>
<FormGroup label="Toolbar">
<ButtonGroup class="w-100">
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-1" autocomplete="off" checked />
<label for="btn-radio-toolbar-1" class="btn btn-icon"><Icon name="bold" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-2" autocomplete="off" />
<label for="btn-radio-toolbar-2" class="btn btn-icon"><Icon name="italic" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-3" autocomplete="off" />
<label for="btn-radio-toolbar-3" class="btn btn-icon"><Icon name="underline" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-4" autocomplete="off" />
<label for="btn-radio-toolbar-4" class="btn btn-icon"><Icon name="copy" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-5" autocomplete="off" />
<label for="btn-radio-toolbar-5" class="btn btn-icon"><Icon name="scissors" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-6" autocomplete="off" />
<label for="btn-radio-toolbar-6" class="btn btn-icon"><Icon name="file-plus" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-7" autocomplete="off" />
<label for="btn-radio-toolbar-7" class="btn btn-icon"><Icon name="file-minus" /></label>
</ButtonGroup>
<fieldset>
<legend class="visually-hidden">Toolbar</legend>
<ButtonGroup class="w-100">
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-1" autocomplete="off" checked />
<label for="btn-radio-toolbar-1" class="btn btn-icon"><Icon name="bold" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-2" autocomplete="off" />
<label for="btn-radio-toolbar-2" class="btn btn-icon"><Icon name="italic" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-3" autocomplete="off" />
<label for="btn-radio-toolbar-3" class="btn btn-icon"><Icon name="underline" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-4" autocomplete="off" />
<label for="btn-radio-toolbar-4" class="btn btn-icon"><Icon name="copy" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-5" autocomplete="off" />
<label for="btn-radio-toolbar-5" class="btn btn-icon"><Icon name="scissors" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-6" autocomplete="off" />
<label for="btn-radio-toolbar-6" class="btn btn-icon"><Icon name="file-plus" /></label>
<input type="radio" class="btn-check" name="btn-radio-toolbar" id="btn-radio-toolbar-7" autocomplete="off" />
<label for="btn-radio-toolbar-7" class="btn btn-icon"><Icon name="file-minus" /></label>
</ButtonGroup>
</fieldset>
</FormGroup>
+84 -71
View File
@@ -4,7 +4,8 @@ import FormGroup from '@ui/FormGroup.astro'
<div class="mb-3">
<div class="form-label">Radios</div>
<div>
<fieldset>
<legend class="visually-hidden">Radios</legend>
<label class="form-check">
<input class="form-check-input" type="radio" name="radios" checked />
<span class="form-check-label">Option 1</span>
@@ -21,12 +22,13 @@ import FormGroup from '@ui/FormGroup.astro'
<input class="form-check-input" type="radio" checked disabled />
<span class="form-check-label">Option 4</span>
</label>
</div>
</fieldset>
</div>
<div class="mb-3">
<div class="form-label">Inline Radios</div>
<div>
<fieldset>
<legend class="visually-hidden">Inline Radios</legend>
<label class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="radios-inline" checked />
<span class="form-check-label">Option 1</span>
@@ -39,12 +41,13 @@ import FormGroup from '@ui/FormGroup.astro'
<input class="form-check-input" type="radio" name="radios-inline" disabled />
<span class="form-check-label">Option 3</span>
</label>
</div>
</fieldset>
</div>
<div class="mb-3">
<div class="form-label">Checkboxes</div>
<div>
<fieldset>
<legend class="visually-hidden">Checkboxes</legend>
<label class="form-check">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label">Checkbox input</span>
@@ -57,12 +60,13 @@ import FormGroup from '@ui/FormGroup.astro'
<input class="form-check-input" type="checkbox" checked />
<span class="form-check-label">Checked checkbox input</span>
</label>
</div>
</fieldset>
</div>
<div class="mb-3">
<div class="form-label">Inline Checkboxes</div>
<div>
<fieldset>
<legend class="visually-hidden">Inline Checkboxes</legend>
<label class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label">Option 1</span>
@@ -75,40 +79,46 @@ import FormGroup from '@ui/FormGroup.astro'
<input class="form-check-input" type="checkbox" checked />
<span class="form-check-label">Option 3</span>
</label>
</div>
</fieldset>
</div>
<FormGroup label="Checkboxes with description">
<label class="form-check">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label"> Default checkbox </span>
<span class="form-check-description"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. </span>
</label>
<label class="form-check">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label"> Longer checkbox item that wraps on to two separate lines </span>
<span class="form-check-description"> Ab alias aut, consequuntur cumque esse eveniet incidunt laborum minus molestiae. </span>
</label>
<label class="form-check">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label"> Default checkbox without description </span>
</label>
<fieldset>
<legend class="visually-hidden">Checkboxes with description</legend>
<label class="form-check">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label"> Default checkbox </span>
<span class="form-check-description"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. </span>
</label>
<label class="form-check">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label"> Longer checkbox item that wraps on to two separate lines </span>
<span class="form-check-description"> Ab alias aut, consequuntur cumque esse eveniet incidunt laborum minus molestiae. </span>
</label>
<label class="form-check">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label"> Default checkbox without description </span>
</label>
</fieldset>
</FormGroup>
<div class="mb-3">
<div class="form-label">Toggle switches</div>
<label class="form-check form-switch">
<input class="form-check-input" type="checkbox" checked />
<span class="form-check-label">Option 1</span>
</label>
<label class="form-check form-switch">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label">Option 2</span>
</label>
<label class="form-check form-switch">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label">Option 3</span>
</label>
<fieldset>
<legend class="visually-hidden">Toggle switches</legend>
<label class="form-check form-switch">
<input class="form-check-input" type="checkbox" checked />
<span class="form-check-label">Option 1</span>
</label>
<label class="form-check form-switch">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label">Option 2</span>
</label>
<label class="form-check form-switch">
<input class="form-check-input" type="checkbox" />
<span class="form-check-label">Option 3</span>
</label>
</fieldset>
</div>
<div class="mb-3">
@@ -120,38 +130,41 @@ import FormGroup from '@ui/FormGroup.astro'
</div>
<FormGroup label="Notification">
<div class="divide-y">
<div>
<label class="row">
<span class="col">Push Notifications</span>
<span class="col-auto">
<label class="form-check form-check-single form-switch">
<input class="form-check-input" type="checkbox" checked />
</label>
</span>
</label>
<fieldset>
<legend class="visually-hidden">Notification</legend>
<div class="divide-y">
<div>
<label class="row">
<span class="col">Push Notifications</span>
<span class="col-auto">
<label class="form-check form-check-single form-switch">
<input class="form-check-input" type="checkbox" checked />
</label>
</span>
</label>
</div>
<div>
<label class="row">
<span class="col">SMS Notifications</span>
<span class="col-auto">
<label class="form-check form-check-single form-switch">
<input class="form-check-input" type="checkbox" />
</label>
</span>
</label>
</div>
<div>
<label class="row">
<span class="col">Email Notifications</span>
<span class="col-auto">
<label class="form-check form-check-single form-switch">
<input class="form-check-input" type="checkbox" checked />
</label>
</span>
</label>
</div>
</div>
<div>
<label class="row">
<span class="col">SMS Notifications</span>
<span class="col-auto">
<label class="form-check form-check-single form-switch">
<input class="form-check-input" type="checkbox" />
</label>
</span>
</label>
</div>
<div>
<label class="row">
<span class="col">Email Notifications</span>
<span class="col-auto">
<label class="form-check form-check-single form-switch">
<input class="form-check-input" type="checkbox" checked />
</label>
</span>
</label>
</div>
</div>
</fieldset>
</FormGroup>
<div class="mb-3">
@@ -340,13 +353,13 @@ import FormGroup from '@ui/FormGroup.astro'
</div>
</FormGroup>
<FormGroup label="Text mask">
<input type="text" name="input-mask" class="form-control" data-mask="00/00/0000" data-mask-visible="true" placeholder="00/00/0000" autocomplete="off" />
<FormGroup label="Text mask" for="fe5-input-mask-date">
<input type="text" name="input-mask" id="fe5-input-mask-date" class="form-control" data-mask="00/00/0000" data-mask-visible="true" placeholder="00/00/0000" autocomplete="off" />
</FormGroup>
<FormGroup label="Telephone mask">
<input type="text" name="input-mask" class="form-control" data-mask="(00) 0000-0000" data-mask-visible="true" placeholder="(00) 0000-0000" autocomplete="off" />
<FormGroup label="Telephone mask" for="fe5-input-mask-tel">
<input type="text" name="input-mask" id="fe5-input-mask-tel" class="form-control" data-mask="(00) 0000-0000" data-mask-visible="true" placeholder="(00) 0000-0000" autocomplete="off" />
</FormGroup>
<FormGroup label="Autosize textarea">
<textarea class="form-control" data-bs-toggle="autosize" placeholder="Type something…"></textarea>
<FormGroup label="Autosize textarea" for="fe5-textarea-autosize">
<textarea class="form-control" id="fe5-textarea-autosize" data-bs-toggle="autosize" placeholder="Type something…"></textarea>
</FormGroup>
+15 -14
View File
@@ -11,8 +11,8 @@ import Select from '@ui/Select.astro'
const datalistCountries = (flags as { name: string }[]).slice(0, 10)
---
<FormGroup label="Datalist example">
<input class="form-control" list="datalistOptions" placeholder="Type to search..." />
<FormGroup label="Datalist example" for="fe6-datalist">
<input class="form-control" id="fe6-datalist" list="datalistOptions" placeholder="Type to search..." />
<datalist id="datalistOptions">
{datalistCountries.map((country) => <option value={country.name} />)}
</datalist>
@@ -31,6 +31,7 @@ const datalistCountries = (flags as { name: string }[]).slice(0, 10)
<Datepicker id="icon-prepend" layout="icon-prepend" />
</FormGroup>
{/* Inline datepicker renders a calendar div (`datepicker-inline`), not a labelable input — `for` intentionally skipped, same as Range. */}
<FormGroup label="Inline datepicker">
<Datepicker id="inline" inline />
</FormGroup>
@@ -51,28 +52,28 @@ const datalistCountries = (flags as { name: string }[]).slice(0, 10)
</div>
</FormGroup>
<FormGroup label="Tags input">
<Select key="tags" placeholder="Select tags" />
<FormGroup label="Tags input" for="select-fe6-tags">
<Select id="fe6-tags" key="tags" placeholder="Select tags" />
</FormGroup>
<FormGroup label="Advanced select">
<Select key="users" />
<FormGroup label="Advanced select" for="select-fe6-advanced-select">
<Select id="fe6-advanced-select" key="users" />
</FormGroup>
<FormGroup label="Advanced select with optgroup">
<Select key="optgroups" />
<FormGroup label="Advanced select with optgroup" for="select-fe6-select-optgroup">
<Select id="fe6-select-optgroup" key="optgroups" />
</FormGroup>
<FormGroup label="Select with avatars">
<Select key="people" indicator="avatar" />
<FormGroup label="Select with avatars" for="select-fe6-select-avatars">
<Select id="fe6-select-avatars" key="people" indicator="avatar" />
</FormGroup>
<FormGroup label="Select with flags">
<Select key="countries" indicator="flag" />
<FormGroup label="Select with flags" for="select-fe6-select-flags">
<Select id="fe6-select-flags" key="countries" indicator="flag" />
</FormGroup>
<FormGroup label="Select with labels">
<Select key="labels" indicator="label" />
<FormGroup label="Select with labels" for="select-fe6-select-labels">
<Select id="fe6-select-labels" key="labels" indicator="label" />
</FormGroup>
<FormGroup label="Advanced select with validation state">
+1 -1
View File
@@ -17,7 +17,7 @@ import ButtonList from '@ui/ButtonList.astro'
</div>
<div class="col">
<h2 class="page-title">tabler.io/icons</h2>
<h1 class="page-title">tabler.io/icons</h1>
<div class="text-secondary">
<ul class="list-inline list-inline-dots mb-0">
<li class="list-inline-item"><span class="text-green">Up</span></li>
+4 -4
View File
@@ -39,14 +39,14 @@ const typedId = 'typed'
<Illustration image="computer-fix.svg" class="d-block mx-auto" height="350" />
</div>
</div>
<a class="carousel-control-prev text-secondary" href="#carousel-controls" role="button" data-bs-slide="prev">
<button type="button" class="carousel-control-prev text-secondary" data-bs-target="#carousel-controls" data-bs-slide="prev">
<Icon name="chevron-left" class="icon-md" />
<span class="visually-hidden">Previous</span>
</a>
<a class="carousel-control-next text-secondary" href="#carousel-controls" role="button" data-bs-slide="next">
</button>
<button type="button" class="carousel-control-next text-secondary" data-bs-target="#carousel-controls" data-bs-slide="next">
<Icon name="chevron-right" class="icon-md" />
<span class="visually-hidden">Next</span>
</a>
</button>
</div>
</div>
</div>
@@ -12,30 +12,30 @@ const selectedPeople = ['5', '6', '2', '3'].map((idStr) => (people as Person[])[
---
<div class="modal-header">
<h4 class="modal-title">Add task</h4>
<h4 class="modal-title" id="modal-add-task-title">Add task</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<FormGroup label="Name">
<input type="text" class="form-control" placeholder="Task name" />
<FormGroup label="Name" for="add-task-name">
<input type="text" class="form-control" id="add-task-name" placeholder="Task name" />
</FormGroup>
<FormGroup label="Assigned To">
<select class="form-select">
<FormGroup label="Assigned To" for="add-task-assigned">
<select class="form-select" id="add-task-assigned">
<option value="">Select person</option>
{selectedPeople.map((person) => <option value={person.id}>{person.full_name}</option>)}
</select>
</FormGroup>
<FormGroup label="Priority">
<select class="form-select">
<FormGroup label="Priority" for="add-task-priority">
<select class="form-select" id="add-task-priority">
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</FormGroup>
<FormGroup label="Description">
<textarea class="form-control" rows="3" placeholder="Task description"></textarea>
<FormGroup label="Description" for="add-task-description">
<textarea class="form-control" id="add-task-description" rows="3" placeholder="Task description"></textarea>
</FormGroup>
</form>
</div>
@@ -6,30 +6,30 @@ import FormGroup from '@ui/FormGroup.astro'
---
<div class="modal-header">
<h4 class="modal-title" id="password-modal-label">Change password</h4>
<h4 class="modal-title" id="modal-change-password-title">Change password</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<FormGroup label="Current password" for="password-current" class="mb-4">
<InputGroup type="password" id="password-current" placeholder="Enter your current password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat />
<InputGroup type="password" id="password-current" placeholder="Enter your current password" autocomplete="current-password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat />
</FormGroup>
<FormGroup label="New password" for="password-new" class="mb-4">
<InputGroup type="password" id="password-new" placeholder="Enter new password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat />
<InputGroup type="password" id="password-new" placeholder="Enter new password" autocomplete="new-password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat />
<FormHint as="small"> Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji. </FormHint>
<div class="mt-2">
<div class="progress" style="height: 4px;">
<div class="progress-bar" id="password-strength" role="progressbar" style="width: 0%"></div>
<div class="progress-bar" id="password-strength" role="progressbar" style="width: 0%" aria-label="Password strength" aria-valuemin="0" aria-valuemax="5" aria-valuenow="0"></div>
</div>
<div class="text-secondary text-xs mt-1" id="password-strength-text"></div>
<div class="text-secondary text-xs mt-1" id="password-strength-text" aria-live="polite"></div>
</div>
</FormGroup>
<FormGroup label="Confirm new password" for="password-confirm" class="mb-4">
<InputGroup type="password" id="password-confirm" placeholder="Confirm your new password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat />
<div class="invalid-feedback d-none" id="password-match-error">Passwords do not match.</div>
<InputGroup type="password" id="password-confirm" placeholder="Confirm your new password" autocomplete="new-password" appendButton={[{ icon: 'eye', description: 'Show password' }]} flat />
<div class="invalid-feedback d-none" id="password-match-error" role="alert">Passwords do not match.</div>
</FormGroup>
<Button type="submit" text="Update password" color="primary" block class="mt-4" />
@@ -37,37 +37,7 @@ import FormGroup from '@ui/FormGroup.astro'
</div>
<!-- BEGIN CHANGE PASSWORD -->
<script>
function setupPasswordToggle(inputId: string) {
const input = document.getElementById(inputId) as HTMLInputElement | null
if (!input) return
const inputGroup = input.closest('.input-group')
if (!inputGroup) return
const toggleLink = inputGroup.querySelector('a.link-secondary') as HTMLElement | null
if (!toggleLink) return
toggleLink.addEventListener('click', function (this: HTMLElement, e: MouseEvent) {
e.preventDefault()
const isPassword = input.type === 'password'
input.type = isPassword ? 'text' : 'password'
// Update tooltip text
const tooltipText = isPassword ? 'Hide password' : 'Show password'
this.setAttribute('title', tooltipText)
this.setAttribute('data-bs-original-title', tooltipText)
// Update icon (simple approach - toggle classes if needed)
const svg = this.querySelector('svg')
const use = svg?.querySelector('use')
use?.setAttribute('href', isPassword ? '#icon-eye-off' : '#icon-eye')
})
}
setupPasswordToggle('password-current')
setupPasswordToggle('password-new')
setupPasswordToggle('password-confirm')
// Password show/hide toggles are wired generically by InputGroup.astro (data-password-toggle).
const newPasswordInput = document.getElementById('password-new') as HTMLInputElement | null
const strengthBar = document.getElementById('password-strength')
const strengthText = document.getElementById('password-strength-text')
@@ -85,10 +55,12 @@ import FormGroup from '@ui/FormGroup.astro'
const percentage = (strength / 5) * 100
strengthBar.style.width = `${percentage}%`
strengthBar.setAttribute('aria-valuenow', String(strength))
const strengthLevels = ['bg-danger', 'bg-danger', 'bg-danger', 'bg-warning', 'bg-info', 'bg-success']
const strengthLabels = ['Weak', 'Weak', 'Weak', 'Fair', 'Good', 'Strong']
strengthBar.className = `progress-bar ${strengthLevels[strength]}`
strengthBar.setAttribute('aria-valuetext', password ? strengthLabels[strength] : 'Empty')
strengthText.textContent = password ? strengthLabels[strength] : ''
})
}
@@ -103,9 +75,13 @@ import FormGroup from '@ui/FormGroup.astro'
if (confirmPassword && newPassword !== confirmPassword) {
confirmPasswordInput.classList.add('is-invalid')
confirmPasswordInput.setAttribute('aria-invalid', 'true')
confirmPasswordInput.setAttribute('aria-describedby', 'password-match-error')
matchError.classList.remove('d-none')
} else {
confirmPasswordInput.classList.remove('is-invalid')
confirmPasswordInput.removeAttribute('aria-invalid')
confirmPasswordInput.removeAttribute('aria-describedby')
matchError.classList.add('d-none')
}
}
@@ -9,7 +9,7 @@ import ModalClose from './ModalClose.astro'
<div class="modal-body text-center py-4">
<Icon name="alert-triangle" color="danger" size="lg" class="mb-2" />
<h3 id="confirm-delete-title">Are you sure?</h3>
<h3 id="modal-confirm-delete-title">Are you sure?</h3>
<div class="text-secondary mb-4">
<p id="confirm-delete-message">Do you really want to delete this item? This action cannot be undone.</p>
<div id="confirm-delete-items" class="text-start d-none">
@@ -9,7 +9,7 @@ import ModalClose from './ModalClose.astro'
<div class="modal-body text-center py-4">
<Icon name="alert-triangle" color="danger" size="lg" class="mb-2" />
<h3>Are you sure?</h3>
<h3 id="modal-danger-title">Are you sure?</h3>
<div class="text-secondary">Do you really want to remove 84 files? What you've done cannot be undone.</div>
</div>
@@ -7,7 +7,7 @@ import FormGroup from '@ui/FormGroup.astro'
---
<div class="modal-header">
<h4 class="modal-title" id="profile-modal-label">Edit profile</h4>
<h4 class="modal-title" id="modal-edit-profile-title">Edit profile</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
@@ -57,7 +57,7 @@ import FormGroup from '@ui/FormGroup.astro'
</FormGroup>
</div>
<div class="col-md-6">
<FormGroup label="Date of birth" for="profile-birthdate" class="mb-4">
<FormGroup label="Date of birth" for="datepicker-profile-birthdate" class="mb-4">
<Datepicker layout="icon" id="profile-birthdate" />
</FormGroup>
</div>
@@ -3,6 +3,6 @@ import ModalHeader from './ModalHeader.astro'
import ModalFooter from './ModalFooter.astro'
---
<ModalHeader title="Full width modal" />
<ModalHeader title="Full width modal" titleId="modal-full-width-title" />
<div class="modal-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci animi beatae delectus deleniti dolorem eveniet facere fuga iste nemo nesciunt nihil odio perspiciatis, quia quis reprehenderit sit tempora totam unde.</div>
<ModalFooter />
@@ -3,6 +3,6 @@ import ModalHeader from './ModalHeader.astro'
import ModalFooter from './ModalFooter.astro'
---
<ModalHeader title="Large modal" />
<ModalHeader title="Large modal" titleId="modal-large-title" />
<div class="modal-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci animi beatae delectus deleniti dolorem eveniet facere fuga iste nemo nesciunt nihil odio perspiciatis, quia quis reprehenderit sit tempora totam unde.</div>
<ModalFooter />
Loaded 100 of 160 files, more files were not shown because too many files have changed in this diff. Show more