Skip to content

Commit

Permalink
Feat/combobox (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
nank1ro authored May 23, 2024
1 parent 798ad52 commit 9b2a330
Show file tree
Hide file tree
Showing 9 changed files with 312 additions and 62 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.5.0

- Add the `ShadSelect.withSearch` constructor to easily add a search input to the select component.

## 0.4.7

- Add `maintainState` to `ShadAccordion` to keep the child in the tree even if the item is closed, defaults to `false`.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ See the [documentation](https://mariuti.com/shadcn-ui/) to interact with the com
- [ ] Carousel
- [x] [Checkbox](https://mariuti.com/shadcn-ui/components/checkbox/)
- [ ] Collapsible
- [ ] Combobox
- [x] [Combobox](https://mariuti.com/shadcn-ui/components/select/#with-search)
- [ ] Command
- [ ] Context Menu
- [ ] Data Table
Expand Down
3 changes: 3 additions & 0 deletions example/devtools_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:
156 changes: 106 additions & 50 deletions example/lib/pages/select.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,62 @@ import 'package:example/common/properties/bool_property.dart';
import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';

const fruits = {
'apple': 'Apple',
'banana': 'Banana',
'blueberry': 'Blueberry',
'grapes': 'Grapes',
'pineapple': 'Pineapple',
};

const timezones = {
'North America': {
'est': 'Eastern Standard Time (EST)',
'cst': 'Central Standard Time (CST)',
'mst': 'Mountain Standard Time (MST)',
'pst': 'Pacific Standard Time (PST)',
'akst': 'Alaska Standard Time (AKST)',
'hst': 'Hawaii Standard Time (HST)',
},
'Europe & Africa': {
'gmt': 'Greenwich Mean Time (GMT)',
'cet': 'Central European Time (CET)',
'eet': 'Eastern European Time (EET)',
'west': 'Western European Summer Time (WEST)',
'cat': 'Central Africa Time (CAT)',
'eat': 'Eastern Africa Time (EAT)',
},
'Asia': {
'msk': 'Moscow Time (MSK)',
'ist': 'India Standard Time (IST)',
'cst_china': 'China Standard Time (CST)',
'jst': 'Japan Standard Time (JST)',
'kst': 'Korea Standard Time (KST)',
'ist_indonasia': 'Indonesia Standard Time (IST)',
},
'Australia & Pacific': {
'awst': 'Australian Western Standard Time (AWST)',
'acst': 'Australian Central Standard Time (ACST)',
'aest': 'Australian Eastern Standard Time (AEST)',
'nzst': 'New Zealand Standard Time (NZST)',
'fjt': 'Fiji Time (FJT)',
},
'South America': {
'art': 'Argentina Time (ART)',
'bot': 'Bolivia Time (BOT)',
'brt': 'Brasilia Time (BRT)',
'clt': 'Chile Standard Time (CLT)',
},
};

const frameworks = {
'nextjs': 'Next.js',
'svelte': 'SvelteKit',
'nuxtjs': 'Nuxt.js',
'remix': 'Remix',
'astro': 'Astro',
};

class SelectPage extends StatefulWidget {
const SelectPage({super.key});

Expand All @@ -15,55 +71,14 @@ class SelectPage extends StatefulWidget {

class _SelectPageState extends State<SelectPage> {
bool enabled = true;
final focusNodes = [FocusNode(), FocusNode()];
final focusNodes = [FocusNode(), FocusNode(), FocusNode()];
var searchValue = '';

final fruits = {
'apple': 'Apple',
'banana': 'Banana',
'blueberry': 'Blueberry',
'grapes': 'Grapes',
'pineapple': 'Pineapple',
};

final timezones = {
'North America': {
'est': 'Eastern Standard Time (EST)',
'cst': 'Central Standard Time (CST)',
'mst': 'Mountain Standard Time (MST)',
'pst': 'Pacific Standard Time (PST)',
'akst': 'Alaska Standard Time (AKST)',
'hst': 'Hawaii Standard Time (HST)',
},
'Europe & Africa': {
'gmt': 'Greenwich Mean Time (GMT)',
'cet': 'Central European Time (CET)',
'eet': 'Eastern European Time (EET)',
'west': 'Western European Summer Time (WEST)',
'cat': 'Central Africa Time (CAT)',
'eat': 'Eastern Africa Time (EAT)',
},
'Asia': {
'msk': 'Moscow Time (MSK)',
'ist': 'India Standard Time (IST)',
'cst_china': 'China Standard Time (CST)',
'jst': 'Japan Standard Time (JST)',
'kst': 'Korea Standard Time (KST)',
'ist_indonasia': 'Indonesia Standard Time (IST)',
},
'Australia & Pacific': {
'awst': 'Australian Western Standard Time (AWST)',
'acst': 'Australian Central Standard Time (ACST)',
'aest': 'Australian Eastern Standard Time (AEST)',
'nzst': 'New Zealand Standard Time (NZST)',
'fjt': 'Fiji Time (FJT)',
},
'South America': {
'art': 'Argentina Time (ART)',
'bot': 'Bolivia Time (BOT)',
'brt': 'Brasilia Time (BRT)',
'clt': 'Chile Standard Time (CLT)',
},
};
Map<String, String> get filteredFrameworks => {
for (final framework in frameworks.entries)
if (framework.value.toLowerCase().contains(searchValue.toLowerCase()))
framework.key: framework.value
};

@override
void dispose() {
Expand Down Expand Up @@ -100,6 +115,14 @@ class _SelectPageState extends State<SelectPage> {
value ? focusNodes[1].requestFocus() : focusNodes[1].unfocus(),
),
),
MyBoolProperty(
label: 'Framework Focused',
value: focusNodes[2].hasFocus,
onChanged: (value) => setState(
() =>
value ? focusNodes[2].requestFocus() : focusNodes[2].unfocus(),
),
),
],
children: [
ShadSelect<String>(
Expand Down Expand Up @@ -147,8 +170,12 @@ class _SelectPageState extends State<SelectPage> {
textAlign: TextAlign.start,
),
),
...zone.value.entries
.map((e) => ShadOption(value: e.key, child: Text(e.value)))
...zone.value.entries.map(
(e) => ShadOption(
value: e.key,
child: Text(e.value),
),
)
],
),
),
Expand All @@ -159,6 +186,35 @@ class _SelectPageState extends State<SelectPage> {
return Text(timezone!);
},
),
ShadSelect<String>.withSearch(
enabled: enabled,
focusNode: focusNodes[2],
minWidth: 180,
placeholder: const Text('Select framework...'),
onSearchChanged: (value) => setState(() => searchValue = value),
searchPlaceholder: const Text('Search framework'),
options: [
if (filteredFrameworks.isEmpty)
const Padding(
padding: EdgeInsets.symmetric(vertical: 24),
child: Text('No framework found'),
),
...frameworks.entries.map(
(framework) {
// this offstage is used to avoid the focus loss when the search results appear again
// because it keeps the widget in the tree.
return Offstage(
offstage: !filteredFrameworks.containsKey(framework.key),
child: ShadOption(
value: framework.key,
child: Text(framework.value),
),
);
},
)
],
selectedOptionBuilder: (context, value) => Text(frameworks[value]!),
),
],
);
}
Expand Down
Loading

0 comments on commit 9b2a330

Please sign in to comment.