-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create country field with dropdown edit mode (#1864)
* introduce country dropdown * remove loading message * fix default selection of model * add some instances * fix lint * add atom format to country field
- Loading branch information
1 parent
2c96b3b
commit 5c2c6ec
Showing
4 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
packages/experiments-realm/CardWithCountryField/6f3855c6-26dd-48e1-b332-73444a1172d1.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"data": { | ||
"type": "card", | ||
"attributes": { | ||
"country": { | ||
"name": null, | ||
"code": null | ||
}, | ||
"title": null, | ||
"description": null, | ||
"thumbnailURL": null | ||
}, | ||
"meta": { | ||
"adoptsFrom": { | ||
"module": "../country", | ||
"name": "CardWithCountryField" | ||
} | ||
} | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
packages/experiments-realm/CardWithCountryField/86fee625-f9f0-460a-99aa-917d25657ec1.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"data": { | ||
"type": "card", | ||
"attributes": { | ||
"country": { | ||
"name": "Cambodia", | ||
"code": "KH" | ||
}, | ||
"title": null, | ||
"description": null, | ||
"thumbnailURL": null | ||
}, | ||
"meta": { | ||
"adoptsFrom": { | ||
"module": "../country", | ||
"name": "CardWithCountryField" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,9 +3,17 @@ import { | |
field, | ||
Component, | ||
CardDef, | ||
FieldDef, | ||
} from 'https://cardstack.com/base/card-api'; | ||
import StringField from 'https://cardstack.com/base/string'; | ||
import World from '@cardstack/boxel-icons/world'; | ||
import { BoxelSelect } from '@cardstack/boxel-ui/components'; | ||
import { tracked } from '@glimmer/tracking'; | ||
import { action } from '@ember/object'; | ||
import { restartableTask } from 'ember-concurrency'; | ||
import type Owner from '@ember/owner'; | ||
// @ts-ignore | ||
import countryDataFind from 'https://esm.run/[email protected]'; | ||
|
||
export class Country extends CardDef { | ||
static displayName = 'Country'; | ||
|
@@ -23,3 +31,99 @@ export class Country extends CardDef { | |
</template> | ||
}; | ||
} | ||
|
||
function getCountryFlagEmoji(countryCode: string) { | ||
const codePoints = countryCode | ||
.toUpperCase() | ||
.split('') | ||
.map((char) => 127397 + char.charCodeAt(0)); | ||
return String.fromCodePoint(...codePoints); | ||
} | ||
|
||
interface CountryData { | ||
code: string; | ||
name: string; | ||
emoji?: string; | ||
} | ||
|
||
class CountryFieldEdit extends Component<typeof CountryField> { | ||
@tracked country: CountryData | undefined = | ||
this.args.model.name && this.args.model.code | ||
? { | ||
name: this.args.model.name, | ||
code: this.args.model.code, | ||
} | ||
: undefined; | ||
@tracked countries: CountryData[] = []; | ||
|
||
constructor(owner: Owner, args: any) { | ||
super(owner, args); | ||
this.loadCountries.perform(); | ||
} | ||
|
||
private loadCountries = restartableTask(async () => { | ||
this.countries = countryDataFind.Array().map((country: any) => { | ||
return { | ||
code: country.ISO2_CODE, | ||
name: country.LIST_OF_NAME.ENG[0], | ||
emoji: getCountryFlagEmoji(country.ISO2_CODE), | ||
} as CountryData; | ||
}); | ||
}); | ||
|
||
@action onSelectCountry(country: CountryData) { | ||
this.country = country; | ||
this.args.model.name = country.name; | ||
this.args.model.code = country.code; | ||
} | ||
|
||
@action countryEmoji(countryCode: string) { | ||
return this.countries?.find((country) => country.code === countryCode) | ||
?.emoji; | ||
} | ||
|
||
<template> | ||
{{#if this.loadCountries.isRunning}} | ||
Loading countries... | ||
{{else}} | ||
<BoxelSelect | ||
@placeholder={{'Choose a country'}} | ||
@options={{this.countries}} | ||
@selected={{this.country}} | ||
@onChange={{this.onSelectCountry}} | ||
as |country| | ||
> | ||
{{#let (this.countryEmoji country.code) as |emoji|}} | ||
{{emoji}} | ||
{{/let}} | ||
{{country.name}} | ||
</BoxelSelect> | ||
{{/if}} | ||
</template> | ||
} | ||
|
||
export class CountryField extends FieldDef { | ||
static displayName = 'Country'; | ||
@field name = contains(StringField); | ||
@field code = contains(StringField); | ||
static edit = CountryFieldEdit; | ||
|
||
static atom = class Atom extends Component<typeof this> { | ||
<template> | ||
{{#if @model.name}} | ||
{{@model.name}} | ||
{{/if}} | ||
</template> | ||
}; | ||
} | ||
|
||
export class CardWithCountryField extends CardDef { | ||
static displayName = 'Card With Country Field'; | ||
@field country = contains(CountryField); | ||
|
||
static isolated = class Isolated extends Component<typeof this> { | ||
<template> | ||
<@fields.country @format='atom' /> | ||
</template> | ||
}; | ||
} |