Skip to content
Merged
154 changes: 127 additions & 27 deletions apps/demo/src/Views/Ui/components/CountryDisplay/CountryDisplayDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export const CountryDisplayDemo = () => {
const navigate = useNavigate();
const selectedLocale = i18n.language;

const customFlagsPath = (code: string) => {
return `https://flagcdn.com/${code.toLowerCase().trim()}.svg`;
};

const data = [
{
id: 1,
Expand All @@ -37,20 +41,48 @@ export const CountryDisplayDemo = () => {
},
{
id: 4,
prop: "i18n",
type: "Record<string, Record<string, string>>",
default: "{}",
description: t("countryDisplay.propertiesDescription.i18n"),
prop: "flagsPath",
type: "(code: string) => string",
default: "undefined",
description: t("countryDisplay.propertiesDescription.flagsPath"),
},
{
id: 5,
prop: "flagsPosition",
type: '"left" | "right" | "right-edge"',
default: '"left"',
description: t("countryDisplay.propertiesDescription.flagsPosition"),
},
{
id: 6,
prop: "flagsStyle",
type: '"circle" | "rectangular" | "square"',
default: '"rectangular"',
description: t("countryDisplay.propertiesDescription.flagsStyle"),
},
{
id: 7,
prop: "locale",
type: "string",
default: "en",
description: t("countryDisplay.propertiesDescription.locale"),
},
{
id: 6,
id: 8,
prop: "locales",
type: "Record<string, Record<string, string>>",
default: "{}",
description: t("countryDisplay.propertiesDescription.i18n"),
},
{
id: 9,
prop: "renderOption",
type: "(code: string, label: string) => ReactNode",
default: "undefined",
description: t("countryDisplay.propertiesDescription.renderOption"),
},
{
id: 10,
prop: "showFlag",
type: "boolean",
default: "true",
Expand Down Expand Up @@ -84,7 +116,7 @@ export const CountryDisplayDemo = () => {
<Country
code="NP"
locale="np"
i18n={{
locales={{
np: nepaliData,
}}
/>
Expand All @@ -98,17 +130,17 @@ const selectedLocale = "np";

<Country
code="NP"
i18n={locales}
locale={selectedLocale}
locales={locales}
/>'
/>
</Section>

<Section title={t("countryDisplay.locale")}>
<Country
code="EG"
i18n={{ fr: frenchData, en: englishData }}
locale={selectedLocale}
locales={{ fr: frenchData, en: englishData }}
/>
<CodeBlock
exampleCode='import frenchData from "./fr.json";
Expand All @@ -118,9 +150,9 @@ locales = { fr: frenchData, en: englishData }
selectedLocale = i18n.language

<Country
code="EG"
i18n={locales}
locale={selectedLocale}
code="EG"
locale={selectedLocale}
locales={locales}
/>'
/>
</Section>
Expand All @@ -129,8 +161,8 @@ selectedLocale = i18n.language
<Country
code="GB"
fallbackLocale="np"
i18n={{ np: nepaliData, en: englishData }}
locale={selectedLocale}
locales={{ np: nepaliData, en: englishData }}
/>
<CodeBlock
exampleCode='import englishData from "./en.json";
Expand All @@ -146,12 +178,87 @@ fallbackLocale = np;
<Country
code="GB"
fallbackLocale={fallbackLocale}
i18n={locales}
locale={selectedLocale}
locales={locales}
/>'
/>
</Section>

<Section title={t("countryDisplay.showFlag")}>
<Country code="CA" showFlag={false} />
<CodeBlock exampleCode='<Country code="CA" showFlag={false} />' />
</Section>

<Section title={t("countryDisplay.flagsStyle")}>
<h3>{t("countryDisplay.styles.rectangular")}</h3>
<Country code="US" flagsStyle="rectangular" />
<CodeBlock exampleCode='<Country code="US" />' />

<h3>{t("countryDisplay.styles.square")}</h3>
<Country code="US" flagsStyle="square" />
<CodeBlock exampleCode='<Country code="US" flagsStyle="square" />' />

<h3>{t("countryDisplay.styles.circle")}</h3>
<Country code="US" flagsStyle="circle" />
<CodeBlock exampleCode='<Country code="US" flagsStyle="circle" />' />
</Section>

<Section title={t("countryDisplay.flagsPosition")}>
<h3>{t("countryDisplay.positions.left")}</h3>
<Country code="BR" flagsPosition="left" />
<CodeBlock exampleCode='<Country code="BR" />' />

<h3>{t("countryDisplay.positions.right")}</h3>
<Country code="BR" flagsPosition="right" />
<CodeBlock exampleCode='<Country code="BR" flagsPosition="right" />' />

<h3>{t("countryDisplay.positions.rightEdge")}</h3>
<Country code="BR" flagsPosition="right-edge" />
<CodeBlock exampleCode='<Country code="BR" flagsPosition="right-edge" />' />
</Section>

<Section title={t("countryDisplay.customFlagsPath", "Custom Flag Path")}>
<Country code="CA" flagsPath={customFlagsPath} />
<CodeBlock
exampleCode='const flagsPath = (code: string) => {
return `https://flagcdn.com/${code.toLowerCase().trim()}.svg`;
};

<Country
code="CA"
flagsPath={customFlagsPath}
/>'
/>
</Section>

<Section title={t("countryDisplay.renderOption")}>
<Country
code="JP"
renderOption={(code, label) => (
<div className="custom-style">
<span
className={`flag-icon flag-icon-${code.toLowerCase()} flag-icon-rounded`}
/>
<span className="font-bold text-sm">{label}</span>
</div>
)}
/>

<CodeBlock
exampleCode={`@import "./country.css";

<Country
code="JP"
renderOption={(code, label) => (
<div className="custom-style">
<span className={\`flag-icon flag-icon-\${code.toLowerCase()} flag-icon-rounded\`}></span>
<span>{label}</span>
</div>
)}
/>`}
/>
</Section>

<Section title={t("countryDisplay.notFound")}>
<div className="country-wrapper">
<span>Country</span>
Expand All @@ -160,11 +267,6 @@ fallbackLocale = np;
<CodeBlock exampleCode='<Country code="WW" />' />
</Section>

<Section title={t("countryDisplay.showFlag")}>
<Country code="CA" showFlag={false} />
<CodeBlock exampleCode='<Country code="CA" showFlag={false} />' />
</Section>

<Section
title={t("headers.propertiesValue", {
value: "Country",
Expand Down Expand Up @@ -196,22 +298,20 @@ fallbackLocale = np;
</Section>
<Section title={t("countryDisplay.typeDefinitions")}>
<CodeBlock
exampleCode={`type I18nData = Record<string, Record<string, string>>;
exampleCode={`type Locales = Record<string, Record<string, string>>;

interface CountryDisplayProperties {
code: string;
className?: string;
fallbackLocale?: string;
i18n?: I18nData;
fallbackLocale?: string;
flagsPath?: (code: string) => string;
flagsPosition?: "left" | "right" | "right-edge";
flagsStyle?: "circle" | "rectangular" | "square";
locale?: string;
locales?: I18nData;
showFlag?: boolean;
renderOption?: (code: string, label: string) => React.ReactNode;
}

Example I18n:
{
en:{ "US": "USA" },
fr: { "US": "États-Unis" }
}
`}
/>
</Section>
Expand Down
3 changes: 2 additions & 1 deletion apps/demo/src/Views/Ui/components/CountryDisplay/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"ES": "Spain",
"IT": "Italy",
"JP": "Japan",
"CN": "China"
"CN": "China",
"EG": "Egypt"
}
12 changes: 12 additions & 0 deletions apps/demo/src/assets/css/country.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,15 @@
flex-direction: column;
gap: 0.25rem;
}

.custom-style {
display: inline-flex;
align-items: center;
gap: 8px;
background: #eef2ff;
padding: 4px 12px;
border-radius: 20px;
border: 1px solid #c7d2fe;
color: #3730a3;
width: 8rem;
}
20 changes: 19 additions & 1 deletion apps/demo/src/locales/en/ui.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,38 @@
},
"countryDisplay": {
"basic": "Basic",
"customFlagsPath": "Custom flag path",
"customLocale": "New locale support",
"fallback": "Fallback locale",
"flagsPosition": "Flag position",
"flagsStyle": "Flag style",
"label": "Label",
"locale": "Locales support",
"notFound": "Missing country code",
"positions": {
"left": "Left (default)",
"right": "Right",
"rightEdge": "Right edge"
},
"propertiesDescription": {
"code": "The ISO country code to display (e.g., 'US', 'gb').",
"className": "CSS class to append to the wrapper span.",
"fallbackLocale": "Locale to use if the specific translation is missing.",
"flagsPath": "Custom function to resolve image paths for flags.",
"flagsPosition": "Position of the flag relative to text ('left', 'right', 'right-edge').",
"flagsStyle": "Shape style of the flag ('circle', 'rectangular', 'square').",
"i18n": "External translation dictionary for additional languages.",
"locale": "The target locale for translation (e.g., 'en', 'fr').",
"renderOption": "Function to customize rendering: (code, label, flagElement) => ReactNode.",
"showFlag": "If false, the flag will not be displayed."
},
"renderOption": "Custom render option",
"showFlag": "Flag visibility",
"styles": {
"circle": "Circle",
"rectangular": "Rectangular (default)",
"square": "Square"
},
"title": "Country",
"typeDefinitions": "Types"
},
Expand Down Expand Up @@ -147,7 +165,7 @@
"single": "Select a country..."
},
"propertiesDescription": {
"autoSortOptions":"By default, options are sorted alphabetically. If false, countries are sorted by priority in the order groups → favorites → include → fallback-locale translations, preserving the defined order.",
"autoSortOptions": "By default, options are sorted alphabetically. If false, countries are sorted by priority in the order groups → favorites → include → fallback-locale translations, preserving the defined order.",
"data": "Custom country data to overwrite existing entries or add new ones.",
"exclude": "An array of country codes to remove from the list.",
"fallbackLocale": "Locale used when active locale translation is missing.",
Expand Down
18 changes: 18 additions & 0 deletions apps/demo/src/locales/fr/ui.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,38 @@
},
"countryDisplay": {
"basic": "Basic (fr)",
"customFlagsPath": "Custom flag path (fr)",
"customLocale": "New locale support (fr)",
"fallback": "Fallback locale (fr)",
"flagsPosition": "Flag position (fr)",
"flagsStyle": "Flag style (fr)",
"label": "Label (fr)",
"locale": "Locales support (fr)",
"notFound": "Missing country code (fr)",
"positions": {
"left": "Left (default) (fr)",
"right": "Right (fr)",
"rightEdge": "Right edge (fr)"
},
"propertiesDescription": {
"code": "The ISO country code to display (e.g., 'US', 'gb'). (fr)",
"className": "CSS class to append to the wrapper span. (fr)",
"fallbackLocale": "Locale to use if the specific translation is missing. (fr)",
"flagsPath": "Custom function to resolve image paths for flags. (fr)",
"flagsPosition": "Position of the flag relative to text ('left', 'right', 'right-edge'). (fr)",
"flagsStyle": "Shape style of the flag ('circle', 'rectangular', 'square'). (fr)",
"i18n": "External translation dictionary for additional languages. (fr)",
"locale": "The target locale for translation (e.g., 'en', 'fr'). (fr)",
"renderOption": "Function to customize rendering: (code, label, flagElement) => ReactNode. (fr)",
"showFlag": "If false, the flag will not be displayed. (fr)"
},
"renderOption": "Custom render option (fr)",
"showFlag": "Flag visibility (fr)",
"styles": {
"circle": "Circle (fr)",
"rectangular": "Rectangular (default) (fr)",
"square": "Square (fr)"
},
"title": "Country (fr)",
"typeDefinitions": "Types (fr)"
},
Expand Down
Loading