From a1aae77b6eac91071ea873eb5e4586135564d77a Mon Sep 17 00:00:00 2001 From: Bartek Date: Tue, 29 Sep 2026 14:05:57 +0200 Subject: [PATCH] Add Combobox preview page and fix small/large variants Add the combobox demo page with a menu entry, keep the field height stable for icons in small and large sizes, and document native select sizes. --- .changeset/combobox-component.md | 3 +- core/js/src/combobox.ts | 5 +- core/scss/ui/forms/_combobox.scss | 15 +- docs/content/ui/forms/combobox.mdx | 53 ++++ preview/pages/combobox.astro | 493 +++++++++++++++++++++++++++++ shared/data/menu.json | 5 + 6 files changed, 569 insertions(+), 5 deletions(-) create mode 100644 preview/pages/combobox.astro diff --git a/.changeset/combobox-component.md b/.changeset/combobox-component.md index f0f231f38..ad05b9ce6 100644 --- a/.changeset/combobox-component.md +++ b/.changeset/combobox-component.md @@ -1,6 +1,7 @@ --- "@tabler/core": minor "@tabler/docs": minor +"@tabler/preview": minor --- -Added Combobox component: a searchable, multi-select dropdown field with `.combobox-toggle` and `data-bs-toggle="combobox"`. +Added Combobox component for `` the size class is copied to the toggle. The height stays the same with tags and icons in every size. + + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ ### Disabled Add `disabled` to the toggle, or to single items. diff --git a/preview/pages/combobox.astro b/preview/pages/combobox.astro new file mode 100644 index 000000000..78d61b49c --- /dev/null +++ b/preview/pages/combobox.astro @@ -0,0 +1,493 @@ +--- +import { assetRoot } from '@shared/lib/assets' +import { people } from '@shared/lib/people' +import DefaultLayout from '@shared/layouts/DefaultLayout.astro' +import Card from '@ui/Card.astro' +import CardBody from '@ui/CardBody.astro' +import CardTitle from '@ui/CardTitle.astro' +import CardSubtitle from '@ui/CardSubtitle.astro' +import DocsLink from '@ui/DocsLink.astro' + +const countries: [string, string][] = [ + ['us', 'United States'], + ['gb', 'United Kingdom'], + ['de', 'Germany'], + ['fr', 'France'], + ['pl', 'Poland'], + ['es', 'Spain'], + ['it', 'Italy'], + ['nl', 'Netherlands'], + ['se', 'Sweden'], + ['jp', 'Japan'], + ['br', 'Brazil'], + ['ca', 'Canada'], +] + +const payments: [string, string][] = [ + ['visa', 'Visa'], + ['mastercard', 'Mastercard'], + ['americanexpress', 'American Express'], + ['paypal', 'PayPal'], + ['stripe', 'Stripe'], + ['applepay', 'Apple Pay'], +] + +const shortcuts: [string, string, string][] = [ + ['cut', 'Cut', 'ctrl + X'], + ['copy', 'Copy', 'ctrl + C'], + ['paste', 'Paste', 'ctrl + V'], + ['all', 'Select all', 'ctrl + A'], + ['find', 'Find', 'ctrl + F'], + ['save', 'Save', 'ctrl + S'], +] + +const statuses: [string, string, string][] = [ + ['online', 'Online', 'green'], + ['away', 'Away', 'yellow'], + ['busy', 'Busy', 'red'], + ['offline', 'Offline', 'secondary'], +] + +const priorities: [string, string, string, number][] = [ + ['low', 'Low', 'blue', 12], + ['medium', 'Medium', 'yellow', 5], + ['high', 'High', 'red', 2], +] + +const sizes: [string, string][] = [ + ['sm', 'Small'], + ['', 'Default'], + ['lg', 'Large'], +] + +const fruits = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry', 'Fig', 'Grape', 'Kiwi', 'Mango'] + +const team = people.slice(0, 8) +const photo = (person: { photo?: string }) => `${assetRoot}/${person.photo}` +const avatar = (person: { photo?: string }) => `` + +const checkIcon = '' +--- + + + + +
+
+ + + Native select + Add data-bs-toggle="combobox" to a <select>. It stays the real form field. + + + + +
+ +
+ + + Multiple + Add multiple for tags. The ones that do not fit collapse into a +N tag. + + + + +
+ +
+ + + Wrapping tags + Set data-bs-tags-overflow="wrap" to show every tag on extra lines. + + + + +
+ +
+ + + Markup + Write the items yourself with a button, a .dropdown-menu and data-bs-value. + + + + + +
+ +
+ + + Multiple as a list + In markup mode the labels are listed with commas and end with “and N more” when they do not fit. + + + + + +
+ +
+ + + Groups + An <optgroup> becomes a header. Search hides a group with no match. + + + + +
+ +
+ + + Flags + Put a flag in data-custom-properties. It shows in the menu and in the field. + + + + +
+ +
+ + + Payment methods + The same works with the payment icons. + + + + +
+ +
+ + + Avatars + Show the person next to the name. + + + + +
+ +
+ + + Avatars as tags + On a multiple select the avatars go into the tags. + + + + +
+ +
+ + + Avatars with details + Add an email under the name with .dropdown-item-description. + + + + + +
+ +
+ + + Keyboard shortcuts + A <kbd> in the item is shown in the menu and in the field. + + + + + +
+ +
+ + + Status + An empty .badge works as a status dot. + + + + + +
+ +
+ + + Badges + A badge at the end of the item is shown in the field too. + + + + + +
+ +
+ + + Disabled + Add disabled to the field, or to single options. +
+ + +
+
+ + +
+
+
+
+
+ + + Sizes + Use .form-select-sm or .form-select-lg. The class is copied to the field. +
+ { + sizes.map(([size, label]) => ( +
+ + +
+ )) + } +
+
+
+
+ +
+ + + Sizes with tags + The height stays the same with tags in every size. +
+ { + sizes.map(([size, label]) => ( +
+ + +
+ )) + } +
+
+
+
+ +
+ + + Validation + Add .is-valid or .is-invalid. The class is copied to the field. +
+ + +
Looks good.
+
+
+ + +
Please pick a fruit.
+
+
+
+
+
+
diff --git a/shared/data/menu.json b/shared/data/menu.json index f0df71c6d..68da6302f 100644 --- a/shared/data/menu.json +++ b/shared/data/menu.json @@ -282,6 +282,11 @@ "layout": { "url": "form-layout.html", "title": "Form layouts" + }, + "combobox": { + "url": "combobox.html", + "title": "Combobox", + "badge": "New" } } },