@code-plate/iran-cities 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/LICENSE +21 -0
  3. package/MIGRATION.fa.md +277 -0
  4. package/MIGRATION.md +272 -0
  5. package/NOTICE.md +17 -0
  6. package/README.fa.md +528 -201
  7. package/README.md +524 -201
  8. package/dist/boundaries.cjs +9218 -0
  9. package/dist/boundaries.cjs.map +1 -0
  10. package/dist/boundaries.d.cts +30 -0
  11. package/dist/boundaries.d.mts +30 -0
  12. package/dist/boundaries.mjs +9215 -0
  13. package/dist/boundaries.mjs.map +1 -0
  14. package/dist/changes-B-wz9-Gy.cjs +841 -0
  15. package/dist/changes-B-wz9-Gy.cjs.map +1 -0
  16. package/dist/changes-CMVZbfZO.d.mts +8 -0
  17. package/dist/changes-DLZkHBwZ.mjs +800 -0
  18. package/dist/changes-DLZkHBwZ.mjs.map +1 -0
  19. package/dist/changes-DnnwRAKl.d.cts +8 -0
  20. package/dist/components-B7060em0.mjs +240 -0
  21. package/dist/components-B7060em0.mjs.map +1 -0
  22. package/dist/components-BuMUB7XT.d.cts +47 -0
  23. package/dist/components-DZz72pd1.d.mts +47 -0
  24. package/dist/components-grWmOsaV.cjs +247 -0
  25. package/dist/components-grWmOsaV.cjs.map +1 -0
  26. package/dist/components.css +251 -0
  27. package/dist/data/cities.csv +1253 -0
  28. package/dist/data/cities.json +23305 -0
  29. package/dist/data/iran-cities.sql +1487 -0
  30. package/dist/data/iran-provinces.geojson +1 -0
  31. package/dist/data/provinces.csv +32 -0
  32. package/dist/data/provinces.json +460 -0
  33. package/dist/hooks-C6kjWLIE.mjs +134 -0
  34. package/dist/hooks-C6kjWLIE.mjs.map +1 -0
  35. package/dist/hooks-K7pTMF2R.cjs +139 -0
  36. package/dist/hooks-K7pTMF2R.cjs.map +1 -0
  37. package/dist/index.cjs +30 -9307
  38. package/dist/index.d.cts +25 -0
  39. package/dist/index.d.mts +25 -25
  40. package/dist/index.mjs +3 -9264
  41. package/dist/lite-CtNPRhU-.mjs +1926 -0
  42. package/dist/lite-CtNPRhU-.mjs.map +1 -0
  43. package/dist/lite-CutarzAc.cjs +2051 -0
  44. package/dist/lite-CutarzAc.cjs.map +1 -0
  45. package/dist/lite-react-1HVWJOWt.cjs +55 -0
  46. package/dist/lite-react-1HVWJOWt.cjs.map +1 -0
  47. package/dist/lite-react-Ds-DNmEi.mjs +20 -0
  48. package/dist/lite-react-Ds-DNmEi.mjs.map +1 -0
  49. package/dist/lite-react-components.cjs +12 -0
  50. package/dist/lite-react-components.cjs.map +1 -0
  51. package/dist/lite-react-components.d.cts +5 -0
  52. package/dist/lite-react-components.d.mts +5 -0
  53. package/dist/lite-react-components.mjs +11 -0
  54. package/dist/lite-react-components.mjs.map +1 -0
  55. package/dist/lite-react.cjs +8 -0
  56. package/dist/lite-react.d.cts +7 -0
  57. package/dist/lite-react.d.mts +7 -0
  58. package/dist/lite-react.mjs +2 -0
  59. package/dist/lite.cjs +28 -0
  60. package/dist/lite.d.cts +23 -0
  61. package/dist/lite.d.mts +23 -0
  62. package/dist/lite.mjs +3 -0
  63. package/dist/react-BKmJ476x.mjs +20 -0
  64. package/dist/react-BKmJ476x.mjs.map +1 -0
  65. package/dist/react-BZV3TkXB.cjs +55 -0
  66. package/dist/react-BZV3TkXB.cjs.map +1 -0
  67. package/dist/react-components.cjs +12 -0
  68. package/dist/react-components.cjs.map +1 -0
  69. package/dist/react-components.d.cts +5 -0
  70. package/dist/react-components.d.mts +5 -0
  71. package/dist/react-components.mjs +11 -0
  72. package/dist/react-components.mjs.map +1 -0
  73. package/dist/react.cjs +8 -9310
  74. package/dist/react.d.cts +7 -0
  75. package/dist/react.d.mts +7 -30
  76. package/dist/react.mjs +2 -9281
  77. package/dist/rolldown-runtime-78lK1XfQ.cjs +42 -0
  78. package/dist/rolldown-runtime-D3KUYPsf.mjs +12 -0
  79. package/dist/src-DRaUVbc4.mjs +4302 -0
  80. package/dist/src-DRaUVbc4.mjs.map +1 -0
  81. package/dist/src-mqZTwJfQ.cjs +4439 -0
  82. package/dist/src-mqZTwJfQ.cjs.map +1 -0
  83. package/dist/types/boundaries.d.ts +30 -0
  84. package/dist/types/changes.d.ts +4 -0
  85. package/dist/types/components.d.ts +47 -0
  86. package/dist/types/core.d.ts +25 -0
  87. package/dist/types/geo.d.ts +2 -0
  88. package/dist/types/hooks.d.ts +2 -0
  89. package/dist/types/index.d.ts +28 -0
  90. package/dist/types/keyboard.d.ts +3 -0
  91. package/dist/types/lite-react-components.d.ts +5 -0
  92. package/dist/types/lite-react.d.ts +7 -0
  93. package/dist/types/lite.d.ts +26 -0
  94. package/dist/types/normalize.d.ts +1 -0
  95. package/dist/types/packed.d.ts +16 -0
  96. package/dist/types/react-components.d.ts +5 -0
  97. package/dist/types/react.d.ts +7 -0
  98. package/dist/types/types.d.ts +149 -0
  99. package/dist/types/valibot.d.ts +23 -0
  100. package/dist/types/validation-shared.d.ts +11 -0
  101. package/dist/types/zod.d.ts +23 -0
  102. package/dist/types-Ds_b0yHP.d.cts +150 -0
  103. package/dist/types-Ds_b0yHP.d.mts +150 -0
  104. package/dist/valibot.cjs +47 -0
  105. package/dist/valibot.cjs.map +1 -0
  106. package/dist/valibot.d.cts +21 -0
  107. package/dist/valibot.d.mts +21 -0
  108. package/dist/valibot.mjs +38 -0
  109. package/dist/valibot.mjs.map +1 -0
  110. package/dist/validation-shared-BFilTuY1.cjs +58 -0
  111. package/dist/validation-shared-BFilTuY1.cjs.map +1 -0
  112. package/dist/validation-shared-C7l2cv4e.d.cts +8 -0
  113. package/dist/validation-shared-CJjGRx8p.d.mts +7 -0
  114. package/dist/validation-shared-mh_saZne.mjs +29 -0
  115. package/dist/validation-shared-mh_saZne.mjs.map +1 -0
  116. package/dist/zod.cjs +49 -0
  117. package/dist/zod.cjs.map +1 -0
  118. package/dist/zod.d.cts +21 -0
  119. package/dist/zod.d.mts +21 -0
  120. package/dist/zod.mjs +42 -0
  121. package/dist/zod.mjs.map +1 -0
  122. package/package.json +167 -22
  123. package/dist/index.cjs.map +0 -1
  124. package/dist/index.d.ts +0 -25
  125. package/dist/index.mjs.map +0 -1
  126. package/dist/react.cjs.map +0 -1
  127. package/dist/react.d.ts +0 -30
  128. package/dist/react.mjs.map +0 -1
  129. package/dist/types-DwK3g-Z0.d.mts +0 -53
  130. package/dist/types-DwK3g-Z0.d.ts +0 -53
@@ -0,0 +1,247 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-78lK1XfQ.cjs");
2
+ let react = require("react");
3
+ react = require_rolldown_runtime.__toESM(react);
4
+ // src/components.tsx
5
+ let idCounter = 0;
6
+ function useStableId(explicit) {
7
+ const reactUseId = react.useId;
8
+ const generated = reactUseId ? reactUseId() : void 0;
9
+ const [fallback] = react.useState(() => `ic-${++idCounter}`);
10
+ return explicit !== null && explicit !== void 0 ? explicit : generated ? `ic-${generated.replace(/:/g, "")}` : fallback;
11
+ }
12
+ function classNames(...names) {
13
+ return names.filter(Boolean).join(" ");
14
+ }
15
+ function createComponents(api, hooks) {
16
+ function displayName(city, locale) {
17
+ return locale === "en" ? city.nameEn : city.fa;
18
+ }
19
+ function CityCombobox(props) {
20
+ const { value, defaultValue = null, onChange, province, label, placeholder, noResultsText = "شهری پیدا نشد", limit = 8, fuzzy = true, showProvince, locale = "fa", name, id, required, disabled, invalid, dir = "rtl", className, inputProps } = props;
21
+ const baseId = useStableId(id);
22
+ const inputId = `${baseId}-input`;
23
+ const listId = `${baseId}-list`;
24
+ const labelId = `${baseId}-label`;
25
+ const controlled = value !== void 0;
26
+ const [innerId, setInnerId] = react.useState(defaultValue);
27
+ const selectedId = controlled ? value !== null && value !== void 0 ? value : null : innerId;
28
+ const selected = selectedId === null ? void 0 : api.getCityById(selectedId);
29
+ const scope = province === void 0 || province === null || province === "" ? void 0 : api.getProvince(province);
30
+ const scopeId = scope === null || scope === void 0 ? void 0 : scope.id;
31
+ const [text, setText] = react.useState(() => selected ? displayName(selected, locale) : "");
32
+ const [open, setOpen] = react.useState(false);
33
+ const [active, setActive] = react.useState(-1);
34
+ const listRef = react.useRef(null);
35
+ react.useEffect(() => {
36
+ setText(selected ? displayName(selected, locale) : "");
37
+ }, [selected, locale]);
38
+ const results = react.useMemo(() => {
39
+ const found = api.searchCities(text, {
40
+ fuzzy,
41
+ emptyQuery: scopeId === void 0 ? "none" : "all",
42
+ limit: scopeId === void 0 ? limit : void 0
43
+ });
44
+ return (scopeId === void 0 ? found : found.filter((c) => c.provinceId === scopeId)).slice(0, limit);
45
+ }, [
46
+ text,
47
+ fuzzy,
48
+ limit,
49
+ scopeId
50
+ ]);
51
+ const withProvince = showProvince !== null && showProvince !== void 0 ? showProvince : scopeId === void 0;
52
+ function select(city) {
53
+ if (!controlled) setInnerId(city ? city.id : null);
54
+ setText(city ? displayName(city, locale) : "");
55
+ setOpen(false);
56
+ setActive(-1);
57
+ onChange === null || onChange === void 0 || onChange(city);
58
+ }
59
+ function restore() {
60
+ setText(selected ? displayName(selected, locale) : "");
61
+ setOpen(false);
62
+ setActive(-1);
63
+ }
64
+ react.useEffect(() => {
65
+ if (active < 0 || !listRef.current) return;
66
+ const option = listRef.current.children[active];
67
+ if (option && typeof option.scrollIntoView === "function") option.scrollIntoView({ block: "nearest" });
68
+ }, [active]);
69
+ function onKeyDown(event) {
70
+ var _inputProps$onKeyDown;
71
+ inputProps === null || inputProps === void 0 || (_inputProps$onKeyDown = inputProps.onKeyDown) === null || _inputProps$onKeyDown === void 0 || _inputProps$onKeyDown.call(inputProps, event);
72
+ if (event.defaultPrevented) return;
73
+ switch (event.key) {
74
+ case "ArrowDown":
75
+ event.preventDefault();
76
+ if (!open) setOpen(true);
77
+ setActive((i) => results.length === 0 ? -1 : (i + 1) % results.length);
78
+ break;
79
+ case "ArrowUp":
80
+ event.preventDefault();
81
+ if (!open) setOpen(true);
82
+ setActive((i) => results.length === 0 ? -1 : i <= 0 ? results.length - 1 : i - 1);
83
+ break;
84
+ case "Home":
85
+ if (open && results.length > 0) {
86
+ event.preventDefault();
87
+ setActive(0);
88
+ }
89
+ break;
90
+ case "End":
91
+ if (open && results.length > 0) {
92
+ event.preventDefault();
93
+ setActive(results.length - 1);
94
+ }
95
+ break;
96
+ case "Enter":
97
+ if (open && active >= 0 && results[active]) {
98
+ event.preventDefault();
99
+ select(results[active]);
100
+ }
101
+ break;
102
+ case "Escape":
103
+ if (open) {
104
+ event.preventDefault();
105
+ restore();
106
+ } else if (text) {
107
+ event.preventDefault();
108
+ select(null);
109
+ }
110
+ break;
111
+ case "Tab": if (open) restore();
112
+ }
113
+ }
114
+ const expanded = open && !disabled;
115
+ const activeId = expanded && active >= 0 ? `${baseId}-option-${active}` : void 0;
116
+ return /* @__PURE__ */ react.createElement("div", {
117
+ className: classNames("ic-field", "ic-combobox", className),
118
+ dir,
119
+ "data-open": expanded ? "" : void 0,
120
+ "data-invalid": invalid ? "" : void 0,
121
+ "data-disabled": disabled ? "" : void 0
122
+ }, label !== void 0 ? /* @__PURE__ */ react.createElement("label", {
123
+ className: "ic-label",
124
+ id: labelId,
125
+ htmlFor: inputId
126
+ }, label) : null, /* @__PURE__ */ react.createElement("div", { className: "ic-control" }, /* @__PURE__ */ react.createElement("input", {
127
+ ...inputProps,
128
+ id: inputId,
129
+ className: classNames("ic-input", inputProps === null || inputProps === void 0 ? void 0 : inputProps.className),
130
+ type: "text",
131
+ role: "combobox",
132
+ autoComplete: "off",
133
+ spellCheck: false,
134
+ "aria-autocomplete": "list",
135
+ "aria-expanded": expanded,
136
+ "aria-controls": listId,
137
+ "aria-activedescendant": activeId,
138
+ "aria-invalid": invalid || void 0,
139
+ "aria-required": required || void 0,
140
+ placeholder,
141
+ disabled,
142
+ value: text,
143
+ onChange: (event) => {
144
+ setText(event.target.value);
145
+ setOpen(true);
146
+ setActive(-1);
147
+ },
148
+ onFocus: (event) => {
149
+ var _inputProps$onFocus;
150
+ inputProps === null || inputProps === void 0 || (_inputProps$onFocus = inputProps.onFocus) === null || _inputProps$onFocus === void 0 || _inputProps$onFocus.call(inputProps, event);
151
+ if (scopeId !== void 0 || text) setOpen(true);
152
+ },
153
+ onBlur: (event) => {
154
+ var _inputProps$onBlur;
155
+ inputProps === null || inputProps === void 0 || (_inputProps$onBlur = inputProps.onBlur) === null || _inputProps$onBlur === void 0 || _inputProps$onBlur.call(inputProps, event);
156
+ restore();
157
+ },
158
+ onKeyDown
159
+ }), name ? /* @__PURE__ */ react.createElement("input", {
160
+ type: "hidden",
161
+ name,
162
+ value: selected ? String(selected.id) : ""
163
+ }) : null), /* @__PURE__ */ react.createElement("ul", {
164
+ ref: listRef,
165
+ id: listId,
166
+ className: "ic-listbox",
167
+ role: "listbox",
168
+ "aria-labelledby": label !== void 0 ? labelId : void 0,
169
+ hidden: !expanded
170
+ }, expanded && results.length === 0 ? /* @__PURE__ */ react.createElement("li", {
171
+ className: "ic-empty",
172
+ role: "presentation"
173
+ }, noResultsText) : null, expanded ? results.map((city, index) => /* @__PURE__ */ react.createElement("li", {
174
+ key: city.id,
175
+ id: `${baseId}-option-${index}`,
176
+ className: "ic-option",
177
+ role: "option",
178
+ "aria-selected": (selected === null || selected === void 0 ? void 0 : selected.id) === city.id,
179
+ "data-active": index === active ? "" : void 0,
180
+ onMouseDown: (event) => event.preventDefault(),
181
+ onMouseMove: () => setActive(index),
182
+ onClick: () => select(city)
183
+ }, /* @__PURE__ */ react.createElement("span", { className: "ic-option-name" }, displayName(city, locale)), withProvince ? /* @__PURE__ */ react.createElement("span", { className: "ic-option-meta" }, locale === "en" ? city.provinceNameEn : city.provinceFa) : null)) : null));
184
+ }
185
+ function ProvinceCitySelect(props) {
186
+ const { value, defaultValue, onChange, provinceLabel = "استان", cityLabel = "شهر", provincePlaceholder = "انتخاب استان", cityPlaceholder = "انتخاب شهر", provinceName, cityName, locale = "fa", id, required, disabled, invalid, layout = "row", dir = "rtl", className } = props;
187
+ const baseId = useStableId(id);
188
+ const state = hooks.useProvinceCitySelect({
189
+ value,
190
+ onChange,
191
+ initialProvince: defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.provinceId,
192
+ initialCity: defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.cityId
193
+ });
194
+ const provinceList = state.provinces;
195
+ const sortedProvinces = react.useMemo(() => locale === "en" ? provinceList.slice().sort((a, b) => a.nameEn.localeCompare(b.nameEn, "en")) : provinceList.slice().sort((a, b) => a.fa.localeCompare(b.fa, "fa")), [provinceList, locale]);
196
+ const sortedCities = react.useMemo(() => locale === "en" ? state.cities.slice().sort((a, b) => a.nameEn.localeCompare(b.nameEn, "en")) : state.cities.slice().sort((a, b) => a.fa.localeCompare(b.fa, "fa")), [state.cities, locale]);
197
+ return /* @__PURE__ */ react.createElement("div", {
198
+ className: classNames("ic-group", className),
199
+ dir,
200
+ "data-layout": layout,
201
+ "data-invalid": invalid ? "" : void 0,
202
+ "data-disabled": disabled ? "" : void 0
203
+ }, /* @__PURE__ */ react.createElement("div", { className: "ic-field" }, /* @__PURE__ */ react.createElement("label", {
204
+ className: "ic-label",
205
+ htmlFor: `${baseId}-province`
206
+ }, provinceLabel), /* @__PURE__ */ react.createElement("select", {
207
+ id: `${baseId}-province`,
208
+ className: "ic-select",
209
+ name: provinceName,
210
+ value: state.provinceId === void 0 ? "" : String(state.provinceId),
211
+ required,
212
+ disabled,
213
+ "aria-invalid": invalid || void 0,
214
+ onChange: (event) => state.setProvince(event.target.value === "" ? "" : Number(event.target.value))
215
+ }, /* @__PURE__ */ react.createElement("option", { value: "" }, provincePlaceholder), sortedProvinces.map((p) => /* @__PURE__ */ react.createElement("option", {
216
+ key: p.id,
217
+ value: p.id
218
+ }, locale === "en" ? p.nameEn : p.fa)))), /* @__PURE__ */ react.createElement("div", { className: "ic-field" }, /* @__PURE__ */ react.createElement("label", {
219
+ className: "ic-label",
220
+ htmlFor: `${baseId}-city`
221
+ }, cityLabel), /* @__PURE__ */ react.createElement("select", {
222
+ id: `${baseId}-city`,
223
+ className: "ic-select",
224
+ name: cityName,
225
+ value: state.cityId === void 0 ? "" : String(state.cityId),
226
+ required,
227
+ disabled: disabled || state.provinceId === void 0,
228
+ "aria-invalid": invalid || void 0,
229
+ onChange: (event) => state.setCity(event.target.value === "" ? "" : Number(event.target.value))
230
+ }, /* @__PURE__ */ react.createElement("option", { value: "" }, cityPlaceholder), sortedCities.map((c) => /* @__PURE__ */ react.createElement("option", {
231
+ key: c.id,
232
+ value: c.id
233
+ }, locale === "en" ? c.nameEn : c.fa)))));
234
+ }
235
+ return {
236
+ CityCombobox,
237
+ ProvinceCitySelect
238
+ };
239
+ }
240
+ Object.defineProperty(exports, "createComponents", {
241
+ enumerable: true,
242
+ get: function() {
243
+ return createComponents;
244
+ }
245
+ });
246
+
247
+ //# sourceMappingURL=components-grWmOsaV.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components-grWmOsaV.cjs","names":["React"],"sources":["../src/components.tsx"],"sourcesContent":["import * as React from 'react';\r\nimport type {\r\n CityId,\r\n FlatCity,\r\n IranCities,\r\n IranCitiesHooks,\r\n ProvinceCityValue,\r\n ProvinceId,\r\n Query,\r\n} from './types';\r\n\r\nexport interface CityComboboxProps {\r\n value?: CityId | null;\r\n defaultValue?: CityId | null;\r\n onChange?: (city: FlatCity | null) => void;\r\n province?: Query | null;\r\n label?: React.ReactNode;\r\n placeholder?: string;\r\n noResultsText?: React.ReactNode;\r\n limit?: number;\r\n fuzzy?: boolean;\r\n showProvince?: boolean;\r\n locale?: 'fa' | 'en';\r\n name?: string;\r\n id?: string;\r\n required?: boolean;\r\n disabled?: boolean;\r\n invalid?: boolean;\r\n dir?: 'rtl' | 'ltr' | 'auto';\r\n className?: string;\r\n inputProps?: Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'defaultValue' | 'onChange'>;\r\n}\r\n\r\nexport interface ProvinceCitySelectProps {\r\n value?: ProvinceCityValue;\r\n defaultValue?: ProvinceCityValue;\r\n onChange?: (value: ProvinceCityValue) => void;\r\n provinceLabel?: React.ReactNode;\r\n cityLabel?: React.ReactNode;\r\n provincePlaceholder?: string;\r\n cityPlaceholder?: string;\r\n provinceName?: string;\r\n cityName?: string;\r\n locale?: 'fa' | 'en';\r\n id?: string;\r\n required?: boolean;\r\n disabled?: boolean;\r\n invalid?: boolean;\r\n layout?: 'row' | 'column';\r\n dir?: 'rtl' | 'ltr' | 'auto';\r\n className?: string;\r\n}\r\n\r\nexport interface IranCitiesComponents {\r\n CityCombobox: (props: CityComboboxProps) => React.ReactElement;\r\n ProvinceCitySelect: (props: ProvinceCitySelectProps) => React.ReactElement;\r\n}\r\n\r\nlet idCounter = 0;\r\n\r\nfunction useStableId(explicit: string | undefined): string {\r\n const reactUseId = (React as unknown as { useId?: () => string }).useId;\r\n const generated = reactUseId ? reactUseId() : undefined;\r\n const [fallback] = React.useState(() => `ic-${++idCounter}`);\r\n return explicit ?? (generated ? `ic-${generated.replace(/:/g, '')}` : fallback);\r\n}\r\n\r\nfunction classNames(...names: (string | false | null | undefined)[]): string {\r\n return names.filter(Boolean).join(' ');\r\n}\r\n\r\nexport function createComponents(api: IranCities, hooks: IranCitiesHooks): IranCitiesComponents {\r\n function displayName(city: FlatCity, locale: 'fa' | 'en'): string {\r\n return locale === 'en' ? city.nameEn : city.fa;\r\n }\r\n\r\n function CityCombobox(props: CityComboboxProps): React.ReactElement {\r\n const {\r\n value,\r\n defaultValue = null,\r\n onChange,\r\n province,\r\n label,\r\n placeholder,\r\n noResultsText = 'شهری پیدا نشد',\r\n limit = 8,\r\n fuzzy = true,\r\n showProvince,\r\n locale = 'fa',\r\n name,\r\n id,\r\n required,\r\n disabled,\r\n invalid,\r\n dir = 'rtl',\r\n className,\r\n inputProps,\r\n } = props;\r\n\r\n const baseId = useStableId(id);\r\n const inputId = `${baseId}-input`;\r\n const listId = `${baseId}-list`;\r\n const labelId = `${baseId}-label`;\r\n\r\n const controlled = value !== undefined;\r\n const [innerId, setInnerId] = React.useState<CityId | null>(defaultValue);\r\n const selectedId = controlled ? value ?? null : innerId;\r\n const selected = selectedId === null ? undefined : api.getCityById(selectedId);\r\n\r\n const scope = province === undefined || province === null || province === '' ? undefined : api.getProvince(province);\r\n const scopeId: ProvinceId | undefined = scope?.id;\r\n\r\n const [text, setText] = React.useState(() => (selected ? displayName(selected, locale) : ''));\r\n const [open, setOpen] = React.useState(false);\r\n const [active, setActive] = React.useState(-1);\r\n const listRef = React.useRef<HTMLUListElement>(null);\r\n\r\n React.useEffect(() => {\r\n setText(selected ? displayName(selected, locale) : '');\r\n }, [selected, locale]);\r\n\r\n const results = React.useMemo(() => {\r\n const found = api.searchCities(text, {\r\n fuzzy,\r\n emptyQuery: scopeId === undefined ? 'none' : 'all',\r\n limit: scopeId === undefined ? limit : undefined,\r\n });\r\n const scoped = scopeId === undefined ? found : found.filter((c) => c.provinceId === scopeId);\r\n return scoped.slice(0, limit);\r\n }, [text, fuzzy, limit, scopeId]);\r\n\r\n const withProvince = showProvince ?? scopeId === undefined;\r\n\r\n function select(city: FlatCity | null): void {\r\n if (!controlled) setInnerId(city ? city.id : null);\r\n setText(city ? displayName(city, locale) : '');\r\n setOpen(false);\r\n setActive(-1);\r\n onChange?.(city);\r\n }\r\n\r\n function restore(): void {\r\n setText(selected ? displayName(selected, locale) : '');\r\n setOpen(false);\r\n setActive(-1);\r\n }\r\n\r\n React.useEffect(() => {\r\n if (active < 0 || !listRef.current) return;\r\n const option = listRef.current.children[active] as HTMLElement | undefined;\r\n if (option && typeof option.scrollIntoView === 'function') option.scrollIntoView({ block: 'nearest' });\r\n }, [active]);\r\n\r\n function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {\r\n inputProps?.onKeyDown?.(event);\r\n if (event.defaultPrevented) return;\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n if (!open) setOpen(true);\r\n setActive((i) => (results.length === 0 ? -1 : (i + 1) % results.length));\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n if (!open) setOpen(true);\r\n setActive((i) => (results.length === 0 ? -1 : i <= 0 ? results.length - 1 : i - 1));\r\n break;\r\n case 'Home':\r\n if (open && results.length > 0) {\r\n event.preventDefault();\r\n setActive(0);\r\n }\r\n break;\r\n case 'End':\r\n if (open && results.length > 0) {\r\n event.preventDefault();\r\n setActive(results.length - 1);\r\n }\r\n break;\r\n case 'Enter':\r\n if (open && active >= 0 && results[active]) {\r\n event.preventDefault();\r\n select(results[active] as FlatCity);\r\n }\r\n break;\r\n case 'Escape':\r\n if (open) {\r\n event.preventDefault();\r\n restore();\r\n } else if (text) {\r\n event.preventDefault();\r\n select(null);\r\n }\r\n break;\r\n case 'Tab':\r\n if (open) restore();\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n const expanded = open && !disabled;\r\n const activeId = expanded && active >= 0 ? `${baseId}-option-${active}` : undefined;\r\n\r\n return (\r\n <div\r\n className={classNames('ic-field', 'ic-combobox', className)}\r\n dir={dir}\r\n data-open={expanded ? '' : undefined}\r\n data-invalid={invalid ? '' : undefined}\r\n data-disabled={disabled ? '' : undefined}\r\n >\r\n {label !== undefined ? (\r\n <label className=\"ic-label\" id={labelId} htmlFor={inputId}>\r\n {label}\r\n </label>\r\n ) : null}\r\n <div className=\"ic-control\">\r\n <input\r\n {...inputProps}\r\n id={inputId}\r\n className={classNames('ic-input', inputProps?.className)}\r\n type=\"text\"\r\n role=\"combobox\"\r\n autoComplete=\"off\"\r\n spellCheck={false}\r\n aria-autocomplete=\"list\"\r\n aria-expanded={expanded}\r\n aria-controls={listId}\r\n aria-activedescendant={activeId}\r\n aria-invalid={invalid || undefined}\r\n aria-required={required || undefined}\r\n placeholder={placeholder}\r\n disabled={disabled}\r\n value={text}\r\n onChange={(event) => {\r\n setText(event.target.value);\r\n setOpen(true);\r\n setActive(-1);\r\n }}\r\n onFocus={(event) => {\r\n inputProps?.onFocus?.(event);\r\n if (scopeId !== undefined || text) setOpen(true);\r\n }}\r\n onBlur={(event) => {\r\n inputProps?.onBlur?.(event);\r\n restore();\r\n }}\r\n onKeyDown={onKeyDown}\r\n />\r\n {name ? <input type=\"hidden\" name={name} value={selected ? String(selected.id) : ''} /> : null}\r\n </div>\r\n <ul\r\n ref={listRef}\r\n id={listId}\r\n className=\"ic-listbox\"\r\n role=\"listbox\"\r\n aria-labelledby={label !== undefined ? labelId : undefined}\r\n hidden={!expanded}\r\n >\r\n {expanded && results.length === 0 ? (\r\n <li className=\"ic-empty\" role=\"presentation\">\r\n {noResultsText}\r\n </li>\r\n ) : null}\r\n {expanded\r\n ? results.map((city, index) => (\r\n <li\r\n key={city.id}\r\n id={`${baseId}-option-${index}`}\r\n className=\"ic-option\"\r\n role=\"option\"\r\n aria-selected={selected?.id === city.id}\r\n data-active={index === active ? '' : undefined}\r\n onMouseDown={(event) => event.preventDefault()}\r\n onMouseMove={() => setActive(index)}\r\n onClick={() => select(city)}\r\n >\r\n <span className=\"ic-option-name\">{displayName(city, locale)}</span>\r\n {withProvince ? (\r\n <span className=\"ic-option-meta\">{locale === 'en' ? city.provinceNameEn : city.provinceFa}</span>\r\n ) : null}\r\n </li>\r\n ))\r\n : null}\r\n </ul>\r\n </div>\r\n );\r\n }\r\n\r\n function ProvinceCitySelect(props: ProvinceCitySelectProps): React.ReactElement {\r\n const {\r\n value,\r\n defaultValue,\r\n onChange,\r\n provinceLabel = 'استان',\r\n cityLabel = 'شهر',\r\n provincePlaceholder = 'انتخاب استان',\r\n cityPlaceholder = 'انتخاب شهر',\r\n provinceName,\r\n cityName,\r\n locale = 'fa',\r\n id,\r\n required,\r\n disabled,\r\n invalid,\r\n layout = 'row',\r\n dir = 'rtl',\r\n className,\r\n } = props;\r\n\r\n const baseId = useStableId(id);\r\n const state = hooks.useProvinceCitySelect({\r\n value,\r\n onChange,\r\n initialProvince: defaultValue?.provinceId,\r\n initialCity: defaultValue?.cityId,\r\n });\r\n const provinceList = state.provinces;\r\n const sortedProvinces = React.useMemo(\r\n () =>\r\n locale === 'en'\r\n ? provinceList.slice().sort((a, b) => a.nameEn.localeCompare(b.nameEn, 'en'))\r\n : provinceList.slice().sort((a, b) => a.fa.localeCompare(b.fa, 'fa')),\r\n [provinceList, locale],\r\n );\r\n const sortedCities = React.useMemo(\r\n () =>\r\n locale === 'en'\r\n ? state.cities.slice().sort((a, b) => a.nameEn.localeCompare(b.nameEn, 'en'))\r\n : state.cities.slice().sort((a, b) => a.fa.localeCompare(b.fa, 'fa')),\r\n [state.cities, locale],\r\n );\r\n\r\n return (\r\n <div\r\n className={classNames('ic-group', className)}\r\n dir={dir}\r\n data-layout={layout}\r\n data-invalid={invalid ? '' : undefined}\r\n data-disabled={disabled ? '' : undefined}\r\n >\r\n <div className=\"ic-field\">\r\n <label className=\"ic-label\" htmlFor={`${baseId}-province`}>\r\n {provinceLabel}\r\n </label>\r\n <select\r\n id={`${baseId}-province`}\r\n className=\"ic-select\"\r\n name={provinceName}\r\n value={state.provinceId === undefined ? '' : String(state.provinceId)}\r\n required={required}\r\n disabled={disabled}\r\n aria-invalid={invalid || undefined}\r\n onChange={(event) => state.setProvince(event.target.value === '' ? '' : Number(event.target.value))}\r\n >\r\n <option value=\"\">{provincePlaceholder}</option>\r\n {sortedProvinces.map((p) => (\r\n <option key={p.id} value={p.id}>\r\n {locale === 'en' ? p.nameEn : p.fa}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n <div className=\"ic-field\">\r\n <label className=\"ic-label\" htmlFor={`${baseId}-city`}>\r\n {cityLabel}\r\n </label>\r\n <select\r\n id={`${baseId}-city`}\r\n className=\"ic-select\"\r\n name={cityName}\r\n value={state.cityId === undefined ? '' : String(state.cityId)}\r\n required={required}\r\n disabled={disabled || state.provinceId === undefined}\r\n aria-invalid={invalid || undefined}\r\n onChange={(event) => state.setCity(event.target.value === '' ? '' : Number(event.target.value))}\r\n >\r\n <option value=\"\">{cityPlaceholder}</option>\r\n {sortedCities.map((c) => (\r\n <option key={c.id} value={c.id}>\r\n {locale === 'en' ? c.nameEn : c.fa}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return { CityCombobox, ProvinceCitySelect };\r\n}\r\n"],"mappings":"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"}
@@ -0,0 +1,251 @@
1
+ :where(.ic-field, .ic-group) {
2
+ --ic-font: inherit;
3
+ --ic-font-size: 0.9375rem;
4
+ --ic-line-height: 1.5;
5
+ --ic-radius: 0.625rem;
6
+ --ic-gap: 0.75rem;
7
+ --ic-height: 2.75rem;
8
+ --ic-padding-inline: 0.875rem;
9
+ --ic-bg: #ffffff;
10
+ --ic-fg: #0f172a;
11
+ --ic-muted: #64748b;
12
+ --ic-border: #cbd5e1;
13
+ --ic-border-hover: #94a3b8;
14
+ --ic-accent: #0a7f5a;
15
+ --ic-accent-soft: rgba(10, 127, 90, 0.1);
16
+ --ic-ring: rgba(10, 127, 90, 0.28);
17
+ --ic-danger: #dc2626;
18
+ --ic-danger-ring: rgba(220, 38, 38, 0.22);
19
+ --ic-disabled-bg: #f1f5f9;
20
+ --ic-popover-bg: #ffffff;
21
+ --ic-shadow: 0 12px 32px -8px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.06);
22
+ --ic-listbox-max-height: 18rem;
23
+ --ic-transition: 150ms ease;
24
+ color-scheme: light;
25
+ font-family: var(--ic-font);
26
+ font-size: var(--ic-font-size);
27
+ line-height: var(--ic-line-height);
28
+ color: var(--ic-fg);
29
+ }
30
+
31
+ @media (prefers-color-scheme: dark) {
32
+ :where(.ic-field, .ic-group):not([data-theme='light'] *, [data-theme='light']) {
33
+ --ic-bg: #0f172a;
34
+ --ic-fg: #e2e8f0;
35
+ --ic-muted: #94a3b8;
36
+ --ic-border: #334155;
37
+ --ic-border-hover: #475569;
38
+ --ic-accent: #34d399;
39
+ --ic-accent-soft: rgba(52, 211, 153, 0.14);
40
+ --ic-ring: rgba(52, 211, 153, 0.32);
41
+ --ic-danger: #f87171;
42
+ --ic-danger-ring: rgba(248, 113, 113, 0.28);
43
+ --ic-disabled-bg: #1e293b;
44
+ --ic-popover-bg: #111c33;
45
+ --ic-shadow: 0 16px 40px -8px rgba(0, 0, 0, 0.6), 0 2px 6px rgba(0, 0, 0, 0.3);
46
+ color-scheme: dark;
47
+ }
48
+ }
49
+
50
+ :where([data-theme='dark'] .ic-field, [data-theme='dark'] .ic-group, .ic-field[data-theme='dark'], .ic-group[data-theme='dark']) {
51
+ --ic-bg: #0f172a;
52
+ --ic-fg: #e2e8f0;
53
+ --ic-muted: #94a3b8;
54
+ --ic-border: #334155;
55
+ --ic-border-hover: #475569;
56
+ --ic-accent: #34d399;
57
+ --ic-accent-soft: rgba(52, 211, 153, 0.14);
58
+ --ic-ring: rgba(52, 211, 153, 0.32);
59
+ --ic-danger: #f87171;
60
+ --ic-danger-ring: rgba(248, 113, 113, 0.28);
61
+ --ic-disabled-bg: #1e293b;
62
+ --ic-popover-bg: #111c33;
63
+ --ic-shadow: 0 16px 40px -8px rgba(0, 0, 0, 0.6), 0 2px 6px rgba(0, 0, 0, 0.3);
64
+ color-scheme: dark;
65
+ }
66
+
67
+ .ic-group > .ic-field,
68
+ .ic-field > .ic-label,
69
+ .ic-field > .ic-control,
70
+ .ic-field > .ic-listbox,
71
+ .ic-listbox > .ic-option,
72
+ .ic-listbox > .ic-empty {
73
+ margin: 0;
74
+ }
75
+
76
+ :where(.ic-group) {
77
+ display: grid;
78
+ grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
79
+ gap: var(--ic-gap);
80
+ }
81
+
82
+ :where(.ic-group[data-layout='column']) {
83
+ grid-template-columns: minmax(0, 1fr);
84
+ }
85
+
86
+ :where(.ic-field) {
87
+ position: relative;
88
+ display: flex;
89
+ flex-direction: column;
90
+ gap: 0.375rem;
91
+ min-inline-size: 0;
92
+ }
93
+
94
+ :where(.ic-label) {
95
+ font-size: 0.875em;
96
+ font-weight: 500;
97
+ color: var(--ic-fg);
98
+ }
99
+
100
+ :where(.ic-control) {
101
+ position: relative;
102
+ }
103
+
104
+ :where(.ic-input, .ic-select) {
105
+ box-sizing: border-box;
106
+ inline-size: 100%;
107
+ block-size: var(--ic-height);
108
+ margin: 0;
109
+ padding-block: 0;
110
+ padding-inline: var(--ic-padding-inline);
111
+ font: inherit;
112
+ color: var(--ic-fg);
113
+ background-color: var(--ic-bg);
114
+ border: 1px solid var(--ic-border);
115
+ border-radius: var(--ic-radius);
116
+ outline: none;
117
+ transition: border-color var(--ic-transition), box-shadow var(--ic-transition), background-color var(--ic-transition);
118
+ }
119
+
120
+ :where(.ic-input)::placeholder {
121
+ color: var(--ic-muted);
122
+ opacity: 1;
123
+ }
124
+
125
+ :where(.ic-select) {
126
+ appearance: none;
127
+ cursor: pointer;
128
+ padding-inline-end: calc(var(--ic-padding-inline) + 1.25rem);
129
+ background-image: linear-gradient(45deg, transparent 50%, var(--ic-muted) 50%),
130
+ linear-gradient(135deg, var(--ic-muted) 50%, transparent 50%);
131
+ background-repeat: no-repeat;
132
+ background-size: 0.3125rem 0.3125rem, 0.3125rem 0.3125rem;
133
+ background-position: right calc(var(--ic-padding-inline) + 0.3125rem) center, right var(--ic-padding-inline) center;
134
+ }
135
+
136
+ :where([dir='rtl']) :where(.ic-select),
137
+ :where(.ic-select[dir='rtl']) {
138
+ background-position: left var(--ic-padding-inline) center, left calc(var(--ic-padding-inline) + 0.3125rem) center;
139
+ }
140
+
141
+ :where(.ic-input, .ic-select):hover:not(:disabled) {
142
+ border-color: var(--ic-border-hover);
143
+ }
144
+
145
+ :where(.ic-input, .ic-select):focus-visible,
146
+ :where(.ic-combobox[data-open]) :where(.ic-input) {
147
+ border-color: var(--ic-accent);
148
+ box-shadow: 0 0 0 3px var(--ic-ring);
149
+ }
150
+
151
+ :where(.ic-input, .ic-select):disabled {
152
+ cursor: not-allowed;
153
+ color: var(--ic-muted);
154
+ background-color: var(--ic-disabled-bg);
155
+ }
156
+
157
+ :where([data-invalid]) :where(.ic-input, .ic-select),
158
+ :where(.ic-input, .ic-select)[aria-invalid='true'] {
159
+ border-color: var(--ic-danger);
160
+ }
161
+
162
+ :where([data-invalid]) :where(.ic-input, .ic-select):focus-visible,
163
+ :where(.ic-input, .ic-select)[aria-invalid='true']:focus-visible {
164
+ box-shadow: 0 0 0 3px var(--ic-danger-ring);
165
+ }
166
+
167
+ :where(.ic-listbox) {
168
+ position: absolute;
169
+ inset-inline: 0;
170
+ inset-block-start: calc(100% + 0.375rem);
171
+ z-index: 50;
172
+ box-sizing: border-box;
173
+ max-block-size: var(--ic-listbox-max-height);
174
+ margin: 0;
175
+ padding: 0.3125rem;
176
+ overflow-y: auto;
177
+ overscroll-behavior: contain;
178
+ list-style: none;
179
+ background-color: var(--ic-popover-bg);
180
+ border: 1px solid var(--ic-border);
181
+ border-radius: var(--ic-radius);
182
+ box-shadow: var(--ic-shadow);
183
+ animation: ic-pop var(--ic-transition);
184
+ }
185
+
186
+ :where(.ic-listbox)[hidden] {
187
+ display: none;
188
+ }
189
+
190
+ :where(.ic-option) {
191
+ display: flex;
192
+ align-items: baseline;
193
+ justify-content: space-between;
194
+ gap: 0.75rem;
195
+ padding-block: 0.5rem;
196
+ padding-inline: 0.625rem;
197
+ border-radius: calc(var(--ic-radius) - 0.25rem);
198
+ cursor: pointer;
199
+ user-select: none;
200
+ }
201
+
202
+ :where(.ic-option)[data-active] {
203
+ background-color: var(--ic-accent-soft);
204
+ }
205
+
206
+ :where(.ic-option)[aria-selected='true'] {
207
+ font-weight: 600;
208
+ color: var(--ic-accent);
209
+ }
210
+
211
+ :where(.ic-option-meta) {
212
+ flex-shrink: 0;
213
+ font-size: 0.8125em;
214
+ font-weight: 400;
215
+ color: var(--ic-muted);
216
+ }
217
+
218
+ :where(.ic-empty) {
219
+ padding-block: 0.75rem;
220
+ padding-inline: 0.625rem;
221
+ color: var(--ic-muted);
222
+ text-align: center;
223
+ }
224
+
225
+ @keyframes ic-pop {
226
+ from {
227
+ opacity: 0;
228
+ transform: translateY(-0.25rem);
229
+ }
230
+ to {
231
+ opacity: 1;
232
+ transform: translateY(0);
233
+ }
234
+ }
235
+
236
+ @media (prefers-reduced-motion: reduce) {
237
+ :where(.ic-input, .ic-select, .ic-listbox) {
238
+ transition: none;
239
+ animation: none;
240
+ }
241
+ }
242
+
243
+ @media (forced-colors: active) {
244
+ :where(.ic-option)[data-active] {
245
+ outline: 2px solid Highlight;
246
+ }
247
+
248
+ :where(.ic-input, .ic-select):focus-visible {
249
+ outline: 2px solid Highlight;
250
+ }
251
+ }