Compare commits

...
3 Commits
Author SHA1 Message Date
Ronan Berder 77680f9e2b Bumping version number 2025-11-17 10:53:40 +08:00
Ronan Berder 2afa2ae02e Fixing and extending combobox and command 2025-11-17 10:45:39 +08:00
Ronan Berder 23585e3161 Fixing #107 2025-11-14 23:58:35 +08:00
10 changed files with 553 additions and 520 deletions
+371 -367
View File
@@ -2791,52 +2791,54 @@
}
}
}
.button-group {
isolation: isolate;
display: inline-flex;
width: fit-content;
align-items: stretch;
> *:focus-visible, > :is(.dropdown-menu, .popover, .select) > button:focus-visible {
position: relative;
z-index: 10;
}
> hr[role='separator'] {
margin: calc(var(--spacing) * 0);
height: auto;
width: calc(var(--spacing) * 0);
flex-shrink: 0;
align-self: stretch;
border-style: var(--tw-border-style);
border-width: 1px;
border-color: var(--color-input);
}
&:not([data-orientation='vertical']) {
> *:not(:first-child), > :is(.dropdown-menu, .popover, .select):not(:first-child) > button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left-style: var(--tw-border-style);
border-left-width: 0px;
@layer components {
.button-group {
isolation: isolate;
display: inline-flex;
width: fit-content;
align-items: stretch;
> *:focus-visible, > :is(.dropdown-menu, .popover, .select) > button:focus-visible {
position: relative;
z-index: 10;
}
> *:not(:last-child), > :is(.dropdown-menu, .popover, .select):not(:last-child) > button {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
&[data-orientation='vertical'] {
flex-direction: column;
> hr[role='separator'] {
height: 1px;
width: auto;
margin: calc(var(--spacing) * 0);
height: auto;
width: calc(var(--spacing) * 0);
flex-shrink: 0;
align-self: stretch;
border-style: var(--tw-border-style);
border-width: 1px;
border-color: var(--color-input);
}
> *:not(:first-child), > :is(.dropdown-menu, .popover, .select):not(:first-child) > button {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-top-style: var(--tw-border-style);
border-top-width: 0px;
&:not([data-orientation='vertical']) {
> *:not(:first-child), > :is(.dropdown-menu, .popover, .select):not(:first-child) > button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left-style: var(--tw-border-style);
border-left-width: 0px;
}
> *:not(:last-child), > :is(.dropdown-menu, .popover, .select):not(:last-child) > button {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
> *:not(:last-child), > :is(.dropdown-menu, .popover, .select):not(:last-child) > button {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
&[data-orientation='vertical'] {
flex-direction: column;
> hr[role='separator'] {
height: 1px;
width: auto;
}
> *:not(:first-child), > :is(.dropdown-menu, .popover, .select):not(:first-child) > button {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-top-style: var(--tw-border-style);
border-top-width: 0px;
}
> *:not(:last-child), > :is(.dropdown-menu, .popover, .select):not(:last-child) > button {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
}
}
}
@@ -3277,7 +3279,7 @@
margin-block: calc(var(--spacing) * 1);
border-color: var(--color-border);
}
&:not(:has([data-value]:not([aria-hidden='true'])))::before {
&:not(:has([role='menuitem']:not([aria-hidden='true'])))::before {
margin: calc(var(--spacing) * -1);
display: flex;
align-items: center;
@@ -3290,11 +3292,11 @@
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
}
&[data-empty]:not(:has([data-value]:not([aria-hidden='true'])))::before {
&[data-empty]:not(:has([role='menuitem']:not([aria-hidden='true'])))::before {
--tw-content: attr(data-empty);
content: var(--tw-content);
}
&:not([data-empty]):not(:has([data-value]:not([aria-hidden='true'])))::before {
&:not([data-empty]):not(:has([role='menuitem']:not([aria-hidden='true'])))::before {
--tw-content: 'No results found';
content: var(--tw-content);
}
@@ -4401,355 +4403,357 @@
}
}
}
.sidebar {
&:not([data-sidebar-initialized]) {
@media (width < 48rem) {
display: none;
@layer components {
.sidebar {
&:not([data-sidebar-initialized]) {
@media (width < 48rem) {
display: none;
}
}
}
&:not([aria-hidden]), &[aria-hidden=false] {
@media (width < 48rem) {
&:not([aria-hidden]), &[aria-hidden=false] {
@media (width < 48rem) {
position: fixed;
}
@media (width < 48rem) {
inset: calc(var(--spacing) * 0);
}
@media (width < 48rem) {
z-index: 40;
}
@media (width < 48rem) {
background-color: color-mix(in srgb, #000 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 50%, transparent);
}
}
}
nav {
position: fixed;
}
@media (width < 48rem) {
inset: calc(var(--spacing) * 0);
}
@media (width < 48rem) {
z-index: 40;
}
@media (width < 48rem) {
background-color: color-mix(in srgb, #000 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 50%, transparent);
inset-block: calc(var(--spacing) * 0);
z-index: 50;
display: flex;
width: var(--sidebar-mobile-width);
flex-direction: column;
background-color: var(--color-sidebar);
color: var(--color-sidebar-foreground);
transition-property: transform, translate, scale, rotate;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
--tw-duration: 300ms;
transition-duration: 300ms;
--tw-ease: var(--ease-in-out);
transition-timing-function: var(--ease-in-out);
@media (width >= 48rem) {
width: var(--sidebar-width);
}
}
}
nav {
position: fixed;
inset-block: calc(var(--spacing) * 0);
z-index: 50;
display: flex;
width: var(--sidebar-mobile-width);
flex-direction: column;
background-color: var(--color-sidebar);
color: var(--color-sidebar-foreground);
transition-property: transform, translate, scale, rotate;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
--tw-duration: 300ms;
transition-duration: 300ms;
--tw-ease: var(--ease-in-out);
transition-timing-function: var(--ease-in-out);
@media (width >= 48rem) {
width: var(--sidebar-width);
}
}
& + * {
transition-property: margin;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
--tw-duration: 300ms;
transition-duration: 300ms;
--tw-ease: var(--ease-in-out);
transition-timing-function: var(--ease-in-out);
}
&:not([data-side]), &[data-side=left] {
nav {
left: calc(var(--spacing) * 0);
border-right-style: var(--tw-border-style);
border-right-width: 1px;
}
& + * {
position: relative;
@media (width >= 48rem) {
margin-left: var(--sidebar-width);
}
transition-property: margin;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
--tw-duration: 300ms;
transition-duration: 300ms;
--tw-ease: var(--ease-in-out);
transition-timing-function: var(--ease-in-out);
}
&[aria-hidden=true] {
&:not([data-side]), &[data-side=left] {
nav {
--tw-translate-x: -100%;
translate: var(--tw-translate-x) var(--tw-translate-y);
left: calc(var(--spacing) * 0);
border-right-style: var(--tw-border-style);
border-right-width: 1px;
}
& + * {
@media (width >= 48rem) {
margin-left: calc(var(--spacing) * 0);
}
}
}
}
&[data-side=right] {
nav {
right: calc(var(--spacing) * 0);
border-left-style: var(--tw-border-style);
border-left-width: 1px;
}
& + * {
position: relative;
@media (width >= 48rem) {
margin-right: var(--sidebar-width);
}
}
&[aria-hidden=true] {
nav {
--tw-translate-x: 100%;
translate: var(--tw-translate-x) var(--tw-translate-y);
}
& + * {
@media (width >= 48rem) {
margin-right: calc(var(--spacing) * 0);
}
}
}
}
nav {
> header, > footer {
display: flex;
flex-direction: column;
gap: calc(var(--spacing) * 2);
padding: calc(var(--spacing) * 2);
}
[role=separator] {
margin-inline: calc(var(--spacing) * 2);
width: auto;
border-color: var(--color-sidebar-border);
}
> section {
display: flex;
min-height: calc(var(--spacing) * 0);
flex: 1;
flex-direction: column;
gap: calc(var(--spacing) * 2);
overflow-y: auto;
> [role=group] {
position: relative;
@media (width >= 48rem) {
margin-left: var(--sidebar-width);
}
}
&[aria-hidden=true] {
nav {
--tw-translate-x: -100%;
translate: var(--tw-translate-x) var(--tw-translate-y);
}
& + * {
@media (width >= 48rem) {
margin-left: calc(var(--spacing) * 0);
}
}
}
}
&[data-side=right] {
nav {
right: calc(var(--spacing) * 0);
border-left-style: var(--tw-border-style);
border-left-width: 1px;
}
& + * {
position: relative;
@media (width >= 48rem) {
margin-right: var(--sidebar-width);
}
}
&[aria-hidden=true] {
nav {
--tw-translate-x: 100%;
translate: var(--tw-translate-x) var(--tw-translate-y);
}
& + * {
@media (width >= 48rem) {
margin-right: calc(var(--spacing) * 0);
}
}
}
}
nav {
> header, > footer {
display: flex;
width: 100%;
min-width: calc(var(--spacing) * 0);
flex-direction: column;
gap: calc(var(--spacing) * 2);
padding: calc(var(--spacing) * 2);
}
h3 {
display: flex;
height: calc(var(--spacing) * 8);
flex-shrink: 0;
align-items: center;
border-radius: var(--radius-md);
padding-inline: calc(var(--spacing) * 2);
font-size: var(--text-xs);
line-height: var(--tw-leading, var(--text-xs--line-height));
--tw-font-weight: var(--font-weight-medium);
font-weight: var(--font-weight-medium);
color: var(--color-sidebar-foreground);
@supports (color: color-mix(in lab, red, red)) {
color: color-mix(in oklab, var(--color-sidebar-foreground) 70%, transparent);
}
--tw-ring-color: var(--color-sidebar-ring);
--tw-outline-style: none;
outline-style: none;
@media (forced-colors: active) {
outline: 2px solid transparent;
outline-offset: 2px;
}
transition-property: margin,opacity;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
--tw-duration: 200ms;
transition-duration: 200ms;
--tw-ease: linear;
transition-timing-function: linear;
&:focus-visible {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
&>svg {
width: calc(var(--spacing) * 4);
height: calc(var(--spacing) * 4);
}
&>svg {
flex-shrink: 0;
}
[role=separator] {
margin-inline: calc(var(--spacing) * 2);
width: auto;
border-color: var(--color-sidebar-border);
}
ul {
> section {
display: flex;
width: 100%;
min-width: calc(var(--spacing) * 0);
min-height: calc(var(--spacing) * 0);
flex: 1;
flex-direction: column;
gap: calc(var(--spacing) * 1);
li {
gap: calc(var(--spacing) * 2);
overflow-y: auto;
> [role=group] {
position: relative;
> a, > details > summary {
display: flex;
width: 100%;
align-items: center;
gap: calc(var(--spacing) * 2);
overflow: hidden;
border-radius: var(--radius-md);
padding: calc(var(--spacing) * 2);
text-align: left;
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
--tw-ring-color: var(--color-sidebar-ring);
--tw-outline-style: none;
outline-style: none;
@media (forced-colors: active) {
outline: 2px solid transparent;
outline-offset: 2px;
}
transition-property: width,height,padding;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
&:hover {
@media (hover: hover) {
background-color: var(--color-sidebar-accent);
}
}
&:hover {
@media (hover: hover) {
color: var(--color-sidebar-accent-foreground);
}
}
&:focus-visible {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
&:active {
background-color: var(--color-sidebar-accent);
}
&:active {
color: var(--color-sidebar-accent-foreground);
}
&:disabled {
pointer-events: none;
}
&:disabled {
opacity: 50%;
}
&[aria-disabled="true"] {
pointer-events: none;
}
&[aria-disabled="true"] {
opacity: 50%;
}
&>span:last-child {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&>svg {
width: calc(var(--spacing) * 4);
height: calc(var(--spacing) * 4);
}
&>svg {
flex-shrink: 0;
}
&[aria-current=page] {
background-color: var(--color-sidebar-accent);
}
&[aria-current=page] {
--tw-font-weight: var(--font-weight-medium);
font-weight: var(--font-weight-medium);
}
&[aria-current=page] {
color: var(--color-sidebar-accent-foreground);
}
&:not([data-variant]), &[data-variant=default] {
&:hover {
@media (hover: hover) {
background-color: var(--color-sidebar-accent);
}
}
&:hover {
@media (hover: hover) {
color: var(--color-sidebar-accent-foreground);
}
}
}
&[data-variant=outline] {
background-color: var(--color-background);
--tw-shadow: 0 0 0 1px var(--tw-shadow-color, hsl(var(--sidebar-border)));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
&:hover {
@media (hover: hover) {
background-color: var(--color-sidebar-accent);
}
}
&:hover {
@media (hover: hover) {
color: var(--color-sidebar-accent-foreground);
}
}
&:hover {
@media (hover: hover) {
--tw-shadow: 0 0 0 1px var(--tw-shadow-color, hsl(var(--sidebar-accent)));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
}
}
&:not([data-size]), &[data-size=default] {
height: calc(var(--spacing) * 8);
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
}
&[data-size=sm] {
height: calc(var(--spacing) * 7);
font-size: var(--text-xs);
line-height: var(--tw-leading, var(--text-xs--line-height));
}
&[data-size=lg] {
height: calc(var(--spacing) * 12);
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
&:is(:where(.group)[data-collapsible="icon"] *) {
padding: calc(var(--spacing) * 0) !important;
}
}
display: flex;
width: 100%;
min-width: calc(var(--spacing) * 0);
flex-direction: column;
padding: calc(var(--spacing) * 2);
}
h3 {
display: flex;
height: calc(var(--spacing) * 8);
flex-shrink: 0;
align-items: center;
border-radius: var(--radius-md);
padding-inline: calc(var(--spacing) * 2);
font-size: var(--text-xs);
line-height: var(--tw-leading, var(--text-xs--line-height));
--tw-font-weight: var(--font-weight-medium);
font-weight: var(--font-weight-medium);
color: var(--color-sidebar-foreground);
@supports (color: color-mix(in lab, red, red)) {
color: color-mix(in oklab, var(--color-sidebar-foreground) 70%, transparent);
}
> details {
&:not([open]) {
> summary {
&::after {
rotate: calc(90deg * -1);
}
}
}
> summary {
&::after {
margin-left: auto;
display: block;
width: calc(var(--spacing) * 3.5);
height: calc(var(--spacing) * 3.5);
background-color: var(--color-primary);
transition-property: transform, translate, scale, rotate;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
--tw-ease: linear;
transition-timing-function: linear;
--tw-content: '';
content: var(--tw-content);
mask-image: var(--chevron-down-icon);
mask-size: 1rem;
mask-position: center;
mask-repeat: no-repeat;
}
}
&::details-content {
padding-inline: calc(var(--spacing) * 3.5);
}
--tw-ring-color: var(--color-sidebar-ring);
--tw-outline-style: none;
outline-style: none;
@media (forced-colors: active) {
outline: 2px solid transparent;
outline-offset: 2px;
}
transition-property: margin,opacity;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
--tw-duration: 200ms;
transition-duration: 200ms;
--tw-ease: linear;
transition-timing-function: linear;
&:focus-visible {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
&>svg {
width: calc(var(--spacing) * 4);
height: calc(var(--spacing) * 4);
}
&>svg {
flex-shrink: 0;
}
}
ul {
display: flex;
width: 100%;
min-width: calc(var(--spacing) * 0);
--tw-translate-x: 1px;
translate: var(--tw-translate-x) var(--tw-translate-y);
flex-direction: column;
gap: calc(var(--spacing) * 1);
border-left-style: var(--tw-border-style);
border-left-width: 1px;
border-color: var(--color-sidebar-border);
padding-inline: calc(var(--spacing) * 2.5);
padding-block: calc(var(--spacing) * 0.5);
li {
position: relative;
> a, > details > summary {
display: flex;
width: 100%;
align-items: center;
gap: calc(var(--spacing) * 2);
overflow: hidden;
border-radius: var(--radius-md);
padding: calc(var(--spacing) * 2);
text-align: left;
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
--tw-ring-color: var(--color-sidebar-ring);
--tw-outline-style: none;
outline-style: none;
@media (forced-colors: active) {
outline: 2px solid transparent;
outline-offset: 2px;
}
transition-property: width,height,padding;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
&:hover {
@media (hover: hover) {
background-color: var(--color-sidebar-accent);
}
}
&:hover {
@media (hover: hover) {
color: var(--color-sidebar-accent-foreground);
}
}
&:focus-visible {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
&:active {
background-color: var(--color-sidebar-accent);
}
&:active {
color: var(--color-sidebar-accent-foreground);
}
&:disabled {
pointer-events: none;
}
&:disabled {
opacity: 50%;
}
&[aria-disabled="true"] {
pointer-events: none;
}
&[aria-disabled="true"] {
opacity: 50%;
}
&>span:last-child {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&>svg {
width: calc(var(--spacing) * 4);
height: calc(var(--spacing) * 4);
}
&>svg {
flex-shrink: 0;
}
&[aria-current=page] {
background-color: var(--color-sidebar-accent);
}
&[aria-current=page] {
--tw-font-weight: var(--font-weight-medium);
font-weight: var(--font-weight-medium);
}
&[aria-current=page] {
color: var(--color-sidebar-accent-foreground);
}
&:not([data-variant]), &[data-variant=default] {
&:hover {
@media (hover: hover) {
background-color: var(--color-sidebar-accent);
}
}
&:hover {
@media (hover: hover) {
color: var(--color-sidebar-accent-foreground);
}
}
}
&[data-variant=outline] {
background-color: var(--color-background);
--tw-shadow: 0 0 0 1px var(--tw-shadow-color, hsl(var(--sidebar-border)));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
&:hover {
@media (hover: hover) {
background-color: var(--color-sidebar-accent);
}
}
&:hover {
@media (hover: hover) {
color: var(--color-sidebar-accent-foreground);
}
}
&:hover {
@media (hover: hover) {
--tw-shadow: 0 0 0 1px var(--tw-shadow-color, hsl(var(--sidebar-accent)));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
}
}
&:not([data-size]), &[data-size=default] {
height: calc(var(--spacing) * 8);
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
}
&[data-size=sm] {
height: calc(var(--spacing) * 7);
font-size: var(--text-xs);
line-height: var(--tw-leading, var(--text-xs--line-height));
}
&[data-size=lg] {
height: calc(var(--spacing) * 12);
font-size: var(--text-sm);
line-height: var(--tw-leading, var(--text-sm--line-height));
&:is(:where(.group)[data-collapsible="icon"] *) {
padding: calc(var(--spacing) * 0) !important;
}
}
}
> details {
&:not([open]) {
> summary {
&::after {
rotate: calc(90deg * -1);
}
}
}
> summary {
&::after {
margin-left: auto;
display: block;
width: calc(var(--spacing) * 3.5);
height: calc(var(--spacing) * 3.5);
background-color: var(--color-primary);
transition-property: transform, translate, scale, rotate;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
--tw-ease: linear;
transition-timing-function: linear;
--tw-content: '';
content: var(--tw-content);
mask-image: var(--chevron-down-icon);
mask-size: 1rem;
mask-position: center;
mask-repeat: no-repeat;
}
}
&::details-content {
padding-inline: calc(var(--spacing) * 3.5);
}
}
}
ul {
display: flex;
width: 100%;
min-width: calc(var(--spacing) * 0);
--tw-translate-x: 1px;
translate: var(--tw-translate-x) var(--tw-translate-y);
flex-direction: column;
gap: calc(var(--spacing) * 1);
border-left-style: var(--tw-border-style);
border-left-width: 1px;
border-color: var(--color-sidebar-border);
padding-inline: calc(var(--spacing) * 2.5);
padding-block: calc(var(--spacing) * 0.5);
}
}
}
}
+8 -1
View File
@@ -118,7 +118,14 @@ toc:
</ul>
<dl>
<dt><code class="highlight language-html">&lt;div role="option" data-value="{ VALUE }"&gt;</code></dt>
<dd>Option that can be selected.Should have a unique id if you use the <code>aria-activedescendant</code> attribute on the trigger.</dd>
<dd>Option that can be selected. Should have a unique id if you use the <code>aria-activedescendant</code> attribute on the trigger. Optional attributes:
<ul>
<li><code>data-filter</code>: custom text used for filtering (if different from displayed content, e.g., <code>data-filter="united states"</code>)</li>
<li><code>data-keywords</code>: additional keywords for enhanced filtering (e.g., <code>data-keywords="bread fruit"</code>)</li>
<li><code>data-force</code>: forces the option to always display, regardless of filter (e.g., <code>data-force</code>)</li>
<li><code>aria-disabled="true"</code>: marks option as disabled (excluded from selection and keyboard navigation)</li>
</ul>
</dd>
<dt><code class="highlight language-html">&lt;hr role="separator"&gt;</code> <span class="badge-secondary">Optional</span></dt>
<dd>Separator between groups/options.</dd>
<dt><code class="highlight language-html">&lt;div role="group"&gt;</code> <span class="badge-secondary">Optional</span></dt>
+11 -10
View File
@@ -33,15 +33,15 @@ toc:
{% macro command_items(suggestions_id="suggestions", settings_id="settings") %}
<div role="group" aria-labelledby="{{ suggestions_id }}">
<span role="heading" id="{{ suggestions_id }}">Suggestions</span>
<div role="menuitem" data-label="calendar" onclick="console.log('Open calendar')">
<div role="menuitem" onclick="console.log('Open calendar')">
{% lucide "calendar" %}
<span>Calendar</span>
</div>
<div role="menuitem" data-label="search-emoji" onclick="console.log('Search emoji')">
<div role="menuitem" onclick="console.log('Search emoji')">
{% lucide "smile" %}
<span>Search Emoji</span>
</div>
<div role="menuitem" data-label="calculator" aria-disabled="true">
<div role="menuitem" aria-disabled="true">
{% lucide "calculator" %}
<span>Calculator</span>
</div>
@@ -49,17 +49,17 @@ toc:
<hr role="separator" />
<div role="group" aria-labelledby="{{ settings_id }}">
<span role="heading" id="{{ settings_id }}">Settings</span>
<div role="menuitem" data-label="profile" onclick="console.log('Open profile')">
<div role="menuitem" onclick="console.log('Open profile')" data-filter="Profile">
{% lucide "user" %}
<span>Profile</span>
<kbd class="ml-auto text-muted-foreground bg-transparent tracking-widest">⌘P</kbd>
</div>
<div role="menuitem" data-label="billing" onclick="console.log('Open billing')">
<div role="menuitem" onclick="console.log('Open billing')" data-filter="Billing">
{% lucide "credit-card" %}
<span>Billing</span>
<kbd class="ml-auto text-muted-foreground bg-transparent tracking-widest">⌘B</kbd>
</div>
<div role="menuitem" data-label="settings" onclick="console.log('Open settings')">
<div role="menuitem" onclick="console.log('Open settings')" data-filter="Settings">
{% lucide "settings" %}
<span>Settings</span>
<kbd class="ml-auto text-muted-foreground bg-transparent tracking-widest">⌘S</kbd>
@@ -158,8 +158,9 @@ toc:
<dt><code class="highlight language-html">&lt;div role="menuitem"&gt;</code></dt>
<dd>Command item that triggers an action when clicked. In a command-dialog, clicking a menuitem automatically closes the dialog unless the <code>data-keep-command-open</code> attribute is present. Optional attributes:
<ul>
<li><code>data-label</code>: custom label for filtering (if different from text content)</li>
<li><code>data-keywords</code>: additional keywords for enhanced filtering</li>
<li><code>data-filter</code>: custom text used for filtering (if different from displayed content, e.g., <code>data-filter="calendar event"</code>)</li>
<li><code>data-keywords</code>: additional keywords for enhanced filtering (e.g., <code>data-keywords="calendar event date"</code>)</li>
<li><code>data-force</code>: forces the item to always display, regardless of filter (e.g., <code>data-force</code>)</li>
<li><code>aria-disabled="true"</code>: marks item as disabled (excluded from keyboard navigation and filtering)</li>
</ul>
</dd>
@@ -209,11 +210,11 @@ toc:
</div>
{% set raw_code %}{% raw %}{% call command() %}
<div role="menuitem" data-label="calendar">
<div role="menuitem">
<svg>...</svg>
<span>Calendar</span>
</div>
<div role="menuitem" data-label="settings">
<div role="menuitem" data-keywords="config preferences">
<svg>...</svg>
<span>Settings</span>
</div>
+2 -2
View File
@@ -58,8 +58,8 @@ toc:
type: "group",
label: "Fruits",
items: [
{ type: "item", value: "apple", label: "Apple" },
{ type: "item", value: "banana", label: "Banana" },
{ type: "item", value: "apple", label: "Apple", attrs: {"data-force": "true"} },
{ type: "item", value: "banana", label: "Banana", attrs: {"data-keywords": "bread"} },
{ type: "item", value: "blueberry", label: "Blueberry" },
{ type: "item", value: "pineapple", label: "Grapes" },
{ type: "item", value: "pineapple", label: "Pineapple" }
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "basecoat",
"version": "0.3.4",
"version": "0.3.6",
"description": "shadcn/ui for the rest of us",
"author": "hunvreus",
"type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "basecoat-cli",
"version": "0.3.4",
"version": "0.3.6",
"description": "Add Basecoat components to your project",
"author": "hunvreus",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "basecoat-css",
"version": "0.3.4",
"version": "0.3.6",
"description": "Tailwind CSS for Basecoat components",
"author": {
"name": "hunvreus",
+137 -133
View File
@@ -381,42 +381,44 @@
}
/* Button Group */
.button-group {
@apply inline-flex w-fit items-stretch isolate;
> *:focus-visible,
> :is(.dropdown-menu, .popover, .select) > button:focus-visible {
@apply relative z-10;
}
> hr[role='separator'] {
@apply w-0 h-auto self-stretch border border-input shrink-0 m-0;
}
&:not([data-orientation='vertical']) {
> *:not(:first-child),
> :is(.dropdown-menu, .popover, .select):not(:first-child) > button {
@apply rounded-l-none border-l-0;
@layer components {
.button-group {
@apply inline-flex w-fit items-stretch isolate;
> *:focus-visible,
> :is(.dropdown-menu, .popover, .select) > button:focus-visible {
@apply relative z-10;
}
> *:not(:last-child),
> :is(.dropdown-menu, .popover, .select):not(:last-child) > button {
@apply rounded-r-none;
}
}
&[data-orientation='vertical'] {
@apply flex-col;
> hr[role='separator'] {
@apply w-auto h-px;
@apply w-0 h-auto self-stretch border border-input shrink-0 m-0;
}
> *:not(:first-child),
> :is(.dropdown-menu, .popover, .select):not(:first-child) > button {
@apply rounded-t-none border-t-0;
}
> *:not(:last-child),
> :is(.dropdown-menu, .popover, .select):not(:last-child) > button {
@apply rounded-b-none;
&:not([data-orientation='vertical']) {
> *:not(:first-child),
> :is(.dropdown-menu, .popover, .select):not(:first-child) > button {
@apply rounded-l-none border-l-0;
}
> *:not(:last-child),
> :is(.dropdown-menu, .popover, .select):not(:last-child) > button {
@apply rounded-r-none;
}
}
&[data-orientation='vertical'] {
@apply flex-col;
> hr[role='separator'] {
@apply w-auto h-px;
}
> *:not(:first-child),
> :is(.dropdown-menu, .popover, .select):not(:first-child) > button {
@apply rounded-t-none border-t-0;
}
> *:not(:last-child),
> :is(.dropdown-menu, .popover, .select):not(:last-child) > button {
@apply rounded-b-none;
}
}
}
}
@@ -570,13 +572,13 @@
[role='separator'] {
@apply border-border -mx-1 my-1;
}
&:not(:has([data-value]:not([aria-hidden='true'])))::before {
&:not(:has([role='menuitem']:not([aria-hidden='true'])))::before {
@apply flex items-center justify-center py-6 px-3 text-sm truncate -m-1;
}
&[data-empty]:not(:has([data-value]:not([aria-hidden='true'])))::before {
&[data-empty]:not(:has([role='menuitem']:not([aria-hidden='true'])))::before {
@apply content-[attr(data-empty)];
}
&:not([data-empty]):not(:has([data-value]:not([aria-hidden='true'])))::before {
&:not([data-empty]):not(:has([role='menuitem']:not([aria-hidden='true'])))::before {
@apply content-['No_results_found'];
}
}
@@ -988,119 +990,121 @@
}
/* Sidebar */
.sidebar {
&:not([data-sidebar-initialized]) {
@apply max-md:hidden;
}
&:not([aria-hidden]),
&[aria-hidden=false] {
@apply max-md:bg-black/50 max-md:fixed max-md:inset-0 max-md:z-40;
}
nav {
@apply bg-sidebar text-sidebar-foreground flex flex-col w-(--sidebar-mobile-width) md:w-(--sidebar-width) fixed inset-y-0 z-50 transition-transform ease-in-out duration-300;
}
& + * {
@apply transition-[margin] ease-in-out duration-300;
}
&:not([data-side]),
&[data-side=left] {
@layer components {
.sidebar {
&:not([data-sidebar-initialized]) {
@apply max-md:hidden;
}
&:not([aria-hidden]),
&[aria-hidden=false] {
@apply max-md:bg-black/50 max-md:fixed max-md:inset-0 max-md:z-40;
}
nav {
@apply left-0 border-r;
@apply bg-sidebar text-sidebar-foreground flex flex-col w-(--sidebar-mobile-width) md:w-(--sidebar-width) fixed inset-y-0 z-50 transition-transform ease-in-out duration-300;
}
& + * {
@apply relative md:ml-(--sidebar-width);
@apply transition-[margin] ease-in-out duration-300;
}
&[aria-hidden=true] {
&:not([data-side]),
&[data-side=left] {
nav {
@apply -translate-x-full;
@apply left-0 border-r;
}
& + * {
@apply md:ml-0;
@apply relative md:ml-(--sidebar-width);
}
&[aria-hidden=true] {
nav {
@apply -translate-x-full;
}
& + * {
@apply md:ml-0;
}
}
}
&[data-side=right] {
nav {
@apply right-0 border-l;
}
& + * {
@apply relative md:mr-(--sidebar-width);
}
&[aria-hidden=true] {
nav {
@apply translate-x-full;
}
& + * {
@apply md:mr-0;
}
}
}
}
&[data-side=right] {
nav {
@apply right-0 border-l;
}
& + * {
@apply relative md:mr-(--sidebar-width);
}
&[aria-hidden=true] {
nav {
@apply translate-x-full;
> header,
> footer {
@apply flex flex-col gap-2 p-2;
}
& + * {
@apply md:mr-0;
[role=separator] {
@apply border-sidebar-border mx-2 w-auto;
}
}
}
nav {
> header,
> footer {
@apply flex flex-col gap-2 p-2;
}
[role=separator] {
@apply border-sidebar-border mx-2 w-auto;
}
> section {
@apply flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto;
> section {
@apply flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto;
> [role=group] {
@apply relative flex w-full min-w-0 flex-col p-2;
}
h3 {
@apply text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0;
}
ul {
@apply flex w-full min-w-0 flex-col gap-1;
li {
@apply relative;
> a,
> details > summary {
@apply flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&[aria-current=page]]:bg-sidebar-accent [&[aria-current=page]]:font-medium [&[aria-current=page]]:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0;
&:not([data-variant]),
&[data-variant=default] {
@apply hover:bg-sidebar-accent hover:text-sidebar-accent-foreground;
}
&[data-variant=outline] {
@apply bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))];
}
&:not([data-size]),
&[data-size=default] {
@apply h-8 text-sm;
}
&[data-size=sm] {
@apply h-7 text-xs;
}
&[data-size=lg] {
@apply h-12 text-sm group-data-[collapsible=icon]:p-0!;
}
}
> details {
&:not([open]) {
> summary {
&::after {
@apply -rotate-90;
}
}
}
> summary {
&::after {
@apply content-[''] block size-3.5 bg-primary ml-auto transition-transform ease-linear;
@apply mask-[image:var(--chevron-down-icon)] mask-size-[1rem] mask-no-repeat mask-center;
}
}
&::details-content {
@apply px-3.5;
}
}
> [role=group] {
@apply relative flex w-full min-w-0 flex-col p-2;
}
h3 {
@apply text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0;
}
ul {
@apply border-sidebar-border flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5 w-full;
@apply flex w-full min-w-0 flex-col gap-1;
li {
@apply relative;
> a,
> details > summary {
@apply flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&[aria-current=page]]:bg-sidebar-accent [&[aria-current=page]]:font-medium [&[aria-current=page]]:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0;
&:not([data-variant]),
&[data-variant=default] {
@apply hover:bg-sidebar-accent hover:text-sidebar-accent-foreground;
}
&[data-variant=outline] {
@apply bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))];
}
&:not([data-size]),
&[data-size=default] {
@apply h-8 text-sm;
}
&[data-size=sm] {
@apply h-7 text-xs;
}
&[data-size=lg] {
@apply h-12 text-sm group-data-[collapsible=icon]:p-0!;
}
}
> details {
&:not([open]) {
> summary {
&::after {
@apply -rotate-90;
}
}
}
> summary {
&::after {
@apply content-[''] block size-3.5 bg-primary ml-auto transition-transform ease-linear;
@apply mask-[image:var(--chevron-down-icon)] mask-size-[1rem] mask-no-repeat mask-center;
}
}
&::details-content {
@apply px-3.5;
}
}
}
ul {
@apply border-sidebar-border flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5 w-full;
}
}
}
}
+9 -1
View File
@@ -46,7 +46,15 @@
visibleMenuItems = [];
allMenuItems.forEach(item => {
const itemText = (item.dataset.label || item.textContent).trim().toLowerCase();
if (item.hasAttribute('data-force')) {
item.setAttribute('aria-hidden', 'false');
if (menuItems.includes(item)) {
visibleMenuItems.push(item);
}
return;
}
const itemText = (item.dataset.filter || item.textContent).trim().toLowerCase();
const keywords = (item.dataset.keywords || '').toLowerCase();
const matches = itemText.includes(searchTerm) || keywords.includes(searchTerm);
item.setAttribute('aria-hidden', String(!matches));
+12 -3
View File
@@ -48,7 +48,7 @@
const updateValue = (option, triggerEvent = true) => {
if (option) {
selectedLabel.innerHTML = option.dataset.label || option.innerHTML;
selectedLabel.innerHTML = option.innerHTML;
input.value = option.dataset.value;
listbox.querySelector('[role="option"][aria-selected="true"]')?.removeAttribute('aria-selected');
option.setAttribute('aria-selected', 'true');
@@ -112,8 +112,17 @@
visibleOptions = [];
allOptions.forEach(option => {
const optionText = (option.dataset.label || option.textContent).trim().toLowerCase();
const matches = optionText.includes(searchTerm);
if (option.hasAttribute('data-force')) {
option.setAttribute('aria-hidden', 'false');
if (options.includes(option)) {
visibleOptions.push(option);
}
return;
}
const optionText = (option.dataset.filter || option.textContent).trim().toLowerCase();
const keywords = (option.dataset.keywords || '').toLowerCase();
const matches = optionText.includes(searchTerm) || keywords.includes(searchTerm);
option.setAttribute('aria-hidden', String(!matches));
if (matches && options.includes(option)) {
visibleOptions.push(option);