Fix pre-release markup, a11y and docs issues found by the crawl (#2935)

This commit is contained in:
Paweł Kuna authored and GitHub committed 2026-09-02 21:28:43 +02:00
1 parent 3cca8bf352
commit 1da70a787e
42 files changed
+161 -116

No files matched your search

@@ -0,0 +1,5 @@
---
"@tabler/docs": patch
---
Fixed the docs logo link name, dead example links in the navbar and offcanvas pages, and the vector map error on its plugin page.
+5
View File
@@ -0,0 +1,5 @@
---
"@tabler/preview": patch
---
Fixed the marketing footer layout, timeline social icons, missing `alt` and `aria-label` attributes and invalid nesting in demos.
+5
View File
@@ -0,0 +1,5 @@
---
"@tabler/core": patch
---
Fixed ScrollSpy throwing on target ids that start with a digit, such as headings like `1. Setup`.
+2 -2
View File
@@ -8,7 +8,7 @@
import BaseComponent from './base-component' import BaseComponent from './base-component'
import EventHandler from './dom/event-handler' import EventHandler from './dom/event-handler'
import SelectorEngine from './dom/selector-engine' import SelectorEngine from './dom/selector-engine'
import { getElement, isDisabled, isVisible } from './util/index' import { getElement, isDisabled, isVisible, parseSelector } from './util/index'
import type { ComponentConfig, ComponentConfigType } from './types' import type { ComponentConfig, ComponentConfigType } from './types'
const NAME = 'scrollspy' const NAME = 'scrollspy'
@@ -198,7 +198,7 @@ class ScrollSpy extends BaseComponent {
continue continue
} }
const observableSection = SelectorEngine.findOne(decodeURI((anchor as HTMLAnchorElement).hash), this._element) const observableSection = SelectorEngine.findOne(parseSelector(decodeURI((anchor as HTMLAnchorElement).hash)), this._element)
if (isVisible(observableSection!)) { if (isVisible(observableSection!)) {
this._targetLinks.set(decodeURI((anchor as HTMLAnchorElement).hash), anchor) this._targetLinks.set(decodeURI((anchor as HTMLAnchorElement).hash), anchor)
+7
View File
@@ -624,4 +624,11 @@ describe('ScrollSpy', () => {
expect(ScrollSpy.getInstance(scrollSpyEl)).not.toBeNull() expect(ScrollSpy.getInstance(scrollSpyEl)).not.toBeNull()
}) })
}) })
describe('target ids', () => {
it('should accept anchors whose target id starts with a digit', () => {
fixtureEl.innerHTML = ['<ul id="navigation" class="navbar">', ' <a class="nav-link" href="#1-intro">Intro</a>', '</ul>', '<div id="content">', ' <div id="1-intro">test</div>', '</div>'].join('')
expect(() => new ScrollSpy('#content', { target: '#navigation' })).not.toThrow()
})
})
}) })
+1 -1
View File
@@ -17,7 +17,7 @@ const changelogUrl = 'https://tabler.io/changelog'
<button type="button" class="btn btn-icon btn-ghost-secondary d-lg-none" data-bs-toggle="offcanvas" data-bs-target="#docs-menu-offcanvas" aria-controls="docs-menu-offcanvas" aria-label="Open documentation menu"> <button type="button" class="btn btn-icon btn-ghost-secondary d-lg-none" data-bs-toggle="offcanvas" data-bs-target="#docs-menu-offcanvas" aria-controls="docs-menu-offcanvas" aria-label="Open documentation menu">
<Icon name="menu-2" /> <Icon name="menu-2" />
</button> </button>
<a href="/" class="navbar-brand navbar-brand-autodark me-2"> <a href="/" class="navbar-brand navbar-brand-autodark me-2" aria-label="Tabler">
<DocsLogo /> <DocsLogo />
</a> </a>
<span class="badge d-none d-sm-inline-block">v{site.version}</span> <span class="badge d-none d-sm-inline-block">v{site.version}</span>
+8 -8
View File
@@ -204,9 +204,9 @@ Put an icon inside to show the action. The variant is often used as a link or a
<Example centered> <Example centered>
<AvatarList> <AvatarList>
<a href="#" class="avatar avatar-upload"><Icon name="plus" /></a> <a href="#" class="avatar avatar-upload" aria-label="Upload photo"><Icon name="plus" /></a>
<a href="#" class="avatar avatar-upload rounded"><Icon name="plus" /></a> <a href="#" class="avatar avatar-upload rounded" aria-label="Upload photo"><Icon name="plus" /></a>
<a href="#" class="avatar avatar-upload rounded-0"><Icon name="camera" /></a> <a href="#" class="avatar avatar-upload rounded-0" aria-label="Take photo"><Icon name="camera" /></a>
</AvatarList> </AvatarList>
</Example> </Example>
@@ -216,11 +216,11 @@ The upload avatar uses the same size classes as a normal avatar, from `avatar-xx
<Example centered> <Example centered>
<AvatarList> <AvatarList>
<a href="#" class="avatar avatar-upload avatar-2xl rounded"><Icon name="plus" /></a> <a href="#" class="avatar avatar-upload avatar-2xl rounded" aria-label="Upload photo"><Icon name="plus" /></a>
<a href="#" class="avatar avatar-upload avatar-xl rounded"><Icon name="plus" /></a> <a href="#" class="avatar avatar-upload avatar-xl rounded" aria-label="Upload photo"><Icon name="plus" /></a>
<a href="#" class="avatar avatar-upload avatar-lg rounded"><Icon name="plus" /></a> <a href="#" class="avatar avatar-upload avatar-lg rounded" aria-label="Upload photo"><Icon name="plus" /></a>
<a href="#" class="avatar avatar-upload rounded"><Icon name="plus" /></a> <a href="#" class="avatar avatar-upload rounded" aria-label="Upload photo"><Icon name="plus" /></a>
<a href="#" class="avatar avatar-upload avatar-sm rounded"><Icon name="plus" /></a> <a href="#" class="avatar avatar-upload avatar-sm rounded" aria-label="Upload photo"><Icon name="plus" /></a>
</AvatarList> </AvatarList>
</Example> </Example>
+4 -4
View File
@@ -592,10 +592,10 @@ Use the `.btn-actions` container to group multiple action buttons together. This
<Example centered> <Example centered>
<div class="btn-actions"> <div class="btn-actions">
<a href="#" class="btn btn-action"><Icon name="refresh" /></a> <a href="#" class="btn btn-action" aria-label="Refresh"><Icon name="refresh" /></a>
<a href="#" class="btn btn-action"><Icon name="chevron-up" /></a> <a href="#" class="btn btn-action" aria-label="Collapse"><Icon name="chevron-up" /></a>
<a href="#" class="btn btn-action"><Icon name="dots-vertical" /></a> <a href="#" class="btn btn-action" aria-label="More actions"><Icon name="dots-vertical" /></a>
<a href="#" class="btn btn-action"><Icon name="x" /></a> <a href="#" class="btn btn-action" aria-label="Close"><Icon name="x" /></a>
</div> </div>
</Example> </Example>
+2 -2
View File
@@ -151,7 +151,7 @@ Add an image to your blog post card to make it eye-catching. You can do it by ad
<div class="text-secondary">3 days ago</div> <div class="text-secondary">3 days ago</div>
</div> </div>
<div class="ms-auto"> <div class="ms-auto">
<a href="#" class="icon d-none d-md-inline-block ms-3 text-secondary"> <a href="#" class="icon d-none d-md-inline-block ms-3 text-secondary" aria-label="Like">
<Icon name="heart" /> <Icon name="heart" />
</a> </a>
</div> </div>
@@ -203,7 +203,7 @@ You can also put the image beside the text instead of above it. Use a `row row-0
<div class="text-secondary">3 days ago</div> <div class="text-secondary">3 days ago</div>
</div> </div>
<div class="ms-auto"> <div class="ms-auto">
<a href="#" class="icon d-none d-md-inline-block ms-3 text-red"> <a href="#" class="icon d-none d-md-inline-block ms-3 text-red" aria-label="Unlike">
<Icon name="heart" /> <Icon name="heart" />
</a> </a>
</div> </div>
+4 -4
View File
@@ -124,7 +124,7 @@ Add `list-group-hoverable` to the container to highlight the row under the point
<div class="row align-items-center"> <div class="row align-items-center">
<div class="col text-truncate">Change deprecated html tags</div> <div class="col text-truncate">Change deprecated html tags</div>
<div class="col-auto"> <div class="col-auto">
<a href="#" class="list-group-item-actions"><Icon name="star" color="muted" /></a> <a href="#" class="list-group-item-actions" aria-label="Add to favorites"><Icon name="star" color="muted" /></a>
</div> </div>
</div> </div>
</div> </div>
@@ -132,7 +132,7 @@ Add `list-group-hoverable` to the container to highlight the row under the point
<div class="row align-items-center"> <div class="row align-items-center">
<div class="col text-truncate">Fix spacing in the navbar</div> <div class="col text-truncate">Fix spacing in the navbar</div>
<div class="col-auto"> <div class="col-auto">
<a href="#" class="list-group-item-actions show"><Icon name="star" color="yellow" /></a> <a href="#" class="list-group-item-actions show" aria-label="Remove from favorites"><Icon name="star" color="yellow" /></a>
</div> </div>
</div> </div>
</div> </div>
@@ -248,7 +248,7 @@ This pattern joins several variants: a flush list inside a card, hoverable rows,
<div class="d-block text-secondary text-truncate mt-n1"> The last deploy did not finish </div> <div class="d-block text-secondary text-truncate mt-n1"> The last deploy did not finish </div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<a href="#" class="list-group-item-actions"><Icon name="star" color="muted" /></a> <a href="#" class="list-group-item-actions" aria-label="Add to favorites"><Icon name="star" color="muted" /></a>
</div> </div>
</div> </div>
</div> </div>
@@ -260,7 +260,7 @@ This pattern joins several variants: a flush list inside a card, hoverable rows,
<div class="d-block text-secondary text-truncate mt-n1"> Alice replied in the design thread </div> <div class="d-block text-secondary text-truncate mt-n1"> Alice replied in the design thread </div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<a href="#" class="list-group-item-actions show"><Icon name="star" color="yellow" /></a> <a href="#" class="list-group-item-actions show" aria-label="Remove from favorites"><Icon name="star" color="yellow" /></a>
</div> </div>
</div> </div>
</div> </div>
+2 -2
View File
@@ -68,8 +68,8 @@ Add `offcanvas-narrow` for a panel thinner than the default. It suits a short li
The offcanvas component is used to display a cookies banner. It is a great way to inform users about the use of cookies on your website and to get their consent. The offcanvas component is used to display a cookies banner. It is a great way to inform users about the use of cookies on your website and to get their consent.
<Example raw code={`<div class="offcanvas offcanvas-bottom h-auto" tabindex="-1" id="offcanvasBottom" aria-modal="true" role="dialog" data-bs-scroll="true"> <div class="offcanvas-body"> <div class="container"> <div class="row align-items-center"> <div class="col"> <strong>Do you like cookies?</strong> 🍪 We use cookies to ensure you get the best experience on our website. <a href="./terms-of-service.html" target="_blank">Learn more</a> </div> <div class="col-auto"> <button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Essential Cookies Only </button> </div> <div class="col-auto"> <button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Allow All Cookies </button> </div> </div> </div> </div> </div>`}> <Example raw code={`<div class="offcanvas offcanvas-bottom h-auto" tabindex="-1" id="offcanvasBottom" aria-modal="true" role="dialog" data-bs-scroll="true"> <div class="offcanvas-body"> <div class="container"> <div class="row align-items-center"> <div class="col"> <strong>Do you like cookies?</strong> 🍪 We use cookies to ensure you get the best experience on our website. <a href="#">Learn more</a> </div> <div class="col-auto"> <button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Essential Cookies Only </button> </div> <div class="col-auto"> <button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Allow All Cookies </button> </div> </div> </div> </div> </div>`}>
<div class="offcanvas offcanvas-bottom h-auto show position-static" tabindex="-1" id="offcanvasBottom" aria-modal="true" role="dialog" data-bs-scroll="true" > <div class="offcanvas-body"> <div class="container"> <div class="row align-items-center"> <div class="col"> <strong>Do you like cookies?</strong> 🍪 We use cookies to ensure you get the best experience on our website. <a href="./terms-of-service.html" target="_blank">Learn more</a> </div> <div class="col-auto"> <button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Essential Cookies Only </button> </div> <div class="col-auto"> <button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Allow All Cookies </button> </div> </div> </div> </div> </div> <div class="offcanvas offcanvas-bottom h-auto show position-static" tabindex="-1" id="offcanvasBottom" aria-modal="true" role="dialog" data-bs-scroll="true" > <div class="offcanvas-body"> <div class="container"> <div class="row align-items-center"> <div class="col"> <strong>Do you like cookies?</strong> 🍪 We use cookies to ensure you get the best experience on our website. <a href="#">Learn more</a> </div> <div class="col-auto"> <button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Essential Cookies Only </button> </div> <div class="col-auto"> <button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Allow All Cookies </button> </div> </div> </div> </div> </div>
</Example> </Example>
## Accessibility ## Accessibility
+3 -3
View File
@@ -69,11 +69,11 @@ The navbar can contain links, buttons, and other elements. You can customize the
</a> </a>
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow"> <div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
<a href="#" class="dropdown-item">Status</a> <a href="#" class="dropdown-item">Status</a>
<a href="./profile.html" class="dropdown-item">Profile</a> <a href="#" class="dropdown-item">Profile</a>
<a href="#" class="dropdown-item">Feedback</a> <a href="#" class="dropdown-item">Feedback</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a href="./settings.html" class="dropdown-item">Settings</a> <a href="#" class="dropdown-item">Settings</a>
<a href="./sign-in.html" class="dropdown-item">Logout</a> <a href="#" class="dropdown-item">Logout</a>
</div> </div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -92,7 +92,7 @@ const sizes = ['sm', 'md', 'lg']
<span class="badge badge-dot bg-red badge-notification badge-blink"></span> <span class="badge badge-dot bg-red badge-notification badge-blink"></span>
</button> </button>
<button type="button" class="btn btn-icon btn-action"> <button type="button" class="btn btn-icon btn-action" aria-label="Notifications">
<Icon name="bell" /> <Icon name="bell" />
<span class="badge badge-dot bg-red badge-notification"></span> <span class="badge badge-dot bg-red badge-notification"></span>
</button> </button>
+2 -1
View File
@@ -1,4 +1,5 @@
--- ---
import { ucFirst } from '@shared/lib/string-format'
import DefaultLayout from '@shared/layouts/DefaultLayout.astro' import DefaultLayout from '@shared/layouts/DefaultLayout.astro'
import Icon from '@ui/Icon.astro' import Icon from '@ui/Icon.astro'
import Button from '@ui/Button.astro' import Button from '@ui/Button.astro'
@@ -69,7 +70,7 @@ const sizes = ['sm', 'md', 'lg', 'xl'] as const
<div class="btn-actions"> <div class="btn-actions">
{ {
actions.map((action) => ( actions.map((action) => (
<a class="btn btn-action"> <a href="#" class="btn btn-action" aria-label={ucFirst(action)}>
<Icon name={action} /> <Icon name={action} />
</a> </a>
)) ))
+5 -5
View File
@@ -130,7 +130,7 @@ const person3 = requireIndex(people, 3)
</div> </div>
<CardActions> <CardActions>
<div class="dropdown"> <div class="dropdown">
<a href="#" class="btn btn-action dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><Icon name="dots-vertical" /></a> <a href="#" class="btn btn-action dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Actions"><Icon name="dots-vertical" /></a>
<div class="dropdown-menu dropdown-menu-end"> <div class="dropdown-menu dropdown-menu-end">
<a class="dropdown-item" href="#">Edit user</a> <a class="dropdown-item" href="#">Edit user</a>
<a class="dropdown-item" href="#">Change permissions</a> <a class="dropdown-item" href="#">Change permissions</a>
@@ -151,10 +151,10 @@ const person3 = requireIndex(people, 3)
<CardSubtitle>A compact row of icon-only actions in the header.</CardSubtitle> <CardSubtitle>A compact row of icon-only actions in the header.</CardSubtitle>
</div> </div>
<CardActions class="btn-actions"> <CardActions class="btn-actions">
<a href="#" class="btn btn-action"><Icon name="refresh" /></a> <a href="#" class="btn btn-action" aria-label="Refresh"><Icon name="refresh" /></a>
<a href="#" class="btn btn-action"><Icon name="chevron-up" /></a> <a href="#" class="btn btn-action" aria-label="Collapse"><Icon name="chevron-up" /></a>
<a href="#" class="btn btn-action"><Icon name="dots-vertical" /></a> <a href="#" class="btn btn-action" aria-label="More actions"><Icon name="dots-vertical" /></a>
<a href="#" class="btn btn-action"><Icon name="x" /></a> <a href="#" class="btn btn-action" aria-label="Close"><Icon name="x" /></a>
</CardActions> </CardActions>
</CardHeader> </CardHeader>
<BodyPlaceholder /> <BodyPlaceholder />
+9 -9
View File
@@ -75,7 +75,7 @@ import mails from '@data/mails.json'
<div class="card-body"> <div class="card-body">
<div class="d-flex flex-wrap align-items-center gap-2"> <div class="d-flex flex-wrap align-items-center gap-2">
<div class="d-xxl-none d-inline-flex"> <div class="d-xxl-none d-inline-flex">
<button class="btn btn-icon" type="button" data-bs-toggle="offcanvas" data-bs-target="#emailSidebaroffcanvas" aria-controls="emailSidebaroffcanvas"> <button class="btn btn-icon" type="button" data-bs-toggle="offcanvas" data-bs-target="#emailSidebaroffcanvas" aria-controls="emailSidebaroffcanvas" aria-label="Show folders">
<Icon name="menu-2" /> <Icon name="menu-2" />
</button> </button>
</div> </div>
@@ -87,7 +87,7 @@ import mails from '@data/mails.json'
</ButtonGroup> </ButtonGroup>
<ButtonGroup> <ButtonGroup>
<button type="button" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false"> <button type="button" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Move to folder">
<Icon name="folder" /> <Icon name="folder" />
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
@@ -100,7 +100,7 @@ import mails from '@data/mails.json'
</ButtonGroup> </ButtonGroup>
<ButtonGroup> <ButtonGroup>
<button type="button" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false"> <button type="button" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Add label">
<Icon name="tag" /> <Icon name="tag" />
</button> </button>
<div class="dropdown-menu"> <div class="dropdown-menu">
@@ -158,22 +158,22 @@ import mails from '@data/mails.json'
<div class="email-action-icons"> <div class="email-action-icons">
<ul class="list-inline"> <ul class="list-inline">
<li class="list-inline-item"> <li class="list-inline-item">
<a href="#"> <a href="#" aria-label="Archive">
<Icon name="archive" /> <Icon name="archive" />
</a> </a>
</li> </li>
<li class="list-inline-item"> <li class="list-inline-item">
<a href="#"> <a href="#" aria-label="Delete">
<Icon name="trash" /> <Icon name="trash" />
</a> </a>
</li> </li>
<li class="list-inline-item"> <li class="list-inline-item">
<a href="#"> <a href="#" aria-label="Mark as read">
<Icon name="mail-opened" class="email-action-icons-item" /> <Icon name="mail-opened" class="email-action-icons-item" />
</a> </a>
</li> </li>
<li class="list-inline-item"> <li class="list-inline-item">
<a href="#"> <a href="#" aria-label="Snooze">
<Icon name="clock" /> <Icon name="clock" />
</a> </a>
</li> </li>
@@ -194,8 +194,8 @@ import mails from '@data/mails.json'
</div> </div>
<div class="col-5"> <div class="col-5">
<ButtonGroup class="float-end"> <ButtonGroup class="float-end">
<button type="button" class="btn btn-icon"><Icon name="chevron-left" /></button> <button type="button" class="btn btn-icon" aria-label="Previous page"><Icon name="chevron-left" /></button>
<button type="button" class="btn btn-icon"><Icon name="chevron-right" /></button> <button type="button" class="btn btn-icon" aria-label="Next page"><Icon name="chevron-right" /></button>
</ButtonGroup> </ButtonGroup>
</div> </div>
</div> </div>
+1 -1
View File
@@ -13,7 +13,7 @@ const filteredPhotos = photos.filter((photo) => photo.horizontal)
{ {
filteredPhotos.map((photo) => ( filteredPhotos.map((photo) => (
<div class="col"> <div class="col">
<a data-fslightbox="gallery" href={`./static/photos/${photo.file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photo.file}`} aria-label={photo.title}>
<Photo photo={photo} class="rounded border" ratio="1x1" /> <Photo photo={photo} class="rounded border" ratio="1x1" />
</a> </a>
</div> </div>
+7 -7
View File
@@ -9,31 +9,31 @@ import DocsLink from '@ui/DocsLink.astro'
<div class="box"> <div class="box">
<div class="mb-3"> <div class="mb-3">
<Navbar sample condensed transparent personId={3} /> <Navbar menuId="navbar-menu-1" sample condensed transparent personId={3} />
</div> </div>
<div class="mb-3"> <div class="mb-3">
<Navbar sample condensed personId={4} /> <Navbar menuId="navbar-menu-2" sample condensed personId={4} />
</div> </div>
<div class="mb-3"> <div class="mb-3">
<Navbar sample condensed dark hideLogo showTitle hideIcons hideUsername personId={5} /> <Navbar menuId="navbar-menu-3" sample condensed dark hideLogo showTitle hideIcons hideUsername personId={5} />
</div> </div>
<div class="mb-3"> <div class="mb-3">
<Navbar sample condensed dark smallLogo backgroundColor="#7952b3" hideSearch personId={6} /> <Navbar menuId="navbar-menu-4" sample condensed dark smallLogo backgroundColor="#7952b3" hideSearch personId={6} />
</div> </div>
<div class="mb-3"> <div class="mb-3">
<Navbar sample condensed dark background="primary" hideBrand hideIcons hideUsername personId={7} /> <Navbar menuId="navbar-menu-5" sample condensed dark background="primary" hideBrand hideIcons hideUsername personId={7} />
</div> </div>
<div class="mb-3"> <div class="mb-3">
<Navbar sample smallLogo showTitle personId={8} /> <Navbar menuId="navbar-menu-6" sample smallLogo showTitle personId={8} />
</div> </div>
<div class="mb-3"> <div class="mb-3">
<Navbar sample dark personId={9} /> <Navbar menuId="navbar-menu-7" sample dark personId={9} />
</div> </div>
</div> </div>
</DefaultLayout> </DefaultLayout>
+14 -14
View File
@@ -13,41 +13,41 @@ const photoAt = (i: number) => requireIndex(photosData, i)
<div class="col-lg-6"> <div class="col-lg-6">
<div class="row g-2 g-md-3"> <div class="row g-2 g-md-3">
<div class="col-12"> <div class="col-12">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(5).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(5).file}`} aria-label={photoAt(5).title}>
<Photo photo={photoAt(5)} class="rounded-3 border" ratio="3x1" /> <Photo photo={photoAt(5)} class="rounded-3 border" ratio="3x1" />
</a> </a>
</div> </div>
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(6).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(6).file}`} aria-label={photoAt(6).title}>
<Photo photo={photoAt(6)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(6)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
<div class="col-6"> <div class="col-6">
<div class="row g-2 g-md-3"> <div class="row g-2 g-md-3">
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(7).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(7).file}`} aria-label={photoAt(7).title}>
<Photo photo={photoAt(7)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(7)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(8).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(8).file}`} aria-label={photoAt(8).title}>
<Photo photo={photoAt(8)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(8)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(9).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(9).file}`} aria-label={photoAt(9).title}>
<Photo photo={photoAt(9)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(9)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(10).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(10).file}`} aria-label={photoAt(10).title}>
<Photo photo={photoAt(10)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(10)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
</div> </div>
</div> </div>
<div class="col-12"> <div class="col-12">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(16).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(16).file}`} aria-label={photoAt(16).title}>
<Photo photo={photoAt(16)} class="rounded-3 border" ratio="4x1" /> <Photo photo={photoAt(16)} class="rounded-3 border" ratio="4x1" />
</a> </a>
</div> </div>
@@ -58,39 +58,39 @@ const photoAt = (i: number) => requireIndex(photosData, i)
<div class="col-6"> <div class="col-6">
<div class="row g-2 g-md-3"> <div class="row g-2 g-md-3">
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(14).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(14).file}`} aria-label={photoAt(14).title}>
<Photo photo={photoAt(14)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(14)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(15).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(15).file}`} aria-label={photoAt(15).title}>
<Photo photo={photoAt(15)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(15)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(12).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(12).file}`} aria-label={photoAt(12).title}>
<Photo photo={photoAt(12)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(12)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(13).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(13).file}`} aria-label={photoAt(13).title}>
<Photo photo={photoAt(13)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(13)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
</div> </div>
</div> </div>
<div class="col-6"> <div class="col-6">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(1).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(1).file}`} aria-label={photoAt(1).title}>
<Photo photo={photoAt(1)} class="rounded-3 border" ratio="1x1" /> <Photo photo={photoAt(1)} class="rounded-3 border" ratio="1x1" />
</a> </a>
</div> </div>
<div class="col-12"> <div class="col-12">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(4).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(4).file}`} aria-label={photoAt(4).title}>
<Photo photo={photoAt(4)} class="rounded-3 border" ratio="4x1" /> <Photo photo={photoAt(4)} class="rounded-3 border" ratio="4x1" />
</a> </a>
</div> </div>
<div class="col-12"> <div class="col-12">
<a data-fslightbox="gallery" href={`./static/photos/${photoAt(17).file}`}> <a data-fslightbox="gallery" href={`./static/photos/${photoAt(17).file}`} aria-label={photoAt(17).title}>
<Photo photo={photoAt(17)} class="rounded-3 border" ratio="3x1" /> <Photo photo={photoAt(17)} class="rounded-3 border" ratio="3x1" />
</a> </a>
</div> </div>
+1 -1
View File
@@ -108,7 +108,7 @@ const imgBottomPhoto = requireIndex(photos as { file: string; title: string }[],
</a> </a>
</li> </li>
<li class="nav-item ms-auto"> <li class="nav-item ms-auto">
<a class="nav-link" href="#"> <a class="nav-link" href="#" aria-label="Settings">
<Icon name="settings" /> <Icon name="settings" />
</a> </a>
</li> </li>
@@ -24,7 +24,7 @@ const rows = (commits as Commit[]).slice(0, 5)
<CardTitle>Development activity</CardTitle> <CardTitle>Development activity</CardTitle>
</div> </div>
<div class="position-relative"> <div class="position-relative">
<div class="position-absolute top-0 left-0 px-3 mt-1 w-75"> <div class="position-absolute top-0 start-0 px-3 mt-1 w-75">
<div class="row g-2"> <div class="row g-2">
<div class="col-auto"><ChartSparkline id="activity" percentage={35} type="donut" /></div> <div class="col-auto"><ChartSparkline id="activity" percentage={35} type="donut" /></div>
<div class="col"> <div class="col">
+2 -1
View File
@@ -5,6 +5,7 @@ import Icon from '@ui/Icon.astro'
import { randomNumber, timeagoLabel } from '@shared/lib/pseudo-random' import { randomNumber, timeagoLabel } from '@shared/lib/pseudo-random'
interface Photo { interface Photo {
title: string
file: string file: string
[key: string]: unknown [key: string]: unknown
} }
@@ -29,7 +30,7 @@ const heartClass = (index > 2 && index < 9) || index === 10 ? 'icon-filled text-
--- ---
<div class="card card-sm"> <div class="card card-sm">
<a href="#" class="d-block"><img src={staticPath(`photos/${photo.file}`)} class="card-img-top" /></a> <a href="#" class="d-block"><img src={staticPath(`photos/${photo.file}`)} class="card-img-top" alt={photo.title} /></a>
<div class="card-body"> <div class="card-body">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<Avatar person={person} class="me-3 rounded" /> <Avatar person={person} class="me-3 rounded" />
+2 -2
View File
@@ -16,10 +16,10 @@ import SignInForm from './SignInForm.astro'
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<Button block icon="brand-github" iconColor="github" text="Login with Github" /> <Button block icon="brand-github" text="Login with Github" />
</div> </div>
<div class="col"> <div class="col">
<Button block icon="brand-x" iconColor="x" text="Login with X" /> <Button block icon="brand-x" text="Login with X" />
</div> </div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -26,7 +26,7 @@ const services = 'Instagram:3550,Twitter:1798,Facebook:1245,TikTok:986,Pinterest
<td>{service.name}</td> <td>{service.name}</td>
<td>{formatNumber(service.visitors)}</td> <td>{formatNumber(service.visitors)}</td>
<td class="w-50"> <td class="w-50">
<div class="progress progress-xs"> <div class="progress progress-sm">
<div class="progress-bar bg-primary" style={`width: ${(service.visitors / 5000.0) * 100}%`} /> <div class="progress-bar bg-primary" style={`width: ${(service.visitors / 5000.0) * 100}%`} />
</div> </div>
</td> </td>
+3 -3
View File
@@ -10,7 +10,7 @@ const { rtl = false } = Astro.props
--- ---
<a href={site.githubSponsorsUrl} class="card border-primary" target="_blank" rel="noopener" aria-label="Sponsor Tabler!" style="background: color-mix(in srgb, var(--tblr-primary) 4%, var(--tblr-bg-surface))"> <a href={site.githubSponsorsUrl} class="card border-primary" target="_blank" rel="noopener" aria-label="Sponsor Tabler!" style="background: color-mix(in srgb, var(--tblr-primary) 4%, var(--tblr-bg-surface))">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 480 373" class="position-absolute top-0 right-0 bottom-0 left-0 w-100 h-100"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 480 373" class="position-absolute top-0 end-0 bottom-0 start-0 w-100 h-100">
<path <path
fill="var(--tblr-primary)" fill="var(--tblr-primary)"
opacity=".3" opacity=".3"
@@ -205,10 +205,10 @@ const { rtl = false } = Astro.props
<div class="h1 text-uppercase">Help Tabler Grow and Thrive</div> <div class="h1 text-uppercase">Help Tabler Grow and Thrive</div>
<p class="h3 fw-normal">Sponsor Tabler and help us make a difference!</p> <p class="h3 fw-normal">Sponsor Tabler and help us make a difference!</p>
<div class="mt-4"> <div class="mt-4">
<button class="btn w-100 pe-none" type="button" dir="ltr"> <span class="btn w-100 pe-none" dir="ltr">
<Icon name="heart" filled color="pink" class={rtl ? 'icon-end' : undefined} /> <Icon name="heart" filled color="pink" class={rtl ? 'icon-end' : undefined} />
Become a Sponsor Become a Sponsor
</button> </span>
</div> </div>
</div> </div>
</div> </div>
+1 -1
View File
@@ -56,7 +56,7 @@ const deals = crmDashboard.top_deals
<Avatar placeholder={item.owner_initials} color={item.owner_color} size="sm" /> <Avatar placeholder={item.owner_initials} color={item.owner_color} size="sm" />
</td> </td>
<td> <td>
<button type="button" class="btn btn-icon btn-sm"> <button type="button" class="btn btn-icon btn-sm" aria-label="Deal actions">
<Icon name="dots" /> <Icon name="dots" />
</button> </button>
</td> </td>
+1 -1
View File
@@ -72,7 +72,7 @@ const rows = people.slice(offset, offset + limit).map((person, idx) => {
</div> </div>
{hoverable && ( {hoverable && (
<div class="col-auto"> <div class="col-auto">
<a href="#" class={`list-group-item-actions${row.checked ? ' show' : ''}`}> <a href="#" class={`list-group-item-actions${row.checked ? ' show' : ''}`} aria-label={row.checked ? 'Remove from favorites' : 'Add to favorites'}>
<Icon name="star" class={row.starColor} /> <Icon name="star" class={row.starColor} />
</a> </a>
</div> </div>
+1 -1
View File
@@ -40,7 +40,7 @@ const rows = people.slice(offset, offset + limit).map((person, idx) => {
rows.map((row) => ( rows.map((row) => (
<div class="col-6"> <div class="col-6">
<div class="row g-3 align-items-center"> <div class="row g-3 align-items-center">
<a href="#" class="col-auto"> <a href="#" class="col-auto" tabindex="-1" aria-hidden="true">
<Avatar person={row.person} status={row.status} statusLabel={row.statusLabel} /> <Avatar person={row.person} status={row.status} statusLabel={row.statusLabel} />
</a> </a>
<div class="col text-truncate"> <div class="col text-truncate">
@@ -27,7 +27,7 @@ const items = tracks.slice(0, 12)
</div> </div>
<div class="col-auto text-secondary">{millisecondsToMinutes(track.duration_ms)}</div> <div class="col-auto text-secondary">{millisecondsToMinutes(track.duration_ms)}</div>
<div class="col-auto"> <div class="col-auto">
<button class="switch-icon" data-bs-toggle="switch-icon"> <button class="switch-icon" data-bs-toggle="switch-icon" aria-label="Like">
<span class="switch-icon-a text-muted"> <span class="switch-icon-a text-muted">
<Icon name="heart" /> <Icon name="heart" />
</span> </span>
@@ -38,7 +38,7 @@ const items = tracks.slice(0, 12)
</div> </div>
<div class="col-auto lh-1"> <div class="col-auto lh-1">
<div class="dropdown"> <div class="dropdown">
<a href="#" class="link-secondary" data-bs-toggle="dropdown"> <a href="#" class="link-secondary" data-bs-toggle="dropdown" aria-label="Track options">
<Icon name="dots" /> <Icon name="dots" />
</a> </a>
<DropdownMenu right /> <DropdownMenu right />
+3
View File
@@ -129,6 +129,9 @@ const mapOptions = data
function initMapVector() { function initMapVector() {
const container = document.querySelector(mapSelector); const container = document.querySelector(mapSelector);
if (!container) {
return;
}
// jsVectorMap computes its initial scale from the container's layout // jsVectorMap computes its initial scale from the container's layout
// size. If the container is still 0x0 (e.g. layout hasn't settled // size. If the container is still 0x0 (e.g. layout hasn't settled
+2 -2
View File
@@ -19,7 +19,7 @@ const timelinePhoto = (i: number) => requireIndex(timelinePhotos, i)
<ul class:list={['timeline', simple && 'timeline-simple']}> <ul class:list={['timeline', simple && 'timeline-simple']}>
<li class="timeline-event"> <li class="timeline-event">
<div class="timeline-event-icon bg-x-lt"><Icon name="brand-x" /></div> <div class="timeline-event-icon bg-x text-x-fg"><Icon name="brand-x" /></div>
<div class="card timeline-event-card"> <div class="card timeline-event-card">
<div class="card-body"> <div class="card-body">
<div class="text-secondary float-end">10 hrs ago</div> <div class="text-secondary float-end">10 hrs ago</div>
@@ -49,7 +49,7 @@ const timelinePhoto = (i: number) => requireIndex(timelinePhotos, i)
</div> </div>
</li> </li>
<li class="timeline-event"> <li class="timeline-event">
<div class="timeline-event-icon bg-facebook-lt"><Icon name="brand-facebook" /></div> <div class="timeline-event-icon bg-facebook text-facebook-fg"><Icon name="brand-facebook" /></div>
<div class="card timeline-event-card"> <div class="card timeline-event-card">
<div class="card-body"> <div class="card-body">
<div class="text-secondary float-end">1 day ago</div> <div class="text-secondary float-end">1 day ago</div>
+6 -6
View File
@@ -137,9 +137,9 @@ import FormGroup from '@ui/FormGroup.astro'
<label class="row"> <label class="row">
<span class="col">Push Notifications</span> <span class="col">Push Notifications</span>
<span class="col-auto"> <span class="col-auto">
<label class="form-check form-check-single form-switch"> <span class="form-check form-check-single form-switch">
<input class="form-check-input" type="checkbox" checked /> <input class="form-check-input" type="checkbox" checked />
</label> </span>
</span> </span>
</label> </label>
</div> </div>
@@ -147,9 +147,9 @@ import FormGroup from '@ui/FormGroup.astro'
<label class="row"> <label class="row">
<span class="col">SMS Notifications</span> <span class="col">SMS Notifications</span>
<span class="col-auto"> <span class="col-auto">
<label class="form-check form-check-single form-switch"> <span class="form-check form-check-single form-switch">
<input class="form-check-input" type="checkbox" /> <input class="form-check-input" type="checkbox" />
</label> </span>
</span> </span>
</label> </label>
</div> </div>
@@ -157,9 +157,9 @@ import FormGroup from '@ui/FormGroup.astro'
<label class="row"> <label class="row">
<span class="col">Email Notifications</span> <span class="col">Email Notifications</span>
<span class="col-auto"> <span class="col-auto">
<label class="form-check form-check-single form-switch"> <span class="form-check form-check-single form-switch">
<input class="form-check-input" type="checkbox" checked /> <input class="form-check-input" type="checkbox" checked />
</label> </span>
</span> </span>
</label> </label>
</div> </div>
@@ -12,7 +12,7 @@ const sectionClass = ['section', className]
<section class:list={sectionClass}> <section class:list={sectionClass}>
<div class="container"> <div class="container">
<div class="row items-center text-center g-lg-10"> <div class="row align-items-center text-center g-lg-10">
<div class="col-md-6 col-lg"> <div class="col-md-6 col-lg">
<div class="shape shape-md mb-3"><Icon name="devices" /></div> <div class="shape shape-md mb-3"><Icon name="devices" /></div>
<h2 class="h2">Mobile-optimized</h2> <h2 class="h2">Mobile-optimized</h2>
+6 -3
View File
@@ -31,6 +31,8 @@ interface Props {
backgroundColor?: string; backgroundColor?: string;
/** extra classes on the header */ /** extra classes on the header */
class?: string | undefined; class?: string | undefined;
/** id of the collapsible menu; pass a unique one when a page renders several navbars */
menuId?: string;
} }
// When a page passes no pageMenu, nothing in the menu is active. // When a page passes no pageMenu, nothing in the menu is active.
@@ -53,6 +55,7 @@ const {
background, background,
backgroundColor, backgroundColor,
class: className, class: className,
menuId = 'navbar-menu',
} = Astro.props; } = Astro.props;
const breakpoint = 'md'; const breakpoint = 'md';
@@ -76,7 +79,7 @@ const headerClass = [
data-bs-theme={dark ? 'dark' : undefined} data-bs-theme={dark ? 'dark' : undefined}
> >
<div class="container-xl"> <div class="container-xl">
<NavbarToggler target="navbar-menu" /> <NavbarToggler target={menuId} />
{ {
!hideBrand && ( !hideBrand && (
@@ -106,7 +109,7 @@ const headerClass = [
{ {
condensed && ( condensed && (
<div class="collapse navbar-collapse" id="navbar-menu"> <div class="collapse navbar-collapse" id={menuId}>
{hideSearch ? ( {hideSearch ? (
<Fragment> <Fragment>
<Fragment set:html={'<!-- BEGIN NAVBAR MENU -->'} /> <Fragment set:html={'<!-- BEGIN NAVBAR MENU -->'} />
@@ -133,7 +136,7 @@ const headerClass = [
{ {
!condensed && ( !condensed && (
<div class={`navbar-expand-${breakpoint}`}> <div class={`navbar-expand-${breakpoint}`}>
<div class="collapse navbar-collapse" id="navbar-menu"> <div class="collapse navbar-collapse" id={menuId}>
<div class="navbar"> <div class="navbar">
<div class="container-xl"> <div class="container-xl">
<div class="row flex-column flex-md-row flex-fill align-items-center"> <div class="row flex-column flex-md-row flex-fill align-items-center">
@@ -18,7 +18,7 @@ import CardTitle from '@ui/CardTitle.astro'
<CardTitle>My Apps</CardTitle> <CardTitle>My Apps</CardTitle>
<CardActions class="btn-actions"> <CardActions class="btn-actions">
<a href="#" class="btn btn-action"> <a href="#" class="btn btn-action" aria-label="App settings">
<Icon name="settings" /> <Icon name="settings" />
</a> </a>
</CardActions> </CardActions>
@@ -9,7 +9,7 @@ import CaptureScript from '../CaptureScript.astro'
<!-- BEGIN NOTIFICATIONS --> <!-- BEGIN NOTIFICATIONS -->
<div class="nav-item dropdown d-none d-md-flex"> <div class="nav-item dropdown d-none d-md-flex">
<a href="#" id="navbar-notifications-toggle" class="nav-link px-0" data-bs-toggle="dropdown" aria-label="Show notifications" data-bs-auto-close="outside" aria-expanded="false"> <a href="#" class="nav-link px-0" data-bs-toggle="dropdown" aria-label="Show notifications" data-bs-auto-close="outside" aria-expanded="false">
<Icon name="bell" /> <Icon name="bell" />
<span class="badge bg-red"></span> <span class="badge bg-red"></span>
</a> </a>
@@ -31,7 +31,7 @@ import CaptureScript from '../CaptureScript.astro'
<div class="d-block text-secondary text-truncate mt-n1">Change deprecated html tags to text decoration classes (#29604)</div> <div class="d-block text-secondary text-truncate mt-n1">Change deprecated html tags to text decoration classes (#29604)</div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<a href="#" class="list-group-item-actions"> <a href="#" class="list-group-item-actions" aria-label="Add to favorites">
<Icon name="star" color="muted" /> <Icon name="star" color="muted" />
</a> </a>
</div> </div>
@@ -47,7 +47,7 @@ import CaptureScript from '../CaptureScript.astro'
<div class="d-block text-secondary text-truncate mt-n1">justify-content:between ⇒ justify-content:space-between (#29734)</div> <div class="d-block text-secondary text-truncate mt-n1">justify-content:between ⇒ justify-content:space-between (#29734)</div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<a href="#" class="list-group-item-actions show"> <a href="#" class="list-group-item-actions show" aria-label="Remove from favorites">
<Icon name="star" color="yellow" /> <Icon name="star" color="yellow" />
</a> </a>
</div> </div>
@@ -63,7 +63,7 @@ import CaptureScript from '../CaptureScript.astro'
<div class="d-block text-secondary text-truncate mt-n1">Update change-version.js (#29736)</div> <div class="d-block text-secondary text-truncate mt-n1">Update change-version.js (#29736)</div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<a href="#" class="list-group-item-actions"> <a href="#" class="list-group-item-actions" aria-label="Add to favorites">
<Icon name="star" color="muted" /> <Icon name="star" color="muted" />
</a> </a>
</div> </div>
@@ -79,7 +79,7 @@ import CaptureScript from '../CaptureScript.astro'
<div class="d-block text-secondary text-truncate mt-n1">Regenerate package-lock.json (#29730)</div> <div class="d-block text-secondary text-truncate mt-n1">Regenerate package-lock.json (#29730)</div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<a href="#" class="list-group-item-actions"> <a href="#" class="list-group-item-actions" aria-label="Add to favorites">
<Icon name="star" color="muted" /> <Icon name="star" color="muted" />
</a> </a>
</div> </div>
@@ -99,10 +99,12 @@ import CaptureScript from '../CaptureScript.astro'
<CaptureScript> <CaptureScript>
<!-- BEGIN NAVBAR NOTIFICATIONS CLOSE --> <!-- BEGIN NAVBAR NOTIFICATIONS CLOSE -->
<script is:inline> <script is:inline>
document.querySelector('[data-navbar-notifications-close]').addEventListener('click', () => { for (const close of document.querySelectorAll('[data-navbar-notifications-close]')) {
const toggle = document.getElementById('navbar-notifications-toggle') close.addEventListener('click', () => {
window.tabler.bootstrap.Dropdown.getOrCreateInstance(toggle).hide() const toggle = close.closest('.dropdown').querySelector('[data-bs-toggle="dropdown"]')
}) window.tabler.bootstrap.Dropdown.getOrCreateInstance(toggle).hide()
})
}
</script> </script>
<!-- END NAVBAR NOTIFICATIONS CLOSE --> <!-- END NAVBAR NOTIFICATIONS CLOSE -->
</CaptureScript> </CaptureScript>
+2 -2
View File
@@ -62,7 +62,7 @@ const data = tasksData as unknown as { columns: Column[] }
)} )}
<div class="col-auto text-secondary"> <div class="col-auto text-secondary">
<button class={`switch-icon switch-icon-scale${task.favorite ? ' active' : ''}`} data-bs-toggle="switch-icon"> <button class={`switch-icon switch-icon-scale${task.favorite ? ' active' : ''}`} aria-label="Mark as favorite" data-bs-toggle="switch-icon">
<span class="switch-icon-a text-muted"> <span class="switch-icon-a text-muted">
<Icon name="heart" /> <Icon name="heart" />
</span> </span>
@@ -89,7 +89,7 @@ const data = tasksData as unknown as { columns: Column[] }
</div> </div>
)} )}
<div class="col-auto"> <div class="col-auto">
<a href="#" class="link-secondary"> <a href="#" class="link-secondary" aria-label="Share">
<Icon name="share" /> <Icon name="share" />
</a> </a>
</div> </div>
+8 -8
View File
@@ -72,7 +72,7 @@ const base = '..'
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-4 ml-auto"> <div class="col-lg-4 ms-auto">
<div class="text-secondary">Tabler comes with tons of well-designed components and features. Start your adventure with Tabler and make your dashboard great again. For free!</div> <div class="text-secondary">Tabler comes with tons of well-designed components and features. Start your adventure with Tabler and make your dashboard great again. For free!</div>
</div> </div>
</div> </div>
@@ -100,16 +100,16 @@ const base = '..'
<Subheader as="h5">Follow us on</Subheader> <Subheader as="h5">Follow us on</Subheader>
<ul class="list-inline mb-0 mt-3"> <ul class="list-inline mb-0 mt-3">
<li class="list-inline-item"> <li class="list-inline-item">
<a class="btn btn-icon btn-facebook" href="#"><Icon name="brand-facebook" /></a> <a class="btn btn-icon btn-facebook" href="#" aria-label="Facebook"><Icon name="brand-facebook" /></a>
</li> </li>
<li class="list-inline-item"> <li class="list-inline-item">
<a class="btn btn-icon btn-instagram" href="#"><Icon name="brand-instagram" /></a> <a class="btn btn-icon btn-instagram" href="#" aria-label="Instagram"><Icon name="brand-instagram" /></a>
</li> </li>
<li class="list-inline-item"> <li class="list-inline-item">
<a class="btn btn-icon btn-twitter" href="#"><Icon name="brand-twitter" /></a> <a class="btn btn-icon btn-twitter" href="#" aria-label="Twitter"><Icon name="brand-twitter" /></a>
</li> </li>
<li class="list-inline-item"> <li class="list-inline-item">
<a class="btn btn-icon btn-linkedin" href="#"><Icon name="brand-linkedin" /></a> <a class="btn btn-icon btn-linkedin" href="#" aria-label="LinkedIn"><Icon name="brand-linkedin" /></a>
</li> </li>
</ul> </ul>
</div> </div>
@@ -120,10 +120,10 @@ const base = '..'
<footer class="footer" aria-label="Legal"> <footer class="footer" aria-label="Legal">
<div class="container"> <div class="container">
<div class="py-3 border-top-light text-center text-lg-start"> <div class="py-3 border-top text-center text-lg-start">
<div class="row g-lg-4"> <div class="row g-lg-4">
<div class="col-lg-auto text-lg-end order-lg-last"> <div class="col-lg-auto text-lg-end order-lg-last">
<div class="row justify-center"> <div class="row justify-content-center">
<div class="col-auto"> <div class="col-auto">
©<a href="https://codecalm.net" class="link-secondary" target="_blank" rel="noopener noreferrer">codecalm.net</a> ©<a href="https://codecalm.net" class="link-secondary" target="_blank" rel="noopener noreferrer">codecalm.net</a>
</div> </div>
@@ -133,7 +133,7 @@ const base = '..'
<a class="link-secondary" href="/terms-of-service">Terms of service</a> <a class="link-secondary" href="/terms-of-service">Terms of service</a>
</li> </li>
<li class="list-inline-item"> <li class="list-inline-item">
<a class="link-secondary" href="/privacy-policy">Privacy policy</a> <a class="link-secondary" href="#">Privacy policy</a>
</li> </li>
</ul> </ul>
</div> </div>
+1 -1
View File
@@ -21,7 +21,7 @@ const { title, pageLibs, bodyClass } = Astro.props
<Logo smallLogo /> <Logo smallLogo />
<div> <div>
<a href="." class="btn btn-close"></a> <a href="." class="btn btn-close" aria-label="Close"></a>
</div> </div>
</div> </div>
</header> </header>
+4 -2
View File
@@ -5,13 +5,15 @@ import type { AvatarSize } from './Avatar.astro'
interface Props { interface Props {
class?: string class?: string
size?: AvatarSize | undefined size?: AvatarSize | undefined
/** accessible name of the upload link */
label?: string
} }
const { class: className, size } = Astro.props const { class: className, size, label = 'Upload photo' } = Astro.props
const classes = ['avatar', 'avatar-upload', className, size && `avatar-${size}`] const classes = ['avatar', 'avatar-upload', className, size && `avatar-${size}`]
--- ---
<a href="#" class:list={classes}> <a href="#" class:list={classes} aria-label={label}>
<Icon name="plus" /> <Icon name="plus" />
</a> </a>
+4 -2
View File
@@ -85,10 +85,12 @@ const datepickerId = id ? `datepicker-${id}` : undefined;
// name. Litepicker also re-renders these buttons (new DOM nodes) on every open // name. Litepicker also re-renders these buttons (new DOM nodes) on every open
// and every month change, so re-apply the labels on each "render" event instead // and every month change, so re-apply the labels on each "render" event instead
// of labeling once at init. // of labeling once at init.
picker.on('render', () => { const labelMonthButtons = () => {
picker.ui?.querySelector('.button-previous-month')?.setAttribute('aria-label', 'Previous month'); picker.ui?.querySelector('.button-previous-month')?.setAttribute('aria-label', 'Previous month');
picker.ui?.querySelector('.button-next-month')?.setAttribute('aria-label', 'Next month'); picker.ui?.querySelector('.button-next-month')?.setAttribute('aria-label', 'Next month');
}); };
picker.on('render', labelMonthButtons);
labelMonthButtons();
window.tabler_datepicker[datepickerId] = picker; window.tabler_datepicker[datepickerId] = picker;
} }
+10 -1
View File
@@ -1,4 +1,5 @@
--- ---
import { ucFirst } from '@shared/lib/string-format'
import Icon from './Icon.astro' import Icon from './Icon.astro'
interface Props { interface Props {
@@ -40,7 +41,15 @@ const rows = Array.from({ length: count }, (_, i) => {
return ( return (
<Fragment> <Fragment>
{name && <input type="radio" class="nav-link-input" name={name} id={`segmented-${name}-${row.index}`} checked={row.isDefault} />} {name && <input type="radio" class="nav-link-input" name={name} id={`segmented-${name}-${row.index}`} checked={row.isDefault} />}
<Element for={name ? `segmented-${name}-${row.index}` : undefined} class:list={row.linkClasses} role={name ? undefined : 'tab'} data-bs-toggle={name ? undefined : 'tab'} aria-selected={name ? undefined : row.isDefault ? 'true' : 'false'} aria-disabled={row.isDisabled ? 'true' : undefined}> <Element
for={name ? `segmented-${name}-${row.index}` : undefined}
class:list={row.linkClasses}
role={name ? undefined : 'tab'}
data-bs-toggle={name ? undefined : 'tab'}
aria-selected={name ? undefined : row.isDefault ? 'true' : 'false'}
aria-disabled={row.isDisabled ? 'true' : undefined}
aria-label={row.item ? undefined : row.icon && ucFirst(row.icon)}
>
{row.icon && <Icon name={row.icon} class="nav-link-icon" />} {row.icon && <Icon name={row.icon} class="nav-link-icon" />}
{row.item && row.item} {row.item && row.item}
</Element> </Element>