@accelint/design-toolkit 8.1.1 → 8.1.3
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.
- package/catalog-info.yaml +6 -6
- package/dist/components/button/styles.module.css +1 -1
- package/dist/components/coordinate-field/coordinate-utils.js +1 -1
- package/dist/components/coordinate-field/coordinate-utils.js.map +1 -1
- package/dist/components/coordinate-field/index.js +1 -1
- package/dist/components/coordinate-field/index.js.map +1 -1
- package/dist/components/coordinate-field/segment-configs.d.ts +3 -1
- package/dist/components/coordinate-field/segment-configs.js +1 -1
- package/dist/components/coordinate-field/segment-configs.js.map +1 -1
- package/dist/components/coordinate-field/styles.module.css +25 -3
- package/dist/components/coordinate-field/types.d.ts +7 -0
- package/dist/components/coordinate-field/types.js.map +1 -1
- package/dist/components/coordinate-field/width-utils.d.ts +4 -3
- package/dist/components/coordinate-field/width-utils.js +1 -1
- package/dist/components/coordinate-field/width-utils.js.map +1 -1
- package/dist/components/menu/types.d.ts +2 -2
- package/dist/hooks/coordinate-field/use-coordinate-field-state.js +1 -1
- package/dist/hooks/coordinate-field/use-coordinate-field-state.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +39 -38
- package/LICENSE +0 -201
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/coordinate-field/segment-configs.ts"],"names":["ddSegmentConfigs","ddmSegmentConfigs","dmsSegmentConfigs","mgrsSegmentConfigs","utmSegmentConfigs","getSegmentConfigs","format","getFormatDescription","getEditableSegmentCount","config","EXPECTED_SEGMENT_COUNTS","getSegmentLabel","editableIndex"],"mappings":"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","file":"segment-configs.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n/**\n * Coordinate Field Segment Configurations\n *\n * This file defines the segment layouts for each supported coordinate system format.\n * Each configuration specifies the editable segments and literal separators that make up\n * the coordinate input for that format.\n *\n * Supported formats:\n * - DD (Decimal Degrees) - 2 editable segments\n * - DDM (Degrees Decimal Minutes) - 6 editable segments\n * - DMS (Degrees Minutes Seconds) - 8 editable segments\n * - MGRS (Military Grid Reference System) - 5 editable segments\n * - UTM (Universal Transverse Mercator) - 4 editable segments\n *\n * References:\n * - DD parser: /packages/geo/src/coordinates/latlon/decimal-degrees/parser.ts\n * - DDM parser: /packages/geo/src/coordinates/latlon/degrees-decimal-minutes/parser.ts\n * - DMS parser: /packages/geo/src/coordinates/latlon/degrees-minutes-seconds/parser.ts\n * - MGRS parser: /packages/geo/src/coordinates/mgrs/parser.ts\n * - UTM parser: /packages/geo/src/coordinates/utm/parser.ts\n */\n\nimport type { CoordinateSystem, SegmentConfig } from './types';\n\n/** Padding for numeric segments (0.25ch ≈ quarter character width for visual spacing) */\nconst NUMERIC_PAD = 0.25;\n\n/** Larger padding for final segment to account for container edge (0.5ch ≈ half character) */\nconst LAST_PAD = 0.5;\n\n/**\n * DD (Decimal Degrees) Segment Configuration\n *\n * Format: [lat_deg], [lon_deg]\n * Example: 89.765432, -123.456789\n *\n * Segments:\n * - Latitude degrees: -90 to 90, allows negative sign, decimals, 0-9\n * - Longitude degrees: -180 to 180, allows negative sign, decimals, 0-9\n *\n * Total segments: 2 editable\n */\nexport const ddSegmentConfigs: SegmentConfig[] = [\n {\n type: 'numeric',\n placeholder: '00.000000',\n allowedChars: '[0-9\\\\-\\\\.]',\n maxLength: 10, // Max: -90.123456\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: ', ',\n },\n {\n type: 'numeric',\n placeholder: '-000.000000',\n allowedChars: '[0-9\\\\-\\\\.]',\n maxLength: 11, // Max: -180.123456\n pad: LAST_PAD,\n },\n];\n\n/**\n * DDM (Degrees Decimal Minutes) Segment Configuration\n *\n * Format: [lat_deg]° [lat_min]' [lat_dir], [lon_deg]° [lon_min]' [lon_dir]\n * Example: 89° 45.9259' N, 123° 27.4073' W\n *\n * Segments:\n * - Latitude degrees: 0-90, whole number only (no decimals)\n * - Latitude minutes: 0-59.9999, decimals allowed\n * - Latitude direction: N or S\n * - Longitude degrees: 0-180, whole number only (no decimals)\n * - Longitude minutes: 0-59.9999, decimals allowed\n * - Longitude direction: E or W\n *\n * Total segments: 6 editable\n */\nexport const ddmSegmentConfigs: SegmentConfig[] = [\n // Latitude degrees\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 90\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '° ',\n },\n // Latitude minutes (decimal minutes)\n {\n type: 'numeric',\n placeholder: '00.0000',\n allowedChars: '[0-9\\\\.]',\n maxLength: 7, // Max: 59.9999\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: \"' \",\n },\n // Latitude direction\n {\n type: 'directional',\n placeholder: 'N',\n allowedChars: '[NS]',\n maxLength: 1,\n pad: 0,\n },\n {\n type: 'literal',\n value: ', ',\n },\n // Longitude degrees\n {\n type: 'numeric',\n placeholder: '000',\n allowedChars: '[0-9]',\n maxLength: 3, // Max: 180\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '° ',\n },\n // Longitude minutes (decimal minutes)\n {\n type: 'numeric',\n placeholder: '00.0000',\n allowedChars: '[0-9\\\\.]',\n maxLength: 7, // Max: 59.9999\n pad: LAST_PAD,\n },\n {\n type: 'literal',\n value: \"' \",\n },\n // Longitude direction\n {\n type: 'directional',\n placeholder: 'W',\n allowedChars: '[EW]',\n maxLength: 1,\n pad: 0,\n },\n];\n\n/**\n * DMS (Degrees Minutes Seconds) Segment Configuration\n *\n * Format: [lat_deg]° [lat_min]' [lat_sec]\" [lat_dir], [lon_deg]° [lon_min]' [lon_sec]\" [lon_dir]\n * Example: 89° 45' 55.56\" N, 123° 27' 24.44\" W\n *\n * Segments:\n * - Latitude degrees: 0-90, whole number only (no decimals)\n * - Latitude minutes: 0-59, whole number only (no decimals)\n * - Latitude seconds: 0-59.999, decimals allowed\n * - Latitude direction: N or S\n * - Longitude degrees: 0-180, whole number only (no decimals)\n * - Longitude minutes: 0-59, whole number only (no decimals)\n * - Longitude seconds: 0-59.999, decimals allowed\n * - Longitude direction: E or W\n *\n * Total segments: 8 editable\n */\nexport const dmsSegmentConfigs: SegmentConfig[] = [\n // Latitude degrees\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 90\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '° ',\n },\n // Latitude minutes (whole number)\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 59\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: \"' \",\n },\n // Latitude seconds (decimal seconds)\n {\n type: 'numeric',\n placeholder: '00.00',\n allowedChars: '[0-9\\\\.]',\n maxLength: 5, // Max: 59.99\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '\" ',\n },\n // Latitude direction\n {\n type: 'directional',\n placeholder: 'N',\n allowedChars: '[NS]',\n maxLength: 1,\n pad: 0,\n },\n {\n type: 'literal',\n value: ', ',\n },\n // Longitude degrees\n {\n type: 'numeric',\n placeholder: '000',\n allowedChars: '[0-9]',\n maxLength: 3, // Max: 180\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '° ',\n },\n // Longitude minutes (whole number)\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 59\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: \"' \",\n },\n // Longitude seconds (decimal seconds)\n {\n type: 'numeric',\n placeholder: '00.00',\n allowedChars: '[0-9\\\\.]',\n maxLength: 5, // Max: 59.99\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '\" ',\n },\n // Longitude direction\n {\n type: 'directional',\n placeholder: 'W',\n allowedChars: '[EW]',\n maxLength: 1,\n pad: 0,\n },\n];\n\n/**\n * MGRS (Military Grid Reference System) Segment Configuration\n *\n * Format: [zone][band] [grid_100km] [easting] [northing]\n * Example: 18T WM 12345 67890\n *\n * Segments:\n * - Zone: 1-60, 2 digits\n * - Band: C-X (excluding I and O), 1 letter\n * - Grid 100km: 2 letters (A-Z excluding I and O)\n * - Easting: 5 digits (can be 1-5 based on precision)\n * - Northing: 5 digits (can be 1-5 based on precision)\n *\n * Total segments: 5 editable\n *\n * Reference: /packages/geo/src/coordinates/mgrs/parser.ts\n * Pattern: /^((?:..?)?)(\\w?)\\s*((?:\\w{2})?)\\s*(?:(\\d+(?:\\.\\d*)?)?)\\s*(?:(\\d+(?:\\.\\d*)?)?)$/i\n */\nexport const mgrsSegmentConfigs: SegmentConfig[] = [\n // Zone (1-60)\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 60\n pad: NUMERIC_PAD,\n },\n // Band (C-X, excluding I and O)\n {\n type: 'alphanumeric',\n placeholder: 'T',\n allowedChars: '[C-HJ-NP-X]', // Excludes I and O\n maxLength: 1,\n pad: 0,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Grid 100km identifier (2 letters, A-Z excluding I and O)\n {\n type: 'alphanumeric',\n placeholder: 'WM',\n allowedChars: '[A-HJ-NP-Z]', // Excludes I and O\n maxLength: 2,\n pad: 0,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Easting (5 digits, can be 1-5 based on precision)\n {\n type: 'numeric',\n placeholder: '00000',\n allowedChars: '[0-9]',\n maxLength: 5,\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Northing (5 digits, can be 1-5 based on precision)\n {\n type: 'numeric',\n placeholder: '00000',\n allowedChars: '[0-9]',\n maxLength: 5,\n pad: LAST_PAD,\n },\n];\n\n/**\n * UTM (Universal Transverse Mercator) Segment Configuration\n *\n * Format: [zone][hemisphere] [easting] [northing]\n * Example: 18N 585628 4511644\n *\n * Segments:\n * - Zone: 1-60, 2 digits\n * - Hemisphere: N or S, 1 letter\n * - Easting: 6-7 digits\n * - Northing: 7 digits\n *\n * Total segments: 4 editable\n *\n * Reference: /packages/geo/src/coordinates/utm/parser.ts\n * Pattern: /^((?:..)?)\\s*(\\w?)\\s*(?:(\\d+(?:\\.\\d*)?)?)\\s*(?:(\\d+(?:\\.\\d*)?)?)$/i\n */\nexport const utmSegmentConfigs: SegmentConfig[] = [\n // Zone (1-60)\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 60\n pad: NUMERIC_PAD,\n },\n // Hemisphere (N or S)\n {\n type: 'directional',\n placeholder: 'N',\n allowedChars: '[NS]',\n maxLength: 1,\n pad: 0,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Easting (6-7 digits)\n {\n type: 'numeric',\n placeholder: '000000',\n allowedChars: '[0-9]',\n maxLength: 7,\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Northing (7 digits)\n {\n type: 'numeric',\n placeholder: '0000000',\n allowedChars: '[0-9]',\n maxLength: 7,\n pad: LAST_PAD,\n },\n];\n\n/**\n * Get segment configurations for a specific coordinate system\n *\n * @param format - The coordinate system format\n * @returns Array of segment configurations for the specified format\n */\nexport function getSegmentConfigs(format: CoordinateSystem): SegmentConfig[] {\n switch (format) {\n case 'dd':\n return ddSegmentConfigs;\n case 'ddm':\n return ddmSegmentConfigs;\n case 'dms':\n return dmsSegmentConfigs;\n case 'mgrs':\n return mgrsSegmentConfigs;\n case 'utm':\n return utmSegmentConfigs;\n default:\n // Default to DD format if unknown format provided\n return ddSegmentConfigs;\n }\n}\n\n/**\n * Get format description with example\n *\n * Provides a user-friendly description of the coordinate format with an example value.\n * These descriptions can be used as helper text to guide users on the expected format.\n *\n * @param format - The coordinate system format\n * @returns Description string with format example\n */\nexport function getFormatDescription(format: CoordinateSystem): string {\n switch (format) {\n case 'dd':\n return 'Example: 40.7128, -74.0060 (New York City)';\n case 'ddm':\n return \"Example: 40° 42.768' N, 74° 0.360' W (New York City)\";\n case 'dms':\n return 'Example: 40° 42\\' 46.08\" N, 74° 0\\' 21.60\" W (New York City)';\n case 'mgrs':\n return 'Example: 18T WL 80654 06346 (New York City)';\n case 'utm':\n return 'Example: 18N 585628 4511644 (New York City)';\n default:\n return '';\n }\n}\n\n/**\n * Get editable segment count for a format\n *\n * Returns the number of editable segments (excluding literal separators) for each format.\n * This is useful for initializing segment values and validation.\n *\n * @param format - The coordinate system format\n * @returns Number of editable segments\n */\nexport function getEditableSegmentCount(format: CoordinateSystem): number {\n const configs = getSegmentConfigs(format);\n return configs.filter((config) => config.type !== 'literal').length;\n}\n\n/**\n * Validate segment count for each format\n *\n * Expected editable segment counts:\n * - DD: 2 segments (lat, lon)\n * - DDM: 6 segments (lat_deg, lat_min, lat_dir, lon_deg, lon_min, lon_dir)\n * - DMS: 8 segments (lat_deg, lat_min, lat_sec, lat_dir, lon_deg, lon_min, lon_sec, lon_dir)\n * - MGRS: 5 segments (zone, band, grid, easting, northing)\n * - UTM: 4 segments (zone, hemisphere, easting, northing)\n */\nexport const EXPECTED_SEGMENT_COUNTS: Record<CoordinateSystem, number> = {\n dd: 2,\n ddm: 6,\n dms: 8,\n mgrs: 5,\n utm: 4,\n};\n\n/**\n * Get semantic accessibility label for a segment based on format and editable index\n *\n * Provides descriptive labels for screen readers (e.g., \"Latitude degrees\", \"Longitude minutes\")\n * to improve accessibility beyond generic \"Coordinate segment 1\" announcements.\n *\n * @param format - The coordinate system format\n * @param editableIndex - The index of the editable segment (0-based, excluding literals)\n * @returns Semantic label string for the segment\n */\nexport function getSegmentLabel(\n format: CoordinateSystem,\n editableIndex: number,\n): string {\n switch (format) {\n case 'dd':\n // DD: [lat, lon]\n return editableIndex === 0 ? 'Latitude' : 'Longitude';\n\n case 'ddm':\n // DDM: [lat_deg, lat_min, lat_dir, lon_deg, lon_min, lon_dir]\n switch (editableIndex) {\n case 0:\n return 'Latitude degrees';\n case 1:\n return 'Latitude minutes';\n case 2:\n return 'Latitude direction';\n case 3:\n return 'Longitude degrees';\n case 4:\n return 'Longitude minutes';\n case 5:\n return 'Longitude direction';\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n\n case 'dms':\n // DMS: [lat_deg, lat_min, lat_sec, lat_dir, lon_deg, lon_min, lon_sec, lon_dir]\n switch (editableIndex) {\n case 0:\n return 'Latitude degrees';\n case 1:\n return 'Latitude minutes';\n case 2:\n return 'Latitude seconds';\n case 3:\n return 'Latitude direction';\n case 4:\n return 'Longitude degrees';\n case 5:\n return 'Longitude minutes';\n case 6:\n return 'Longitude seconds';\n case 7:\n return 'Longitude direction';\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n\n case 'mgrs':\n // MGRS: [zone, band, grid, easting, northing]\n switch (editableIndex) {\n case 0:\n return 'MGRS zone';\n case 1:\n return 'MGRS band';\n case 2:\n return 'MGRS grid square';\n case 3:\n return 'MGRS easting';\n case 4:\n return 'MGRS northing';\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n\n case 'utm':\n // UTM: [zone, hemisphere, easting, northing]\n switch (editableIndex) {\n case 0:\n return 'UTM zone';\n case 1:\n return 'UTM hemisphere';\n case 2:\n return 'UTM easting';\n case 3:\n return 'UTM northing';\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/coordinate-field/segment-configs.ts"],"names":["GROUP_SEPARATOR","ddSegmentConfigs","ddmSegmentConfigs","dmsSegmentConfigs","mgrsSegmentConfigs","utmSegmentConfigs","getSegmentConfigs","format","getFormatDescription","getEditableSegmentCount","config","EXPECTED_SEGMENT_COUNTS","getSegmentLabel","editableIndex"],"mappings":"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","file":"segment-configs.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n/**\n * Coordinate Field Segment Configurations\n *\n * This file defines the segment layouts for each supported coordinate system format.\n * Each configuration specifies the editable segments and literal separators that make up\n * the coordinate input for that format.\n *\n * Supported formats:\n * - DD (Decimal Degrees) - 2 editable segments\n * - DDM (Degrees Decimal Minutes) - 6 editable segments\n * - DMS (Degrees Minutes Seconds) - 8 editable segments\n * - MGRS (Military Grid Reference System) - 5 editable segments\n * - UTM (Universal Transverse Mercator) - 4 editable segments\n *\n * References:\n * - DD parser: /packages/geo/src/coordinates/latlon/decimal-degrees/parser.ts\n * - DDM parser: /packages/geo/src/coordinates/latlon/degrees-decimal-minutes/parser.ts\n * - DMS parser: /packages/geo/src/coordinates/latlon/degrees-minutes-seconds/parser.ts\n * - MGRS parser: /packages/geo/src/coordinates/mgrs/parser.ts\n * - UTM parser: /packages/geo/src/coordinates/utm/parser.ts\n */\n\nimport type { CoordinateSystem, SegmentConfig } from './types';\n\n/** Padding for numeric segments (0.25ch ≈ quarter character width for visual spacing) */\nconst NUMERIC_PAD = 0.25;\n\n/** Larger padding for final segment to account for container edge (0.5ch ≈ half character) */\nconst LAST_PAD = 0.5;\n\n/** The separator used for the logical field groups. */\nexport const GROUP_SEPARATOR = ', ';\n\n/**\n * DD (Decimal Degrees) Segment Configuration\n *\n * Format: [lat_deg], [lon_deg]\n * Example: 89.765432, -123.456789\n *\n * Segments:\n * - Latitude degrees: -90 to 90, allows negative sign, decimals, 0-9\n * - Longitude degrees: -180 to 180, allows negative sign, decimals, 0-9\n *\n * Total segments: 2 editable\n */\nexport const ddSegmentConfigs: SegmentConfig[] = [\n {\n type: 'numeric',\n placeholder: '00.000000',\n allowedChars: '[0-9\\\\-\\\\.]',\n maxLength: 10, // Max: -90.123456\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: GROUP_SEPARATOR,\n },\n {\n type: 'numeric',\n placeholder: '-000.000000',\n allowedChars: '[0-9\\\\-\\\\.]',\n maxLength: 11, // Max: -180.123456\n pad: LAST_PAD,\n },\n];\n\n/**\n * DDM (Degrees Decimal Minutes) Segment Configuration\n *\n * Format: [lat_deg]° [lat_min]' [lat_dir], [lon_deg]° [lon_min]' [lon_dir]\n * Example: 89° 45.9259' N, 123° 27.4073' W\n *\n * Segments:\n * - Latitude degrees: 0-90, whole number only (no decimals)\n * - Latitude minutes: 0-59.9999, decimals allowed\n * - Latitude direction: N or S\n * - Longitude degrees: 0-180, whole number only (no decimals)\n * - Longitude minutes: 0-59.9999, decimals allowed\n * - Longitude direction: E or W\n *\n * Total segments: 6 editable\n */\nexport const ddmSegmentConfigs: SegmentConfig[] = [\n // Latitude degrees\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 90\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '°',\n },\n // Latitude minutes (decimal minutes)\n {\n type: 'numeric',\n placeholder: '00.0000',\n allowedChars: '[0-9\\\\.]',\n maxLength: 7, // Max: 59.9999\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: \"'\",\n },\n // Latitude direction\n {\n type: 'directional',\n placeholder: 'N',\n allowedChars: '[NS]',\n maxLength: 1,\n pad: 0,\n },\n {\n type: 'literal',\n value: GROUP_SEPARATOR,\n },\n // Longitude degrees\n {\n type: 'numeric',\n placeholder: '000',\n allowedChars: '[0-9]',\n maxLength: 3, // Max: 180\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '°',\n },\n // Longitude minutes (decimal minutes)\n {\n type: 'numeric',\n placeholder: '00.0000',\n allowedChars: '[0-9\\\\.]',\n maxLength: 7, // Max: 59.9999\n pad: LAST_PAD,\n },\n {\n type: 'literal',\n value: \"'\",\n },\n // Longitude direction\n {\n type: 'directional',\n placeholder: 'W',\n allowedChars: '[EW]',\n maxLength: 1,\n pad: 0,\n },\n];\n\n/**\n * DMS (Degrees Minutes Seconds) Segment Configuration\n *\n * Format: [lat_deg]° [lat_min]' [lat_sec]\" [lat_dir], [lon_deg]° [lon_min]' [lon_sec]\" [lon_dir]\n * Example: 89° 45' 55.56\" N, 123° 27' 24.44\" W\n *\n * Segments:\n * - Latitude degrees: 0-90, whole number only (no decimals)\n * - Latitude minutes: 0-59, whole number only (no decimals)\n * - Latitude seconds: 0-59.999, decimals allowed\n * - Latitude direction: N or S\n * - Longitude degrees: 0-180, whole number only (no decimals)\n * - Longitude minutes: 0-59, whole number only (no decimals)\n * - Longitude seconds: 0-59.999, decimals allowed\n * - Longitude direction: E or W\n *\n * Total segments: 8 editable\n */\nexport const dmsSegmentConfigs: SegmentConfig[] = [\n // Latitude degrees\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 90\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '°',\n },\n // Latitude minutes (whole number)\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 59\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: \"'\",\n },\n // Latitude seconds (decimal seconds)\n {\n type: 'numeric',\n placeholder: '00.00',\n allowedChars: '[0-9\\\\.]',\n maxLength: 5, // Max: 59.99\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '\"',\n },\n // Latitude direction\n {\n type: 'directional',\n placeholder: 'N',\n allowedChars: '[NS]',\n maxLength: 1,\n pad: 0,\n },\n {\n type: 'literal',\n value: GROUP_SEPARATOR,\n },\n // Longitude degrees\n {\n type: 'numeric',\n placeholder: '000',\n allowedChars: '[0-9]',\n maxLength: 3, // Max: 180\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '°',\n },\n // Longitude minutes (whole number)\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 59\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: \"'\",\n },\n // Longitude seconds (decimal seconds)\n {\n type: 'numeric',\n placeholder: '00.00',\n allowedChars: '[0-9\\\\.]',\n maxLength: 5, // Max: 59.99\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: '\"',\n },\n // Longitude direction\n {\n type: 'directional',\n placeholder: 'W',\n allowedChars: '[EW]',\n maxLength: 1,\n pad: 0,\n },\n];\n\n/**\n * MGRS (Military Grid Reference System) Segment Configuration\n *\n * Format: [zone][band] [grid_100km] [easting] [northing]\n * Example: 18T WM 12345 67890\n *\n * Segments:\n * - Zone: 1-60, 2 digits\n * - Band: C-X (excluding I and O), 1 letter\n * - Grid 100km: 2 letters (A-Z excluding I and O)\n * - Easting: 5 digits (can be 1-5 based on precision)\n * - Northing: 5 digits (can be 1-5 based on precision)\n *\n * Total segments: 5 editable\n *\n * Reference: /packages/geo/src/coordinates/mgrs/parser.ts\n * Pattern: /^((?:..?)?)(\\w?)\\s*((?:\\w{2})?)\\s*(?:(\\d+(?:\\.\\d*)?)?)\\s*(?:(\\d+(?:\\.\\d*)?)?)$/i\n */\nexport const mgrsSegmentConfigs: SegmentConfig[] = [\n // Zone (1-60)\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 60\n pad: NUMERIC_PAD,\n },\n // Band (C-X, excluding I and O)\n {\n type: 'alphanumeric',\n placeholder: 'T',\n allowedChars: '[C-HJ-NP-X]', // Excludes I and O\n maxLength: 1,\n pad: 0,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Grid 100km identifier (2 letters, A-Z excluding I and O)\n {\n type: 'alphanumeric',\n placeholder: 'WM',\n allowedChars: '[A-HJ-NP-Z]', // Excludes I and O\n maxLength: 2,\n pad: 0,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Easting (5 digits, can be 1-5 based on precision)\n {\n type: 'numeric',\n placeholder: '00000',\n allowedChars: '[0-9]',\n maxLength: 5,\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Northing (5 digits, can be 1-5 based on precision)\n {\n type: 'numeric',\n placeholder: '00000',\n allowedChars: '[0-9]',\n maxLength: 5,\n pad: LAST_PAD,\n },\n];\n\n/**\n * UTM (Universal Transverse Mercator) Segment Configuration\n *\n * Format: [zone][hemisphere] [easting] [northing]\n * Example: 18N 585628 4511644\n *\n * Segments:\n * - Zone: 1-60, 2 digits\n * - Hemisphere: N or S, 1 letter\n * - Easting: 6-7 digits\n * - Northing: 7 digits\n *\n * Total segments: 4 editable\n *\n * Reference: /packages/geo/src/coordinates/utm/parser.ts\n * Pattern: /^((?:..)?)\\s*(\\w?)\\s*(?:(\\d+(?:\\.\\d*)?)?)\\s*(?:(\\d+(?:\\.\\d*)?)?)$/i\n */\nexport const utmSegmentConfigs: SegmentConfig[] = [\n // Zone (1-60)\n {\n type: 'numeric',\n placeholder: '00',\n allowedChars: '[0-9]',\n maxLength: 2, // Max: 60\n pad: NUMERIC_PAD,\n },\n // Hemisphere (N or S)\n {\n type: 'directional',\n placeholder: 'N',\n allowedChars: '[NS]',\n maxLength: 1,\n pad: 0,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Easting (6-7 digits)\n {\n type: 'numeric',\n placeholder: '000000',\n allowedChars: '[0-9]',\n maxLength: 7,\n pad: NUMERIC_PAD,\n },\n {\n type: 'literal',\n value: ' ',\n },\n // Northing (7 digits)\n {\n type: 'numeric',\n placeholder: '0000000',\n allowedChars: '[0-9]',\n maxLength: 7,\n pad: LAST_PAD,\n },\n];\n\n/**\n * Get segment configurations for a specific coordinate system\n *\n * @param format - The coordinate system format\n * @returns Array of segment configurations for the specified format\n */\nexport function getSegmentConfigs(format: CoordinateSystem): SegmentConfig[] {\n switch (format) {\n case 'dd':\n return ddSegmentConfigs;\n case 'ddm':\n return ddmSegmentConfigs;\n case 'dms':\n return dmsSegmentConfigs;\n case 'mgrs':\n return mgrsSegmentConfigs;\n case 'utm':\n return utmSegmentConfigs;\n default:\n // Default to DD format if unknown format provided\n return ddSegmentConfigs;\n }\n}\n\n/**\n * Get format description with example\n *\n * Provides a user-friendly description of the coordinate format with an example value.\n * These descriptions can be used as helper text to guide users on the expected format.\n *\n * @param format - The coordinate system format\n * @returns Description string with format example\n */\nexport function getFormatDescription(format: CoordinateSystem): string {\n switch (format) {\n case 'dd':\n return 'Example: 40.7128, -74.0060 (New York City)';\n case 'ddm':\n return \"Example: 40° 42.768' N, 74° 0.360' W (New York City)\";\n case 'dms':\n return 'Example: 40° 42\\' 46.08\" N, 74° 0\\' 21.60\" W (New York City)';\n case 'mgrs':\n return 'Example: 18T WL 80654 06346 (New York City)';\n case 'utm':\n return 'Example: 18N 585628 4511644 (New York City)';\n default:\n return '';\n }\n}\n\n/**\n * Get editable segment count for a format\n *\n * Returns the number of editable segments (excluding literal separators) for each format.\n * This is useful for initializing segment values and validation.\n *\n * @param format - The coordinate system format\n * @returns Number of editable segments\n */\nexport function getEditableSegmentCount(format: CoordinateSystem): number {\n const configs = getSegmentConfigs(format);\n return configs.filter((config) => config.type !== 'literal').length;\n}\n\n/**\n * Validate segment count for each format\n *\n * Expected editable segment counts:\n * - DD: 2 segments (lat, lon)\n * - DDM: 6 segments (lat_deg, lat_min, lat_dir, lon_deg, lon_min, lon_dir)\n * - DMS: 8 segments (lat_deg, lat_min, lat_sec, lat_dir, lon_deg, lon_min, lon_sec, lon_dir)\n * - MGRS: 5 segments (zone, band, grid, easting, northing)\n * - UTM: 4 segments (zone, hemisphere, easting, northing)\n */\nexport const EXPECTED_SEGMENT_COUNTS: Record<CoordinateSystem, number> = {\n dd: 2,\n ddm: 6,\n dms: 8,\n mgrs: 5,\n utm: 4,\n};\n\n/**\n * Get semantic accessibility label for a segment based on format and editable index\n *\n * Provides descriptive labels for screen readers (e.g., \"Latitude degrees\", \"Longitude minutes\")\n * to improve accessibility beyond generic \"Coordinate segment 1\" announcements.\n *\n * @param format - The coordinate system format\n * @param editableIndex - The index of the editable segment (0-based, excluding literals)\n * @returns Semantic label string for the segment\n */\nexport function getSegmentLabel(\n format: CoordinateSystem,\n editableIndex: number,\n): string {\n switch (format) {\n case 'dd':\n // DD: [lat, lon]\n return editableIndex === 0 ? 'Latitude' : 'Longitude';\n\n case 'ddm':\n // DDM: [lat_deg, lat_min, lat_dir, lon_deg, lon_min, lon_dir]\n switch (editableIndex) {\n case 0:\n return 'Latitude degrees';\n case 1:\n return 'Latitude minutes';\n case 2:\n return 'Latitude direction';\n case 3:\n return 'Longitude degrees';\n case 4:\n return 'Longitude minutes';\n case 5:\n return 'Longitude direction';\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n\n case 'dms':\n // DMS: [lat_deg, lat_min, lat_sec, lat_dir, lon_deg, lon_min, lon_sec, lon_dir]\n switch (editableIndex) {\n case 0:\n return 'Latitude degrees';\n case 1:\n return 'Latitude minutes';\n case 2:\n return 'Latitude seconds';\n case 3:\n return 'Latitude direction';\n case 4:\n return 'Longitude degrees';\n case 5:\n return 'Longitude minutes';\n case 6:\n return 'Longitude seconds';\n case 7:\n return 'Longitude direction';\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n\n case 'mgrs':\n // MGRS: [zone, band, grid, easting, northing]\n switch (editableIndex) {\n case 0:\n return 'MGRS zone';\n case 1:\n return 'MGRS band';\n case 2:\n return 'MGRS grid square';\n case 3:\n return 'MGRS easting';\n case 4:\n return 'MGRS northing';\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n\n case 'utm':\n // UTM: [zone, hemisphere, easting, northing]\n switch (editableIndex) {\n case 0:\n return 'UTM zone';\n case 1:\n return 'UTM hemisphere';\n case 2:\n return 'UTM easting';\n case 3:\n return 'UTM northing';\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n\n default:\n return `Coordinate segment ${editableIndex + 1}`;\n }\n}\n"]}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
@reference '
|
|
13
|
+
@reference '@accelint/design-foundation/styles';
|
|
14
14
|
|
|
15
15
|
@layer components.l1 {
|
|
16
16
|
.field {
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
.control {
|
|
21
|
-
@apply fg-primary-bold gap-m rounded-medium px-s py-xs font-display outline-interactive flex w-
|
|
21
|
+
@apply fg-primary-bold gap-m rounded-medium px-s py-xs font-display outline-interactive flex w-full items-center outline;
|
|
22
|
+
|
|
23
|
+
min-width: var(--min-width, unset);
|
|
22
24
|
|
|
23
25
|
@variant group-size-medium/coordinate-field {
|
|
24
26
|
@apply text-body-m;
|
|
@@ -42,7 +44,19 @@
|
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
.input {
|
|
45
|
-
@apply
|
|
47
|
+
@apply flex items-center;
|
|
48
|
+
|
|
49
|
+
&.inline {
|
|
50
|
+
@apply w-full flex-row;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&.stacked {
|
|
54
|
+
@apply w-full flex-col items-end;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.literal {
|
|
59
|
+
@apply fg-primary-muted pr-xs;
|
|
46
60
|
}
|
|
47
61
|
|
|
48
62
|
.segment {
|
|
@@ -61,6 +75,14 @@
|
|
|
61
75
|
}
|
|
62
76
|
}
|
|
63
77
|
|
|
78
|
+
.segmentGroup {
|
|
79
|
+
@apply w-full;
|
|
80
|
+
|
|
81
|
+
&.stacked {
|
|
82
|
+
@apply w-full text-right;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
64
86
|
.description {
|
|
65
87
|
@apply fg-primary-muted text-body-xs;
|
|
66
88
|
|
|
@@ -77,6 +77,8 @@ type CoordinateFieldState = {
|
|
|
77
77
|
isRequired: boolean;
|
|
78
78
|
/** Size variant of the field */
|
|
79
79
|
size: CoordinateFieldProps['size'];
|
|
80
|
+
/** Whether or not the logical coordinate fields are inlined or stacked */
|
|
81
|
+
variant: CoordinateFieldProps['variant'];
|
|
80
82
|
/** Function to register timeouts for cleanup on unmount */
|
|
81
83
|
registerTimeout: (timeoutId: NodeJS.Timeout) => void;
|
|
82
84
|
};
|
|
@@ -172,6 +174,11 @@ type CoordinateFieldProps = Omit<TextFieldProps, 'children' | 'className' | 'pla
|
|
|
172
174
|
* - CoordinateValue: controlled mode with valid value
|
|
173
175
|
*/
|
|
174
176
|
value?: CoordinateValue | null;
|
|
177
|
+
/**
|
|
178
|
+
* Whether or not the input is stacked or inline
|
|
179
|
+
* @default 'inline'
|
|
180
|
+
*/
|
|
181
|
+
variant?: 'inline' | 'stacked';
|
|
175
182
|
/**
|
|
176
183
|
* Default uncontrolled value in Decimal Degrees format
|
|
177
184
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/coordinate-field/types.ts"],"names":["COORDINATE_FORMAT_LABELS","COORDINATE_FORMAT_NAMES","COORDINATE_SYSTEMS"],"mappings":"AAgCO,MAAMA,CAAAA,CAA6D,CACxE,EAAA,CAAI,IAAA,CACJ,IAAK,KAAA,CACL,GAAA,CAAK,KAAA,CACL,IAAA,CAAM,MAAA,CACN,GAAA,CAAK,KACP,CAAA,CAKaC,EAA4D,CACvE,EAAA,CAAI,iBAAA,CACJ,GAAA,CAAK,yBAAA,CACL,GAAA,CAAK,yBAAA,CACL,IAAA,CAAM,iCACN,GAAA,CAAK,+BACP,CAAA,CAMaC,CAAAA,CAAkD,CAC7D,IAAA,CACA,KAAA,CACA,KAAA,CACA,OACA,KACF","file":"types.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type {\n Dispatch,\n KeyboardEvent,\n RefAttributes,\n SetStateAction,\n} from 'react';\nimport type {\n TextFieldProps as AriaTextFieldProps,\n FieldErrorProps,\n LabelProps,\n} from 'react-aria-components';\n\n/**\n * Supported coordinate systems for display and input\n */\nexport type CoordinateSystem = 'dd' | 'ddm' | 'dms' | 'mgrs' | 'utm';\n\n/**\n * Short labels for coordinate formats (used in popover)\n */\nexport const COORDINATE_FORMAT_LABELS: Record<CoordinateSystem, string> = {\n dd: 'DD',\n ddm: 'DDM',\n dms: 'DMS',\n mgrs: 'MGRS',\n utm: 'UTM',\n};\n\n/**\n * Full names for coordinate formats (used in popover titles/descriptions)\n */\nexport const COORDINATE_FORMAT_NAMES: Record<CoordinateSystem, string> = {\n dd: 'Decimal Degrees',\n ddm: 'Degrees Decimal Minutes',\n dms: 'Degrees Minutes Seconds',\n mgrs: 'Military Grid Reference System',\n utm: 'Universal Transverse Mercator',\n};\n\n/**\n * All supported coordinate systems\n * Use this constant instead of hardcoding the array in multiple places\n */\nexport const COORDINATE_SYSTEMS: readonly CoordinateSystem[] = [\n 'dd',\n 'dms',\n 'ddm',\n 'mgrs',\n 'utm',\n] as const;\n\n/**\n * Coordinate value in Decimal Degrees format (internal representation)\n * All coordinate values are normalized to this format internally\n */\nexport type CoordinateValue = {\n lat: number; // Latitude in decimal degrees (-90 to 90)\n lon: number; // Longitude in decimal degrees (-180 to 180)\n};\n\n/**\n * Types of segments in a coordinate input\n */\nexport type SegmentType =\n | 'numeric'\n | 'directional'\n | 'literal'\n | 'alphanumeric';\n\n/**\n * Configuration for a single coordinate segment\n */\nexport type SegmentConfig = {\n type: SegmentType;\n /** Placeholder text shown when segment is empty */\n placeholder?: string;\n /** Maximum character length for the segment */\n maxLength?: number;\n /** Regex pattern for allowed characters */\n allowedChars?: string;\n /** Fixed value for literal segments (e.g., \", \" or \"º\") */\n value?: string;\n /** Padding in CSS 'ch' units to add to the segment width (defaults to 0.5 if not specified) */\n pad?: number;\n};\n\n/**\n * Result of parsing a pasted coordinate string\n */\nexport type ParsedCoordinateMatch = {\n /** The coordinate system format that matched */\n format: CoordinateSystem;\n /** The coordinate value in DD format */\n value: CoordinateValue;\n /** Display string in the matched format */\n displayString: string;\n};\n\n/**\n * State shared with child components through context\n */\nexport type CoordinateFieldState = {\n segmentValues: string[];\n format: CoordinateFieldProps['format'];\n /**\n * Current coordinate value in DD format\n * - undefined: uncontrolled mode with no default value\n * - null: controlled mode with empty/invalid value\n * - CoordinateValue: valid coordinate\n */\n currentValue?: CoordinateValue | null;\n /** Validation errors from @accelint/geo */\n validationErrors: string[];\n isDisabled: boolean;\n isInvalid: boolean;\n isRequired: boolean;\n /** Size variant of the field */\n size: CoordinateFieldProps['size'];\n /** Function to register timeouts for cleanup on unmount */\n registerTimeout: (timeoutId: NodeJS.Timeout) => void;\n};\n\n/**\n * Props for the CoordinateSegment component\n */\nexport type CoordinateSegmentProps = {\n /** Current value of the segment */\n value: string;\n /** Callback when the segment value changes */\n onChange: (value: string) => void;\n /** Callback when the segment receives focus */\n onFocus?: () => void;\n /** Callback when the segment loses focus */\n onBlur?: () => void;\n /** Callback for keyboard events (used for navigation between segments) */\n onKeyDown?: (e: KeyboardEvent<HTMLInputElement>) => void;\n /** Placeholder text to display when segment is empty */\n placeholder?: string;\n /** Maximum character length for the segment */\n maxLength?: number;\n /** Custom className for styling */\n className?: string;\n /** Whether the segment is disabled */\n isDisabled?: boolean;\n /** Regex pattern for allowed characters (e.g., \"[0-9\\\\-\\\\.]\" for numeric, \"[NSEW]\" for directional) */\n allowedChars?: string;\n /** Ref to the input element for programmatic focus management */\n segmentRef?: React.RefObject<HTMLInputElement>;\n /** Index of this segment in the parent field (for accessibility) */\n segmentIndex?: number;\n /** Total number of segments (for accessibility) */\n totalSegments?: number;\n /** Callback to trigger auto-advance to next segment */\n onAutoAdvance?: () => void;\n /** Callback to trigger auto-retreat to previous segment */\n onAutoRetreat?: () => void;\n /** Padding in CSS 'ch' units to add to the segment width (defaults to 0.5 if not specified) */\n pad?: number;\n /** Semantic accessibility label for the segment (e.g., \"Latitude degrees\") */\n ariaLabel?: string;\n};\n\n/**\n * Props for the CoordinateField component\n *\n * Extends AriaTextFieldProps to inherit standard form field props (id, isDisabled, isRequired, etc.)\n */\nexport type CoordinateFieldProps = Omit<\n AriaTextFieldProps,\n | 'children'\n | 'className'\n | 'placeholder'\n | 'type'\n | 'pattern'\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'name' // Not applicable to multi-segment fields\n> &\n RefAttributes<HTMLDivElement> & {\n /**\n * Custom class names for component slots\n */\n classNames?: {\n field?: string;\n label?: LabelProps['className'];\n control?: string;\n input?: string;\n segment?: string;\n description?: string;\n error?: FieldErrorProps['className'];\n formatButton?: string;\n };\n\n /**\n * Label text displayed above the input (medium size only)\n */\n label?: string;\n\n /**\n * Helper text displayed below the input\n */\n description?: string;\n\n /**\n * Error message to display when the field is invalid\n */\n errorMessage?: string;\n\n /**\n * Display format for coordinate input\n * @default 'dd' (Decimal Degrees)\n */\n format?: CoordinateSystem;\n\n /**\n * Size variant of the field\n * @default 'medium'\n */\n size?: 'small' | 'medium';\n\n /**\n * Whether to show the format button for copying coordinates in different formats\n * @default true\n */\n showFormatButton?: boolean;\n\n /**\n * Controlled value in Decimal Degrees format\n * - undefined: uncontrolled mode\n * - null: controlled mode with no/invalid value\n * - CoordinateValue: controlled mode with valid value\n */\n value?: CoordinateValue | null;\n\n /**\n * Default uncontrolled value in Decimal Degrees format\n */\n defaultValue?: CoordinateValue;\n\n /**\n * Callback fired when the coordinate value changes\n * @param value - The new coordinate value in DD format, or null if invalid\n */\n onChange?:\n | Dispatch<SetStateAction<CoordinateValue | null>>\n | ((value: CoordinateValue | null) => void);\n\n /**\n * Callback fired when validation or paste errors occur\n * @param message - Error message (\"Invalid coordinate value\" for validation errors, \"Invalid coordinate format\" for paste errors)\n * @param context - Additional context about the error:\n * - Validation errors: `{ errors: string[], format: string, segments: string[] }`\n * - Paste errors: `{ pastedText: string }`\n */\n onError?: (message: string, context?: Record<string, unknown>) => void;\n };\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/coordinate-field/types.ts"],"names":["COORDINATE_FORMAT_LABELS","COORDINATE_FORMAT_NAMES","COORDINATE_SYSTEMS"],"mappings":"AAgCO,MAAMA,CAAAA,CAA6D,CACxE,EAAA,CAAI,IAAA,CACJ,IAAK,KAAA,CACL,GAAA,CAAK,KAAA,CACL,IAAA,CAAM,MAAA,CACN,GAAA,CAAK,KACP,CAAA,CAKaC,EAA4D,CACvE,EAAA,CAAI,iBAAA,CACJ,GAAA,CAAK,yBAAA,CACL,GAAA,CAAK,yBAAA,CACL,IAAA,CAAM,iCACN,GAAA,CAAK,+BACP,CAAA,CAMaC,CAAAA,CAAkD,CAC7D,IAAA,CACA,KAAA,CACA,KAAA,CACA,OACA,KACF","file":"types.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type {\n Dispatch,\n KeyboardEvent,\n RefAttributes,\n SetStateAction,\n} from 'react';\nimport type {\n TextFieldProps as AriaTextFieldProps,\n FieldErrorProps,\n LabelProps,\n} from 'react-aria-components';\n\n/**\n * Supported coordinate systems for display and input\n */\nexport type CoordinateSystem = 'dd' | 'ddm' | 'dms' | 'mgrs' | 'utm';\n\n/**\n * Short labels for coordinate formats (used in popover)\n */\nexport const COORDINATE_FORMAT_LABELS: Record<CoordinateSystem, string> = {\n dd: 'DD',\n ddm: 'DDM',\n dms: 'DMS',\n mgrs: 'MGRS',\n utm: 'UTM',\n};\n\n/**\n * Full names for coordinate formats (used in popover titles/descriptions)\n */\nexport const COORDINATE_FORMAT_NAMES: Record<CoordinateSystem, string> = {\n dd: 'Decimal Degrees',\n ddm: 'Degrees Decimal Minutes',\n dms: 'Degrees Minutes Seconds',\n mgrs: 'Military Grid Reference System',\n utm: 'Universal Transverse Mercator',\n};\n\n/**\n * All supported coordinate systems\n * Use this constant instead of hardcoding the array in multiple places\n */\nexport const COORDINATE_SYSTEMS: readonly CoordinateSystem[] = [\n 'dd',\n 'dms',\n 'ddm',\n 'mgrs',\n 'utm',\n] as const;\n\n/**\n * Coordinate value in Decimal Degrees format (internal representation)\n * All coordinate values are normalized to this format internally\n */\nexport type CoordinateValue = {\n lat: number; // Latitude in decimal degrees (-90 to 90)\n lon: number; // Longitude in decimal degrees (-180 to 180)\n};\n\n/**\n * Types of segments in a coordinate input\n */\nexport type SegmentType =\n | 'numeric'\n | 'directional'\n | 'literal'\n | 'alphanumeric';\n\n/**\n * Configuration for a single coordinate segment\n */\nexport type SegmentConfig = {\n type: SegmentType;\n /** Placeholder text shown when segment is empty */\n placeholder?: string;\n /** Maximum character length for the segment */\n maxLength?: number;\n /** Regex pattern for allowed characters */\n allowedChars?: string;\n /** Fixed value for literal segments (e.g., \", \" or \"º\") */\n value?: string;\n /** Padding in CSS 'ch' units to add to the segment width (defaults to 0.5 if not specified) */\n pad?: number;\n};\n\n/**\n * Result of parsing a pasted coordinate string\n */\nexport type ParsedCoordinateMatch = {\n /** The coordinate system format that matched */\n format: CoordinateSystem;\n /** The coordinate value in DD format */\n value: CoordinateValue;\n /** Display string in the matched format */\n displayString: string;\n};\n\n/**\n * State shared with child components through context\n */\nexport type CoordinateFieldState = {\n segmentValues: string[];\n format: CoordinateFieldProps['format'];\n /**\n * Current coordinate value in DD format\n * - undefined: uncontrolled mode with no default value\n * - null: controlled mode with empty/invalid value\n * - CoordinateValue: valid coordinate\n */\n currentValue?: CoordinateValue | null;\n /** Validation errors from @accelint/geo */\n validationErrors: string[];\n isDisabled: boolean;\n isInvalid: boolean;\n isRequired: boolean;\n /** Size variant of the field */\n size: CoordinateFieldProps['size'];\n /** Whether or not the logical coordinate fields are inlined or stacked */\n variant: CoordinateFieldProps['variant'];\n /** Function to register timeouts for cleanup on unmount */\n registerTimeout: (timeoutId: NodeJS.Timeout) => void;\n};\n\n/**\n * Props for the CoordinateSegment component\n */\nexport type CoordinateSegmentProps = {\n /** Current value of the segment */\n value: string;\n /** Callback when the segment value changes */\n onChange: (value: string) => void;\n /** Callback when the segment receives focus */\n onFocus?: () => void;\n /** Callback when the segment loses focus */\n onBlur?: () => void;\n /** Callback for keyboard events (used for navigation between segments) */\n onKeyDown?: (e: KeyboardEvent<HTMLInputElement>) => void;\n /** Placeholder text to display when segment is empty */\n placeholder?: string;\n /** Maximum character length for the segment */\n maxLength?: number;\n /** Custom className for styling */\n className?: string;\n /** Whether the segment is disabled */\n isDisabled?: boolean;\n /** Regex pattern for allowed characters (e.g., \"[0-9\\\\-\\\\.]\" for numeric, \"[NSEW]\" for directional) */\n allowedChars?: string;\n /** Ref to the input element for programmatic focus management */\n segmentRef?: React.RefObject<HTMLInputElement>;\n /** Index of this segment in the parent field (for accessibility) */\n segmentIndex?: number;\n /** Total number of segments (for accessibility) */\n totalSegments?: number;\n /** Callback to trigger auto-advance to next segment */\n onAutoAdvance?: () => void;\n /** Callback to trigger auto-retreat to previous segment */\n onAutoRetreat?: () => void;\n /** Padding in CSS 'ch' units to add to the segment width (defaults to 0.5 if not specified) */\n pad?: number;\n /** Semantic accessibility label for the segment (e.g., \"Latitude degrees\") */\n ariaLabel?: string;\n};\n\n/**\n * Props for the CoordinateField component\n *\n * Extends AriaTextFieldProps to inherit standard form field props (id, isDisabled, isRequired, etc.)\n */\nexport type CoordinateFieldProps = Omit<\n AriaTextFieldProps,\n | 'children'\n | 'className'\n | 'placeholder'\n | 'type'\n | 'pattern'\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'name' // Not applicable to multi-segment fields\n> &\n RefAttributes<HTMLDivElement> & {\n /**\n * Custom class names for component slots\n */\n classNames?: {\n field?: string;\n label?: LabelProps['className'];\n control?: string;\n input?: string;\n segment?: string;\n description?: string;\n error?: FieldErrorProps['className'];\n formatButton?: string;\n };\n\n /**\n * Label text displayed above the input (medium size only)\n */\n label?: string;\n\n /**\n * Helper text displayed below the input\n */\n description?: string;\n\n /**\n * Error message to display when the field is invalid\n */\n errorMessage?: string;\n\n /**\n * Display format for coordinate input\n * @default 'dd' (Decimal Degrees)\n */\n format?: CoordinateSystem;\n\n /**\n * Size variant of the field\n * @default 'medium'\n */\n size?: 'small' | 'medium';\n\n /**\n * Whether to show the format button for copying coordinates in different formats\n * @default true\n */\n showFormatButton?: boolean;\n\n /**\n * Controlled value in Decimal Degrees format\n * - undefined: uncontrolled mode\n * - null: controlled mode with no/invalid value\n * - CoordinateValue: controlled mode with valid value\n */\n value?: CoordinateValue | null;\n\n /**\n * Whether or not the input is stacked or inline\n * @default 'inline'\n */\n variant?: 'inline' | 'stacked';\n\n /**\n * Default uncontrolled value in Decimal Degrees format\n */\n defaultValue?: CoordinateValue;\n\n /**\n * Callback fired when the coordinate value changes\n * @param value - The new coordinate value in DD format, or null if invalid\n */\n onChange?:\n | Dispatch<SetStateAction<CoordinateValue | null>>\n | ((value: CoordinateValue | null) => void);\n\n /**\n * Callback fired when validation or paste errors occur\n * @param message - Error message (\"Invalid coordinate value\" for validation errors, \"Invalid coordinate format\" for paste errors)\n * @param context - Additional context about the error:\n * - Validation errors: `{ errors: string[], format: string, segments: string[] }`\n * - Paste errors: `{ pastedText: string }`\n */\n onError?: (message: string, context?: Record<string, unknown>) => void;\n };\n"]}
|
|
@@ -16,14 +16,15 @@ declare const FORMAT_BUTTON_WIDTH = 3.5;
|
|
|
16
16
|
/** Gap between input and button (gap-m = 1rem = ~1ch) */
|
|
17
17
|
declare const INPUT_BUTTON_GAP = 1.5;
|
|
18
18
|
/**
|
|
19
|
-
* Calculates the
|
|
19
|
+
* Calculates the minimum width needed for the coordinate field control container.
|
|
20
20
|
* This keeps the outlined container at a fixed width while segments animate.
|
|
21
21
|
*
|
|
22
|
+
* @private
|
|
22
23
|
* @param editableSegmentConfigs - Array of editable segment configurations
|
|
23
24
|
* @param segmentConfigs - Array of all segment configurations (including literals)
|
|
24
25
|
* @param showFormatButton - Whether the format button is displayed
|
|
25
26
|
* @returns The calculated width as a CSS string (e.g., "25ch")
|
|
26
27
|
*/
|
|
27
|
-
declare function
|
|
28
|
+
declare function calculateMinControlWidth(editableSegmentConfigs: SegmentConfig[], segmentConfigs: SegmentConfig[], showFormatButton: boolean): string;
|
|
28
29
|
|
|
29
|
-
export { CONTAINER_PADDING_WIDTH, FORMAT_BUTTON_WIDTH, INPUT_BUTTON_GAP, SEGMENT_GAP_WIDTH,
|
|
30
|
+
export { CONTAINER_PADDING_WIDTH, FORMAT_BUTTON_WIDTH, INPUT_BUTTON_GAP, SEGMENT_GAP_WIDTH, calculateMinControlWidth };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const s=.5,l=2,I=3.5,W=1.5;function u(T,e,o){const c=T.reduce((t,n)=>{const N=n.maxLength||0,d=n.pad??.5;return t+N+d},0),
|
|
1
|
+
const s=.5,l=2,I=3.5,W=1.5;function u(T,e,o){const c=T.reduce((t,n)=>{const N=n.maxLength||0,d=n.pad??.5;return t+N+d},0),i=e.filter(t=>t.type==="literal").reduce((t,n)=>t+(n.value?.length||0),0),p=Math.max(0,e.length-1)*.5,r=2,a=o?3.5:0,_=o?1.5:0;return `${c+i+p+r+a+_}ch`}export{l as CONTAINER_PADDING_WIDTH,I as FORMAT_BUTTON_WIDTH,W as INPUT_BUTTON_GAP,s as SEGMENT_GAP_WIDTH,u as calculateMinControlWidth};//# sourceMappingURL=width-utils.js.map
|
|
2
2
|
//# sourceMappingURL=width-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/coordinate-field/width-utils.ts"],"names":["SEGMENT_GAP_WIDTH","CONTAINER_PADDING_WIDTH","FORMAT_BUTTON_WIDTH","INPUT_BUTTON_GAP","
|
|
1
|
+
{"version":3,"sources":["../../../src/components/coordinate-field/width-utils.ts"],"names":["SEGMENT_GAP_WIDTH","CONTAINER_PADDING_WIDTH","FORMAT_BUTTON_WIDTH","INPUT_BUTTON_GAP","calculateMinControlWidth","editableSegmentConfigs","segmentConfigs","showFormatButton","segmentWidth","sum","config","maxLen","padding","literalWidth","c","gapWidth","paddingWidth","buttonWidth","inputButtonGap"],"mappings":"AAsBO,MAAMA,EAAoB,EAAA,CAGpBC,CAAAA,CAA0B,EAG1BC,CAAAA,CAAsB,GAAA,CAGtBC,EAAmB,IAYzB,SAASC,CAAAA,CACdC,CAAAA,CACAC,EACAC,CAAAA,CACQ,CAER,MAAMC,CAAAA,CAAeH,CAAAA,CAAuB,OAAO,CAACI,CAAAA,CAAKC,CAAAA,GAAW,CAClE,MAAMC,CAAAA,CAASD,CAAAA,CAAO,WAAa,CAAA,CAC7BE,CAAAA,CAAUF,EAAO,GAAA,EAAO,EAAA,CAC9B,OAAOD,CAAAA,CAAME,EAASC,CACxB,CAAA,CAAG,CAAC,CAAA,CAGEC,CAAAA,CAAeP,EAClB,MAAA,CAAQQ,CAAAA,EAAMA,CAAAA,CAAE,IAAA,GAAS,SAAS,CAAA,CAClC,MAAA,CAAO,CAACL,CAAAA,CAAKK,CAAAA,GAAML,GAAOK,CAAAA,CAAE,KAAA,EAAO,MAAA,EAAU,CAAA,CAAA,CAAI,CAAC,CAAA,CAK/CC,CAAAA,CADW,KAAK,GAAA,CAAI,CAAA,CAAGT,EAAe,MAAA,CAAS,CAAC,CAAA,CAC1B,EAAA,CAGtBU,EAAe,CAAA,CAGfC,CAAAA,CAAcV,EAAmB,GAAA,CAAsB,CAAA,CAGvDW,EAAiBX,CAAAA,CAAmB,GAAA,CAAmB,CAAA,CAE7D,OAAO,GAAGC,CAAAA,CAAeK,CAAAA,CAAeE,EAAWC,CAAAA,CAAeC,CAAAA,CAAcC,CAAc,CAAA,EAAA,CAChG","file":"width-utils.js","sourcesContent":["// __private-exports\n/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { SegmentConfig } from './types';\n\n/**\n * Layout spacing constants for coordinate field width calculations.\n * All values are in character widths (ch units) to ensure consistent sizing\n * with monospace coordinate values.\n */\n\n/** Gap spacing between segments (0.5rem = ~0.5ch per gap) */\nexport const SEGMENT_GAP_WIDTH = 0.5;\n\n/** Container padding (px-s = 0.5rem on each side = ~1ch total) */\nexport const CONTAINER_PADDING_WIDTH = 2;\n\n/** Format button width (icon button is roughly 2.5-3ch) */\nexport const FORMAT_BUTTON_WIDTH = 3.5;\n\n/** Gap between input and button (gap-m = 1rem = ~1ch) */\nexport const INPUT_BUTTON_GAP = 1.5;\n\n/**\n * Calculates the minimum width needed for the coordinate field control container.\n * This keeps the outlined container at a fixed width while segments animate.\n *\n * @private\n * @param editableSegmentConfigs - Array of editable segment configurations\n * @param segmentConfigs - Array of all segment configurations (including literals)\n * @param showFormatButton - Whether the format button is displayed\n * @returns The calculated width as a CSS string (e.g., \"25ch\")\n */\nexport function calculateMinControlWidth(\n editableSegmentConfigs: SegmentConfig[],\n segmentConfigs: SegmentConfig[],\n showFormatButton: boolean,\n): string {\n // Sum all editable segment max widths with their padding\n const segmentWidth = editableSegmentConfigs.reduce((sum, config) => {\n const maxLen = config.maxLength || 0;\n const padding = config.pad ?? 0.5;\n return sum + maxLen + padding;\n }, 0);\n\n // Calculate width of literal characters (colons, spaces, etc.)\n const literalWidth = segmentConfigs\n .filter((c) => c.type === 'literal')\n .reduce((sum, c) => sum + (c.value?.length || 0), 0);\n\n // Add gap spacing between segments\n // Number of gaps = number of segments - 1 (minimum 0)\n const gapCount = Math.max(0, segmentConfigs.length - 1);\n const gapWidth = gapCount * SEGMENT_GAP_WIDTH;\n\n // Add container padding\n const paddingWidth = CONTAINER_PADDING_WIDTH;\n\n // Add format button width if shown\n const buttonWidth = showFormatButton ? FORMAT_BUTTON_WIDTH : 0;\n\n // Add gap between input and button if button is shown\n const inputButtonGap = showFormatButton ? INPUT_BUTTON_GAP : 0;\n\n return `${segmentWidth + literalWidth + gapWidth + paddingWidth + buttonWidth + inputButtonGap}ch`;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RefAttributes } from 'react';
|
|
1
|
+
import { RefAttributes, ReactElement } from 'react';
|
|
2
2
|
import { MenuProps as MenuProps$1, PopoverProps, MenuItemProps as MenuItemProps$1, TextProps, MenuSectionProps as MenuSectionProps$1 } from 'react-aria-components';
|
|
3
3
|
import { IconProps } from '../icon/types.js';
|
|
4
4
|
|
|
@@ -25,7 +25,7 @@ type MenuSectionProps<T> = Omit<MenuSectionProps$1<T>, 'className'> & {
|
|
|
25
25
|
section?: MenuSectionProps$1<T>['className'];
|
|
26
26
|
header?: string;
|
|
27
27
|
};
|
|
28
|
-
title?: string;
|
|
28
|
+
title?: string | ReactElement;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export type { MenuItemProps, MenuProps, MenuSectionProps };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {useState,useRef,useMemo,useCallback,useEffect}from'react';import {convertDDToDisplaySegments,areAllSegmentsFilled,validateCoordinateSegments,convertDisplaySegmentsToDD}from'../../components/coordinate-field/coordinate-utils.js';import {getSegmentConfigs}from'../../components/coordinate-field/segment-configs.js';function B({value:o,defaultValue:h,format:n,onChange:b,onError:y,registerTimeout:x}){const[m,I]=useState(h||null),[C,i]=useState([]),l=useRef(null),T=o!==void 0?o:m,s=()=>{l.current&&(clearTimeout(l.current),l.current=null);},a=e=>{o===void 0&&I(e),b?.(e);},S=useMemo(()=>getSegmentConfigs(n),[n]),d=useMemo(()=>S.filter(e=>e.type!=="literal"),[S]),[g,c]=useState(()=>{const e=o!==void 0?o:h;if(!e)return new Array(d.length).fill("");const t=convertDDToDisplaySegments(e,n);return t||new Array(d.length).fill("")}),f=useCallback(e=>{s();const t=e?convertDDToDisplaySegments(e,n):null;c(t||new Array(d.length).fill("")),i([]);},[n,d.length]),D=useRef(n);useEffect(()=>{D.current!==n&&(D.current=n,f(o!==void 0?o:m));},[n,o,m,f]),useEffect(()=>{o!==void 0&&f(o);},[o,f]);const A=e=>{const t=validateCoordinateSegments(e,n);if(t.length>0){i(t),y?.("Invalid coordinate value",{errors:t,format:n,segments:e}),a(null);return}const r=convertDisplaySegmentsToDD(e,n);if(!r){const u="Invalid coordinate value";i([u]),y?.(u,{format:n,segments:e}),a(null);return}i([]),a(r);},U=(e,t)=>{const r=[...g];if(r[e]=t,c(r),areAllSegmentsFilled(r)){s();const u=setTimeout(()=>{A(r),l.current=null;},400);l.current=u,x?.(u);}else s(),i([]),T!==null&&a(null);},w=e=>{s();const t=convertDDToDisplaySegments(e,n);t&&(c(t),i([]),a(e));},M=()=>{l.current&&(s(),areAllSegmentsFilled(g)&&A(g));},P=useMemo(()=>C[0]||null,[C]);return {currentValue:T,segmentValues:g,validationErrors:C,segmentConfigs:S,editableSegmentConfigs:d,handleSegmentChange:U,setSegmentValues:c,setValidationErrors:i,effectiveErrorMessage:P,applyPastedCoordinate:w,flushPendingValidation:M}}export{B as useCoordinateFieldState};//# sourceMappingURL=use-coordinate-field-state.js.map
|
|
1
|
+
import {useState,useRef,useMemo,useCallback,useEffect}from'react';import {convertDDToDisplaySegments,areAllSegmentsFilled,validateCoordinateSegments,convertDisplaySegmentsToDD}from'../../components/coordinate-field/coordinate-utils.js';import {getSegmentConfigs}from'../../components/coordinate-field/segment-configs.js';function B({value:o,defaultValue:h,format:n,onChange:b,onError:y,registerTimeout:x}){const[m,I]=useState(h||null),[C,i]=useState([]),l=useRef(null),T=o!==void 0?o:m,s=()=>{l.current&&(clearTimeout(l.current),l.current=null);},a=e=>{o===void 0&&I(e),b?.(e);},S=useMemo(()=>getSegmentConfigs(n),[n]),d=useMemo(()=>S.flat().filter(e=>e.type!=="literal"),[S]),[g,c]=useState(()=>{const e=o!==void 0?o:h;if(!e)return new Array(d.length).fill("");const t=convertDDToDisplaySegments(e,n);return t||new Array(d.length).fill("")}),f=useCallback(e=>{s();const t=e?convertDDToDisplaySegments(e,n):null;c(t||new Array(d.length).fill("")),i([]);},[n,d.length]),D=useRef(n);useEffect(()=>{D.current!==n&&(D.current=n,f(o!==void 0?o:m));},[n,o,m,f]),useEffect(()=>{o!==void 0&&f(o);},[o,f]);const A=e=>{const t=validateCoordinateSegments(e,n);if(t.length>0){i(t),y?.("Invalid coordinate value",{errors:t,format:n,segments:e}),a(null);return}const r=convertDisplaySegmentsToDD(e,n);if(!r){const u="Invalid coordinate value";i([u]),y?.(u,{format:n,segments:e}),a(null);return}i([]),a(r);},U=(e,t)=>{const r=[...g];if(r[e]=t,c(r),areAllSegmentsFilled(r)){s();const u=setTimeout(()=>{A(r),l.current=null;},400);l.current=u,x?.(u);}else s(),i([]),T!==null&&a(null);},w=e=>{s();const t=convertDDToDisplaySegments(e,n);t&&(c(t),i([]),a(e));},M=()=>{l.current&&(s(),areAllSegmentsFilled(g)&&A(g));},P=useMemo(()=>C[0]||null,[C]);return {currentValue:T,segmentValues:g,validationErrors:C,segmentConfigs:S,editableSegmentConfigs:d,handleSegmentChange:U,setSegmentValues:c,setValidationErrors:i,effectiveErrorMessage:P,applyPastedCoordinate:w,flushPendingValidation:M}}export{B as useCoordinateFieldState};//# sourceMappingURL=use-coordinate-field-state.js.map
|
|
2
2
|
//# sourceMappingURL=use-coordinate-field-state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/hooks/coordinate-field/use-coordinate-field-state.ts"],"names":["value","format","onError","internalValue","setInternalValue","defaultValue","p","validationErrors","useState","validationTimeoutRef","useRef","currentValue","handleChange","onChange","newValue","segmentConfigs","getSegmentConfigs","N","editableSegmentConfigs","useMemo","V","config","segmentValues","setSegmentValues","initialValue","segments","convertDDToDisplaySegments","v","convertValueToSegmentsOrClear","useCallback","valueToConvert","clearValidationTimeout","O","useEffect","F","prevFormatRef","validateAndUpdateCoordinate","updatedValues","errors","validateCoordinateSegments","ddValue","convertDisplaySegmentsToDD","k","errorMsg","setValidationErrors","handleSegmentChange","index","areAllSegmentsFilled","R","timeoutId","applyPastedCoordinate","pastedValue","flushPendingValidation","effectiveErrorMessage"],"mappings":"0UA4DE,CAAAA,CAAAA,CACA,KAAA,CAAA,CAAA,CAAA,cACAC,CAAAA,MACA,CAAA,CAAA,CAAA,QACA,CAAA,CAAA,CAAAC,OACA,CAAA,CAAA,CAAA,eAEA,CAAA,CAAM,CAACC,CAAAA,CAAeC,KACpBC,CAAAA,CAAAA,CAAgB,CAAA,CAAA,CAAAC,QAClB,CAAA,CACM,EAACC,IAAyCC,CAAAA,CAAmB,CAAC,CAAC,CAAA,CAC/DC,CAAAA,CAAuBC,SAA8B,EAAA,CAAA,CAAI,CAAA,CAEzDC,MAAAA,CAAeX,IAAU,CAAA,CAAA,CAAA,CAAA,CAAA,GAAYA,MAEZ,CAAA,CAAA,CAAM,CAC/BS,CAAAA,CAAqB,CAAA,IAAA,CAAA,CAAA,CAAA,OACvB,GAAA,YAAkC,CAAA,CAAO,CAAA,OACpB,CAAA,CAAA,CAAA,CAAU,OAI7BG,KAAqD,EACrDZ,CAAAA,CAAAA,CAAAA,CAAU,CAAA,EAAA,CAAA,CAAA,GACZI,MAEFS,EAAAA,CAAWC,CAAQ,CACrB,CAAA,CAEMC,CAAAA,GAAyB,KAAMC,CAAAA,CAAkBf,OAAM,CAAA,IAAWgB,kBAElEC,CAAAA,CAAyBC,CAAAA,CAC7B,CAAA,CAAA,CAAA,CAAMJ,CAAAA,CAAeK,OAAA,CAAA,IAAA,CAAQC,CAAAA,MAAkB,CAAA,CAAA,EAAA,CAAS,CAAA,IAAA,GAAA,SAInDC,CAAAA,CAAeC,CAAgB,CAAA,CAAIf,CAAAA,CAAmB,IAAM,CACjE,CAAAF,QAAA,CAAA,IAAMkB,CAAexB,MAAU,CAAA,CAAA,CAAA,GAAYA,MACvC,CAACwB,CAAAA,CACH,CAAA,CAAA,GAAA,CAAA,CAAO,CAAA,OAAI,IAA6B,KAAA,CAAM,CAAA,CAAE,MAAK,CAAE,CAAA,IAGzD,CAAA,EAAMC,EAAWC,MAA+C,CAChE,CAAAC,0BAAA,CAAA,CAAA,CAAA,CAAA,CAAKF,CAAAA,OACQ,CAAA,EAAA,IAA6B,KAAA,CAAM,CAAA,CAAE,MAAK,CAAE,CAI3D,IAEMG,CAAgCC,EACnCC,CAAAA,CAAAA,CAA2C,CAE1CC,EAAuBC,WAAA,CAEvB,CAAA,EAAA,CAAA,CAAA,EAAMP,CAAWK,MAC8B7B,CAAM,CAAA,CACjD,CAAA0B,0BAAA,CAAA,CAAA,CAEJJ,CAAAA,CACEE,CAAAA,IAAY,CAAA,CAAI,CAAA,CAAA,EAAA,IAA6B,KAAA,CAAM,CAAA,CAAE,MAAK,CAAE,CAC9D,IACoB,CAAC,EACvB,CAAA,CACA,CAACxB,CAAAA,CAAQiB,EAAuB,EAAA,CAAA,CAAA,CAAA,CAAA,CAAM,CACxC,CAAA,MAEmC,EAEnCe,CAAAA,CAAU,CAAAC,MAAA,CAAA,CAAM,CACVC,CAAAA,SAAc,CAAA,IAAA,CAAA,CAAA,CAAA,UACF,CAAA,GAAA,CAAA,CAAUlC,OACDD,CAAU,CAAA,CAAA,CAAA,CAAA,CAAA,GAAYA,MAG9C,CAACC,CAAAA,CAAQD,CAAAA,CAAOG,EAAAA,CAAeyB,CAA6B,CAAC,CAAA,CAEhEK,EAAU,CAAA,CAAA,CAAA,CAAM,CACVjC,eAAU,CAAA,CAAA,GACZ4B,MAED,GAAQA,CAA6B,CAAC,EAAA,CAUzC,CAAA,CAAA,CAAA,CAAA,CAAA,CAAMQ,CAAAA,CAA+BC,MACnC,CAAA,CAAA,CAAA,EAAMC,CAASC,MAAgD,CAE/D,4BAAID,CAAAA,CAAO,CAAA,CAAA,CAAA,GAAA,CAAS,CAAA,OAElBpC,CAAAA,CAAAA,CAAAA,CAAU,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,0BACR,CAAAoC,CAAAA,MACA,CAAA,CAAArC,OACA,CAAA,CAAA,CAAA,QAEW,CAAA,CAAA,CAAI,EACjB,CAAA,CAAA,IACF,CAEA,CAAA,MAAMuC,CAAUC,MAAgD,CAChE,CAAAC,0BAAA,CAAI,CAACF,CAAAA,CAAS,CACZ,CAAA,GAAA,CAAA,CAAMG,EAAW,MAAA,CAAA,CAAA,0BAEjBzC,IAAUyC,CAAAA,CAAU,CAAE,CAAA,CAAA,GAAA,CAAA,CAAA1C,CAAAA,MAAQ,CAAA,CAAA,CAAA,QACjB,CAAA,CAAA,CAAI,CAAA,CACjB,CAAA,CAAA,IACF,CAEA2C,OACAhC,CAAa4B,CAAO,CACtB,EAEMK,CAAAA,CAAsB,CAACC,CAAAA,CAAehC,EAAAA,CAAAA,CAAAA,CAAqB,CAC/D,CAAA,CAAA,CAAA,CAAA,IAAsB,MAAiB,CAIvC,CAAA,CAAA,GAHcgC,CAAK,CAAA,CAAIhC,GACvBS,CAAiBc,CAAa,CAAA,CAE1BU,CAAAA,CAAqBV,CAAa,CAAA,CAAG,CAEvCN,CAAAA,CAAuBiB,oBAAA,CAGvB,CAAA,CAAA,CAAA,CAAA,CAAA,EAAMC,CAAY,kBACYZ,CAAa,IACpB,QAAU,OAC9B,CAAA,KAEH5B,CAAqB,CAAA,GAAA,CAAA,CAAA,CAAA,CAAUwC,OACJ,CAC7B,CAAA,CAAA,CAAA,GAEElB,CAAAA,EAAuB,CAAA,KACD,CAAA,EAClBpB,CAAAA,CAAAA,CAAiB,EAAA,CAAA,CAAA,CAAA,GACN,IAAI,EAGvB,CAEMuC,CAAAA,IAA0D,EAE9DnB,CAAAA,CAAuB,EAEvB,CAAA,EAAA,CAAA,CAAA,EAAMN,CAAWC,MAA8C,CAE3DD,6BACFF,CAAAA,CAAiBE,CAAQ,CAAA,CACzBmB,GAAqB,CAAC,EACtBhC,CAAAA,CAAauC,CAAW,CAAA,EAE5B,CAEMC,CAAAA,CAAyB,CAAA,CAAA,CAAA,EAAM,CAC/B3C,CAAAA,CAAqB,CAAA,IAAA,CAAA,CAAA,CAAA,OAInBsC,MACFX,CAA4Bd,oBAAa,CAAA,CAG/C,CAAA,EAEM+B,CAAwBlC,CAAAA,CAC5B,KAAMZ,CAAAA,CAAiBa,OAAC,CAAA,IAAK,CAAA,CAAA,CAC7B,CAACb,EACH,IAEA,CAAA,CAAA,CAAA,CAAO,CACL,CAAA,OAAA,CAAA,YACA,CAAA,CAAA,CAAA,aACA,CAAA,CAAA,CAAA,gBACA,CAAA,CAAA,CAAA,cACA,CAAA,CAAA,CAAA,4CAEA,CAAA,CAAA,CAAA,gBACA,CAAA,CAAA,CAAA,mBACA,CAAA,CAAA,CAAA,qBACA,CAAA,CAAA,CAAA,qBACA,CAAA,CAAA,CAAA,sBAEJ,CAAA,CAAA,CAAA","file":"use-coordinate-field-state.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n type Dispatch,\n type SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n areAllSegmentsFilled,\n convertDDToDisplaySegments,\n convertDisplaySegmentsToDD,\n validateCoordinateSegments,\n} from '../../components/coordinate-field/coordinate-utils';\nimport { getSegmentConfigs } from '../../components/coordinate-field/segment-configs';\nimport type {\n CoordinateSystem,\n CoordinateValue,\n SegmentConfig,\n} from '../../components/coordinate-field/types';\n\nexport interface UseCoordinateFieldStateOptions {\n value?: CoordinateValue | null;\n defaultValue?: CoordinateValue;\n format: CoordinateSystem;\n onChange?:\n | Dispatch<SetStateAction<CoordinateValue | null>>\n | ((value: CoordinateValue | null) => void);\n onError?: (message: string, context?: Record<string, unknown>) => void;\n registerTimeout?: (timeoutId: NodeJS.Timeout) => void;\n}\n\nexport interface UseCoordinateFieldStateResult {\n currentValue: CoordinateValue | null;\n segmentValues: string[];\n validationErrors: string[];\n segmentConfigs: SegmentConfig[];\n editableSegmentConfigs: SegmentConfig[];\n handleSegmentChange: (index: number, newValue: string) => void;\n setSegmentValues: (values: string[]) => void;\n setValidationErrors: (errors: string[]) => void;\n effectiveErrorMessage: string | null;\n applyPastedCoordinate: (pastedValue: CoordinateValue) => void;\n flushPendingValidation: () => void;\n}\n\nexport function useCoordinateFieldState({\n value,\n defaultValue,\n format,\n onChange,\n onError,\n registerTimeout,\n}: UseCoordinateFieldStateOptions): UseCoordinateFieldStateResult {\n const [internalValue, setInternalValue] = useState<CoordinateValue | null>(\n defaultValue || null,\n );\n const [validationErrors, setValidationErrors] = useState<string[]>([]);\n const validationTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n const currentValue = value !== undefined ? value : internalValue;\n\n const clearValidationTimeout = () => {\n if (validationTimeoutRef.current) {\n clearTimeout(validationTimeoutRef.current);\n validationTimeoutRef.current = null;\n }\n };\n\n const handleChange = (newValue: CoordinateValue | null) => {\n if (value === undefined) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n };\n\n const segmentConfigs = useMemo(() => getSegmentConfigs(format), [format]);\n\n const editableSegmentConfigs = useMemo(\n () => segmentConfigs.filter((config) => config.type !== 'literal'),\n [segmentConfigs],\n );\n\n const [segmentValues, setSegmentValues] = useState<string[]>(() => {\n const initialValue = value !== undefined ? value : defaultValue;\n if (!initialValue) {\n return new Array(editableSegmentConfigs.length).fill('');\n }\n\n const segments = convertDDToDisplaySegments(initialValue, format);\n if (!segments) {\n return new Array(editableSegmentConfigs.length).fill('');\n }\n\n return segments;\n });\n\n const convertValueToSegmentsOrClear = useCallback(\n (valueToConvert: CoordinateValue | null) => {\n // Clear any pending validation when value changes\n clearValidationTimeout();\n\n const segments = valueToConvert\n ? convertDDToDisplaySegments(valueToConvert, format)\n : null;\n\n setSegmentValues(\n segments || new Array(editableSegmentConfigs.length).fill(''),\n );\n setValidationErrors([]);\n },\n [format, editableSegmentConfigs.length],\n );\n\n const prevFormatRef = useRef(format);\n\n useEffect(() => {\n if (prevFormatRef.current !== format) {\n prevFormatRef.current = format;\n const valueToConvert = value !== undefined ? value : internalValue;\n convertValueToSegmentsOrClear(valueToConvert);\n }\n }, [format, value, internalValue, convertValueToSegmentsOrClear]);\n\n useEffect(() => {\n if (value !== undefined) {\n convertValueToSegmentsOrClear(value);\n }\n }, [value, convertValueToSegmentsOrClear]);\n\n /**\n * Validates segment values and updates the coordinate state\n *\n * When validation fails, calls onError with \"Invalid coordinate value\" message\n * and context containing the detailed validation errors from @accelint/geo.\n *\n * @param updatedValues - Array of segment values to validate\n */\n const validateAndUpdateCoordinate = (updatedValues: string[]) => {\n const errors = validateCoordinateSegments(updatedValues, format);\n\n if (errors.length > 0) {\n setValidationErrors(errors);\n onError?.('Invalid coordinate value', {\n errors,\n format,\n segments: updatedValues,\n });\n handleChange(null);\n return;\n }\n\n const ddValue = convertDisplaySegmentsToDD(updatedValues, format);\n if (!ddValue) {\n const errorMsg = 'Invalid coordinate value';\n setValidationErrors([errorMsg]);\n onError?.(errorMsg, { format, segments: updatedValues });\n handleChange(null);\n return;\n }\n\n setValidationErrors([]);\n handleChange(ddValue);\n };\n\n const handleSegmentChange = (index: number, newValue: string) => {\n const updatedValues = [...segmentValues];\n updatedValues[index] = newValue;\n setSegmentValues(updatedValues);\n\n if (areAllSegmentsFilled(updatedValues)) {\n // Clear any pending validation timeout\n clearValidationTimeout();\n\n // Debounce validation by 400ms when all segments are full\n const timeoutId = setTimeout(() => {\n validateAndUpdateCoordinate(updatedValues);\n validationTimeoutRef.current = null;\n }, 400);\n\n validationTimeoutRef.current = timeoutId;\n registerTimeout?.(timeoutId);\n } else {\n // Clear any pending validation when segments become incomplete\n clearValidationTimeout();\n setValidationErrors([]);\n if (currentValue !== null) {\n handleChange(null);\n }\n }\n };\n\n const applyPastedCoordinate = (pastedValue: CoordinateValue) => {\n // Clear any pending validation when applying pasted coordinate\n clearValidationTimeout();\n\n const segments = convertDDToDisplaySegments(pastedValue, format);\n\n if (segments) {\n setSegmentValues(segments);\n setValidationErrors([]);\n handleChange(pastedValue);\n }\n };\n\n const flushPendingValidation = () => {\n if (validationTimeoutRef.current) {\n clearValidationTimeout();\n\n // Immediately validate if all segments are filled\n if (areAllSegmentsFilled(segmentValues)) {\n validateAndUpdateCoordinate(segmentValues);\n }\n }\n };\n\n const effectiveErrorMessage = useMemo(\n () => validationErrors[0] || null,\n [validationErrors],\n );\n\n return {\n currentValue,\n segmentValues,\n validationErrors,\n segmentConfigs,\n editableSegmentConfigs,\n handleSegmentChange,\n setSegmentValues,\n setValidationErrors,\n effectiveErrorMessage,\n applyPastedCoordinate,\n flushPendingValidation,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/hooks/coordinate-field/use-coordinate-field-state.ts"],"names":["value","format","onError","internalValue","setInternalValue","defaultValue","p","validationErrors","useState","validationTimeoutRef","useRef","currentValue","handleChange","onChange","newValue","segmentConfigs","getSegmentConfigs","N","editableSegmentConfigs","useMemo","V","config","segmentValues","setSegmentValues","initialValue","segments","convertDDToDisplaySegments","v","convertValueToSegmentsOrClear","useCallback","valueToConvert","clearValidationTimeout","O","useEffect","F","prevFormatRef","validateAndUpdateCoordinate","updatedValues","errors","validateCoordinateSegments","ddValue","convertDisplaySegmentsToDD","k","errorMsg","setValidationErrors","handleSegmentChange","index","areAllSegmentsFilled","R","timeoutId","applyPastedCoordinate","pastedValue","flushPendingValidation","effectiveErrorMessage"],"mappings":"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","file":"use-coordinate-field-state.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n type Dispatch,\n type SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n areAllSegmentsFilled,\n convertDDToDisplaySegments,\n convertDisplaySegmentsToDD,\n validateCoordinateSegments,\n} from '../../components/coordinate-field/coordinate-utils';\nimport { getSegmentConfigs } from '../../components/coordinate-field/segment-configs';\nimport type {\n CoordinateSystem,\n CoordinateValue,\n SegmentConfig,\n} from '../../components/coordinate-field/types';\n\nexport interface UseCoordinateFieldStateOptions {\n value?: CoordinateValue | null;\n defaultValue?: CoordinateValue;\n format: CoordinateSystem;\n onChange?:\n | Dispatch<SetStateAction<CoordinateValue | null>>\n | ((value: CoordinateValue | null) => void);\n onError?: (message: string, context?: Record<string, unknown>) => void;\n registerTimeout?: (timeoutId: NodeJS.Timeout) => void;\n}\n\nexport interface UseCoordinateFieldStateResult {\n currentValue: CoordinateValue | null;\n segmentValues: string[];\n validationErrors: string[];\n segmentConfigs: SegmentConfig[];\n editableSegmentConfigs: SegmentConfig[];\n handleSegmentChange: (index: number, newValue: string) => void;\n setSegmentValues: (values: string[]) => void;\n setValidationErrors: (errors: string[]) => void;\n effectiveErrorMessage: string | null;\n applyPastedCoordinate: (pastedValue: CoordinateValue) => void;\n flushPendingValidation: () => void;\n}\n\nexport function useCoordinateFieldState({\n value,\n defaultValue,\n format,\n onChange,\n onError,\n registerTimeout,\n}: UseCoordinateFieldStateOptions): UseCoordinateFieldStateResult {\n const [internalValue, setInternalValue] = useState<CoordinateValue | null>(\n defaultValue || null,\n );\n const [validationErrors, setValidationErrors] = useState<string[]>([]);\n const validationTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n const currentValue = value !== undefined ? value : internalValue;\n\n const clearValidationTimeout = () => {\n if (validationTimeoutRef.current) {\n clearTimeout(validationTimeoutRef.current);\n validationTimeoutRef.current = null;\n }\n };\n\n const handleChange = (newValue: CoordinateValue | null) => {\n if (value === undefined) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n };\n\n const segmentConfigs = useMemo(() => getSegmentConfigs(format), [format]);\n\n const editableSegmentConfigs = useMemo(\n () => segmentConfigs.flat().filter((config) => config.type !== 'literal'),\n [segmentConfigs],\n );\n\n const [segmentValues, setSegmentValues] = useState<string[]>(() => {\n const initialValue = value !== undefined ? value : defaultValue;\n if (!initialValue) {\n return new Array(editableSegmentConfigs.length).fill('');\n }\n\n const segments = convertDDToDisplaySegments(initialValue, format);\n if (!segments) {\n return new Array(editableSegmentConfigs.length).fill('');\n }\n\n return segments;\n });\n\n const convertValueToSegmentsOrClear = useCallback(\n (valueToConvert: CoordinateValue | null) => {\n // Clear any pending validation when value changes\n clearValidationTimeout();\n\n const segments = valueToConvert\n ? convertDDToDisplaySegments(valueToConvert, format)\n : null;\n\n setSegmentValues(\n segments || new Array(editableSegmentConfigs.length).fill(''),\n );\n setValidationErrors([]);\n },\n [format, editableSegmentConfigs.length],\n );\n\n const prevFormatRef = useRef(format);\n\n useEffect(() => {\n if (prevFormatRef.current !== format) {\n prevFormatRef.current = format;\n const valueToConvert = value !== undefined ? value : internalValue;\n convertValueToSegmentsOrClear(valueToConvert);\n }\n }, [format, value, internalValue, convertValueToSegmentsOrClear]);\n\n useEffect(() => {\n if (value !== undefined) {\n convertValueToSegmentsOrClear(value);\n }\n }, [value, convertValueToSegmentsOrClear]);\n\n /**\n * Validates segment values and updates the coordinate state\n *\n * When validation fails, calls onError with \"Invalid coordinate value\" message\n * and context containing the detailed validation errors from @accelint/geo.\n *\n * @param updatedValues - Array of segment values to validate\n */\n const validateAndUpdateCoordinate = (updatedValues: string[]) => {\n const errors = validateCoordinateSegments(updatedValues, format);\n\n if (errors.length > 0) {\n setValidationErrors(errors);\n onError?.('Invalid coordinate value', {\n errors,\n format,\n segments: updatedValues,\n });\n handleChange(null);\n return;\n }\n\n const ddValue = convertDisplaySegmentsToDD(updatedValues, format);\n if (!ddValue) {\n const errorMsg = 'Invalid coordinate value';\n setValidationErrors([errorMsg]);\n onError?.(errorMsg, { format, segments: updatedValues });\n handleChange(null);\n return;\n }\n\n setValidationErrors([]);\n handleChange(ddValue);\n };\n\n const handleSegmentChange = (index: number, newValue: string) => {\n const updatedValues = [...segmentValues];\n updatedValues[index] = newValue;\n setSegmentValues(updatedValues);\n\n if (areAllSegmentsFilled(updatedValues)) {\n // Clear any pending validation timeout\n clearValidationTimeout();\n\n // Debounce validation by 400ms when all segments are full\n const timeoutId = setTimeout(() => {\n validateAndUpdateCoordinate(updatedValues);\n validationTimeoutRef.current = null;\n }, 400);\n\n validationTimeoutRef.current = timeoutId;\n registerTimeout?.(timeoutId);\n } else {\n // Clear any pending validation when segments become incomplete\n clearValidationTimeout();\n setValidationErrors([]);\n if (currentValue !== null) {\n handleChange(null);\n }\n }\n };\n\n const applyPastedCoordinate = (pastedValue: CoordinateValue) => {\n // Clear any pending validation when applying pasted coordinate\n clearValidationTimeout();\n\n const segments = convertDDToDisplaySegments(pastedValue, format);\n\n if (segments) {\n setSegmentValues(segments);\n setValidationErrors([]);\n handleChange(pastedValue);\n }\n };\n\n const flushPendingValidation = () => {\n if (validationTimeoutRef.current) {\n clearValidationTimeout();\n\n // Immediately validate if all segments are filled\n if (areAllSegmentsFilled(segmentValues)) {\n validateAndUpdateCoordinate(segmentValues);\n }\n }\n };\n\n const effectiveErrorMessage = useMemo(\n () => validationErrors[0] || null,\n [validationErrors],\n );\n\n return {\n currentValue,\n segmentValues,\n validationErrors,\n segmentConfigs,\n editableSegmentConfigs,\n handleSegmentChange,\n setSegmentValues,\n setValidationErrors,\n effectiveErrorMessage,\n applyPastedCoordinate,\n flushPendingValidation,\n };\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -47,10 +47,9 @@ export { ComboBoxFieldProps } from './components/combobox-field/types.js';
|
|
|
47
47
|
export { CoordinateFieldContext, CoordinateFieldProvider, CoordinateFieldStateContext, CoordinateFieldStateProvider, useCoordinateFieldStateContext } from './components/coordinate-field/context.js';
|
|
48
48
|
export { COORDINATE_EPSILON, COORDINATE_ERROR_MESSAGES, CoordinateFormatResult, areAllSegmentsFilled, areCoordinatesEqual, convertDDToDisplaySegments, convertDisplaySegmentsToDD, deduplicateMatchesByLocation, formatSegmentsToCoordinateString, getAllCoordinateFormats, hasAnySegmentValue, isCompleteCoordinate, parseCoordinatePaste, parseCoordinateStringToSegments, validateCoordinateSegments } from './components/coordinate-field/coordinate-utils.js';
|
|
49
49
|
export { CoordinateField } from './components/coordinate-field/index.js';
|
|
50
|
-
export { EXPECTED_SEGMENT_COUNTS, ddSegmentConfigs, ddmSegmentConfigs, dmsSegmentConfigs, getEditableSegmentCount, getFormatDescription, getSegmentConfigs, getSegmentLabel, mgrsSegmentConfigs, utmSegmentConfigs } from './components/coordinate-field/segment-configs.js';
|
|
50
|
+
export { EXPECTED_SEGMENT_COUNTS, GROUP_SEPARATOR, ddSegmentConfigs, ddmSegmentConfigs, dmsSegmentConfigs, getEditableSegmentCount, getFormatDescription, getSegmentConfigs, getSegmentLabel, mgrsSegmentConfigs, utmSegmentConfigs } from './components/coordinate-field/segment-configs.js';
|
|
51
51
|
export { CoordinateSegment } from './components/coordinate-field/segment.js';
|
|
52
52
|
export { COORDINATE_FORMAT_LABELS, COORDINATE_FORMAT_NAMES, COORDINATE_SYSTEMS, CoordinateFieldProps, CoordinateFieldState, CoordinateSegmentProps, CoordinateSystem, CoordinateValue, ParsedCoordinateMatch, SegmentConfig, SegmentType } from './components/coordinate-field/types.js';
|
|
53
|
-
export { CONTAINER_PADDING_WIDTH, FORMAT_BUTTON_WIDTH, INPUT_BUTTON_GAP, SEGMENT_GAP_WIDTH, calculateMaxControlWidth } from './components/coordinate-field/width-utils.js';
|
|
54
53
|
export { DateField } from './components/date-field/index.js';
|
|
55
54
|
export { DateFieldProps } from './components/date-field/types.js';
|
|
56
55
|
export { DetailsListContext, DetailsListProvider } from './components/details-list/context.js';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{AccordionContext}from'./components/accordion/context.js';export{AccordionGroup}from'./components/accordion/group.js';export{AccordionHeader}from'./components/accordion/header.js';export{Accordion}from'./components/accordion/index.js';export{AccordionPanel}from'./components/accordion/panel.js';export{AccordionTrigger}from'./components/accordion/trigger.js';export{ActionBar}from'./components/action-bar/index.js';export{AvatarContext,AvatarProvider}from'./components/avatar/context.js';export{Avatar}from'./components/avatar/index.js';export{BadgeContext,BadgeProvider}from'./components/badge/context.js';export{Badge}from'./components/badge/index.js';export{Breadcrumbs}from'./components/breadcrumbs/index.js';export{BreadcrumbItem}from'./components/breadcrumbs/item.js';export{ButtonContext,ButtonProvider,LinkButtonContext,LinkButtonProvider,ToggleButtonContext,ToggleButtonProvider}from'./components/button/context.js';export{Button}from'./components/button/index.js';export{LinkButton}from'./components/button/link.js';export{ToggleButton}from'./components/button/toggle.js';export{CheckboxContext,CheckboxGroupContext}from'./components/checkbox/context.js';export{CheckboxGroup}from'./components/checkbox/group.js';export{Checkbox}from'./components/checkbox/index.js';export{ChipContext,ChipProvider}from'./components/chip/context.js';export{DeletableChip}from'./components/chip/deletable.js';export{Chip}from'./components/chip/index.js';export{ChipList,ChipListRenderingContext}from'./components/chip/list.js';export{SelectableChip}from'./components/chip/selectable.js';export{ClassificationBadgeContext,ClassificationBadgeProvider}from'./components/classification-badge/context.js';export{ClassificationBadge}from'./components/classification-badge/index.js';export{ClassificationBannerContext,ClassificationBannerProvider}from'./components/classification-banner/context.js';export{ClassificationBanner}from'./components/classification-banner/index.js';export{Clock}from'./components/clock/index.js';export{ColorPicker}from'./components/color-picker/index.js';export{ComboBoxFieldContext,ComboBoxFieldProvider}from'./components/combobox-field/context.js';export{ComboBoxField}from'./components/combobox-field/index.js';export{CoordinateFieldContext,CoordinateFieldProvider,CoordinateFieldStateContext,CoordinateFieldStateProvider,useCoordinateFieldStateContext}from'./components/coordinate-field/context.js';export{COORDINATE_EPSILON,COORDINATE_ERROR_MESSAGES,areAllSegmentsFilled,areCoordinatesEqual,convertDDToDisplaySegments,convertDisplaySegmentsToDD,deduplicateMatchesByLocation,formatSegmentsToCoordinateString,getAllCoordinateFormats,hasAnySegmentValue,isCompleteCoordinate,parseCoordinatePaste,parseCoordinateStringToSegments,validateCoordinateSegments}from'./components/coordinate-field/coordinate-utils.js';export{CoordinateField}from'./components/coordinate-field/index.js';export{EXPECTED_SEGMENT_COUNTS,ddSegmentConfigs,ddmSegmentConfigs,dmsSegmentConfigs,getEditableSegmentCount,getFormatDescription,getSegmentConfigs,getSegmentLabel,mgrsSegmentConfigs,utmSegmentConfigs}from'./components/coordinate-field/segment-configs.js';export{CoordinateSegment}from'./components/coordinate-field/segment.js';export{COORDINATE_FORMAT_LABELS,COORDINATE_FORMAT_NAMES,COORDINATE_SYSTEMS}from'./components/coordinate-field/types.js';export{CONTAINER_PADDING_WIDTH,FORMAT_BUTTON_WIDTH,INPUT_BUTTON_GAP,SEGMENT_GAP_WIDTH,calculateMaxControlWidth}from'./components/coordinate-field/width-utils.js';export{DateField}from'./components/date-field/index.js';export{DetailsListContext,DetailsListProvider}from'./components/details-list/context.js';export{DetailsList}from'./components/details-list/index.js';export{DetailsListLabel}from'./components/details-list/label.js';export{DetailsListValue}from'./components/details-list/value.js';export{DialogContent}from'./components/dialog/content.js';export{DialogContext}from'./components/dialog/context.js';export{DialogFooter}from'./components/dialog/footer.js';export{Dialog}from'./components/dialog/index.js';export{DialogTitle}from'./components/dialog/title.js';export{DialogTrigger}from'./components/dialog/trigger.js';export{DividerContext,DividerProvider}from'./components/divider/context.js';export{Divider}from'./components/divider/index.js';export{DrawerBack}from'./components/drawer/back.js';export{DrawerClose}from'./components/drawer/close.js';export{DrawerContent}from'./components/drawer/content.js';export{DrawerContext,DrawerEventHandlers,bus,useDrawerEmit}from'./components/drawer/context.js';export{DrawerEventNamespace,DrawerEventTypes}from'./components/drawer/events.js';export{DrawerFooter}from'./components/drawer/footer.js';export{DrawerHeaderTitle}from'./components/drawer/header-title.js';export{DrawerHeader}from'./components/drawer/header.js';export{Drawer}from'./components/drawer/index.js';export{DrawerLayoutMain}from'./components/drawer/layout-main.js';export{DrawerLayout}from'./components/drawer/layout.js';export{DrawerMenuItem}from'./components/drawer/menu-item.js';export{DrawerMenu}from'./components/drawer/menu.js';export{DrawerPanel}from'./components/drawer/panel.js';export{DrawerTrigger}from'./components/drawer/trigger.js';export{DrawerView}from'./components/drawer/view.js';export{Flashcard,FlashcardAdditionalData,FlashcardContext,FlashcardDetailsLabel,FlashcardDetailsList,FlashcardDetailsValue,FlashcardHero}from'./components/flashcard/index.js';export{HeroContext}from'./components/hero/context.js';export{Hero}from'./components/hero/index.js';export{HeroSubtitle}from'./components/hero/subtitle.js';export{HeroTitle}from'./components/hero/title.js';export{HotkeyContext,HotkeyProvider}from'./components/hotkey/context.js';export{Hotkey}from'./components/hotkey/index.js';export{HotkeySet}from'./components/hotkey/set.js';export{IconContext,IconProvider}from'./components/icon/context.js';export{Icon}from'./components/icon/index.js';export{InputContext}from'./components/input/context.js';export{Input}from'./components/input/index.js';export{KanbanCardBody}from'./components/kanban/card-body.js';export{KanbanCardHeaderActions}from'./components/kanban/card-header-actions.js';export{KanbanCardHeaderTitle}from'./components/kanban/card-header-title.js';export{KanbanCardHeader}from'./components/kanban/card-header.js';export{KanbanCard}from'./components/kanban/card.js';export{KanbanColumnActions}from'./components/kanban/column-actions.js';export{KanbanColumnContainer}from'./components/kanban/column-container.js';export{KanbanColumnContent}from'./components/kanban/column-content.js';export{KanbanColumnHeaderActions}from'./components/kanban/column-header-actions.js';export{KanbanColumnHeaderDragHandle}from'./components/kanban/column-header-drag-handle.js';export{KanbanColumnHeaderTitle}from'./components/kanban/column-header-title.js';export{KanbanColumnHeader}from'./components/kanban/column-header.js';export{KanbanColumn}from'./components/kanban/column.js';export{KanbanProvider,calculateClosestEdge,getInsertIndex,parseDropTarget,useKanban,validateMoveCard}from'./components/kanban/context.js';export{KanbanHeaderActions}from'./components/kanban/header-actions.js';export{KanbanHeaderSearch}from'./components/kanban/header-search.js';export{KanbanHeaderTitle}from'./components/kanban/header-title.js';export{KanbanHeader}from'./components/kanban/header.js';export{DragContext,Kanban,useDragContext}from'./components/kanban/kanban.js';export{columnData}from'./components/kanban/mock-data.js';export{LabelContext,LabelProvider}from'./components/label/context.js';export{Label}from'./components/label/index.js';export{Lines}from'./components/lines/index.js';export{LinkProvider}from'./components/link/context.js';export{Link}from'./components/link/index.js';export{MenuContext}from'./components/menu/context.js';export{Menu}from'./components/menu/index.js';export{MenuItemDescription}from'./components/menu/item-description.js';export{MenuItemLabel}from'./components/menu/item-label.js';export{MenuItem}from'./components/menu/item.js';export{MenuSection}from'./components/menu/section.js';export{MenuSeparator}from'./components/menu/separator.js';export{MenuSubmenu}from'./components/menu/submenu.js';export{MenuTrigger}from'./components/menu/trigger.js';export{NoticeEventNamespace,NoticeEventTypes}from'./components/notice/events.js';export{Notice}from'./components/notice/index.js';export{NoticeList}from'./components/notice/list.js';export{NoticeIcon}from'./components/notice/notice-icon.js';export{matchesMetadata}from'./components/notice/utils.js';export{OptionsContext}from'./components/options/context.js';export{Options}from'./components/options/index.js';export{OptionsItemContent}from'./components/options/item-content.js';export{OptionsItemDescription}from'./components/options/item-description.js';export{OptionsItemLabel}from'./components/options/item-label.js';export{OptionsItem}from'./components/options/item.js';export{OptionsSection}from'./components/options/section.js';export{PaginationContext}from'./components/pagination/context.js';export{Pagination}from'./components/pagination/index.js';export{PaginationNext}from'./components/pagination/next.js';export{PaginationPages}from'./components/pagination/pages.js';export{PaginationPrev}from'./components/pagination/prev.js';export{PopoverContent}from'./components/popover/content.js';export{PopoverFooter}from'./components/popover/footer.js';export{Popover}from'./components/popover/index.js';export{PopoverTitle}from'./components/popover/title.js';export{PopoverTrigger}from'./components/popover/trigger.js';export{CloneAction,LockAction,RemoveRuleAction}from'./components/query-builder/actions.js';export{CombinatorSelector}from'./components/query-builder/combinator-selector.js';export{QueryBuilder}from'./components/query-builder/index.js';export{RadioContext}from'./components/radio/context.js';export{RadioGroup}from'./components/radio/group.js';export{Radio}from'./components/radio/index.js';export{SearchFieldContext,SearchFieldProvider}from'./components/search-field/context.js';export{SearchField}from'./components/search-field/index.js';export{SelectFieldContext,SelectFieldProvider}from'./components/select-field/context.js';export{SelectField}from'./components/select-field/index.js';export{SidenavAvatar}from'./components/sidenav/avatar.js';export{SidenavContent}from'./components/sidenav/content.js';export{SidenavContext}from'./components/sidenav/context.js';export{SidenavEventNamespace,SidenavEventTypes}from'./components/sidenav/events.js';export{SidenavFooter}from'./components/sidenav/footer.js';export{SidenavHeader}from'./components/sidenav/header.js';export{Sidenav}from'./components/sidenav/index.js';export{SidenavItem}from'./components/sidenav/item.js';export{SidenavLink}from'./components/sidenav/link.js';export{SidenavMenuItem}from'./components/sidenav/menu-item.js';export{SidenavMenu}from'./components/sidenav/menu.js';export{SidenavTrigger}from'./components/sidenav/trigger.js';export{Skeleton}from'./components/skeleton/index.js';export{Slider}from'./components/slider/index.js';export{SwitchContext,SwitchProvider}from'./components/switch/context.js';export{Switch}from'./components/switch/index.js';export{HeaderColumnAction,SortDirection,headerColumnActionValues,sortDirectionValues}from'./components/table/constants/table.js';export{TableContext}from'./components/table/context.js';export{Table}from'./components/table/index.js';export{TabsContext,TabsProvider}from'./components/tabs/context.js';export{Tabs}from'./components/tabs/index.js';export{TabList}from'./components/tabs/list.js';export{TabPanel}from'./components/tabs/panel.js';export{Tab}from'./components/tabs/tab.js';export{TextAreaFieldContext,TextAreaFieldProvider}from'./components/text-area-field/context.js';export{TextAreaField}from'./components/text-area-field/index.js';export{TextFieldContext,TextFieldProvider}from'./components/text-field/context.js';export{TextField}from'./components/text-field/index.js';export{TimeField}from'./components/time-field/index.js';export{TooltipContext}from'./components/tooltip/context.js';export{Tooltip}from'./components/tooltip/index.js';export{TooltipTrigger}from'./components/tooltip/trigger.js';export{TreeContext,TreeItemContext}from'./components/tree/context.js';export{Tree}from'./components/tree/index.js';export{TreeItemActions}from'./components/tree/item-actions.js';export{TreeItemContent}from'./components/tree/item-content.js';export{TreeItemDescription}from'./components/tree/item-description.js';export{TreeItemLabel}from'./components/tree/item-label.js';export{TreeItemPrefixIcon}from'./components/tree/item-prefix-icon.js';export{TreeItem}from'./components/tree/item.js';export{TreeLines}from'./components/tree/lines.js';export{ViewStackContext,ViewStackEventHandlers,useViewStackEmit}from'./components/view-stack/context.js';export{ViewStackEventNamespace,ViewStackEventTypes}from'./components/view-stack/events.js';export{ViewStack}from'./components/view-stack/index.js';export{ViewStackTrigger}from'./components/view-stack/trigger.js';export{ViewStackView}from'./components/view-stack/view.js';export{useCoordinateCopy}from'./hooks/coordinate-field/use-coordinate-copy.js';export{useCoordinateFieldState}from'./hooks/coordinate-field/use-coordinate-field-state.js';export{useCoordinateField}from'./hooks/coordinate-field/use-coordinate-field.js';export{useCoordinateFocus}from'./hooks/coordinate-field/use-coordinate-focus.js';export{useCoordinatePaste}from'./hooks/coordinate-field/use-coordinate-paste.js';export{useTimeoutCleanup}from'./hooks/coordinate-field/use-timeout-cleanup.js';export{useCardInteractions,useColumnInteractions}from'./hooks/kanban/index.js';export{useTreeActions}from'./hooks/use-tree/actions/index.js';export{useTreeState}from'./hooks/use-tree/state/index.js';export{isSlottedContextValue}from'./lib/utils.js';export{PortalProvider}from'./providers/portal.js';export{ThemeProvider,useTheme}from'./providers/theme-provider.js';//# sourceMappingURL=index.js.map
|
|
1
|
+
export{AccordionContext}from'./components/accordion/context.js';export{AccordionGroup}from'./components/accordion/group.js';export{AccordionHeader}from'./components/accordion/header.js';export{Accordion}from'./components/accordion/index.js';export{AccordionPanel}from'./components/accordion/panel.js';export{AccordionTrigger}from'./components/accordion/trigger.js';export{ActionBar}from'./components/action-bar/index.js';export{AvatarContext,AvatarProvider}from'./components/avatar/context.js';export{Avatar}from'./components/avatar/index.js';export{BadgeContext,BadgeProvider}from'./components/badge/context.js';export{Badge}from'./components/badge/index.js';export{Breadcrumbs}from'./components/breadcrumbs/index.js';export{BreadcrumbItem}from'./components/breadcrumbs/item.js';export{ButtonContext,ButtonProvider,LinkButtonContext,LinkButtonProvider,ToggleButtonContext,ToggleButtonProvider}from'./components/button/context.js';export{Button}from'./components/button/index.js';export{LinkButton}from'./components/button/link.js';export{ToggleButton}from'./components/button/toggle.js';export{CheckboxContext,CheckboxGroupContext}from'./components/checkbox/context.js';export{CheckboxGroup}from'./components/checkbox/group.js';export{Checkbox}from'./components/checkbox/index.js';export{ChipContext,ChipProvider}from'./components/chip/context.js';export{DeletableChip}from'./components/chip/deletable.js';export{Chip}from'./components/chip/index.js';export{ChipList,ChipListRenderingContext}from'./components/chip/list.js';export{SelectableChip}from'./components/chip/selectable.js';export{ClassificationBadgeContext,ClassificationBadgeProvider}from'./components/classification-badge/context.js';export{ClassificationBadge}from'./components/classification-badge/index.js';export{ClassificationBannerContext,ClassificationBannerProvider}from'./components/classification-banner/context.js';export{ClassificationBanner}from'./components/classification-banner/index.js';export{Clock}from'./components/clock/index.js';export{ColorPicker}from'./components/color-picker/index.js';export{ComboBoxFieldContext,ComboBoxFieldProvider}from'./components/combobox-field/context.js';export{ComboBoxField}from'./components/combobox-field/index.js';export{CoordinateFieldContext,CoordinateFieldProvider,CoordinateFieldStateContext,CoordinateFieldStateProvider,useCoordinateFieldStateContext}from'./components/coordinate-field/context.js';export{COORDINATE_EPSILON,COORDINATE_ERROR_MESSAGES,areAllSegmentsFilled,areCoordinatesEqual,convertDDToDisplaySegments,convertDisplaySegmentsToDD,deduplicateMatchesByLocation,formatSegmentsToCoordinateString,getAllCoordinateFormats,hasAnySegmentValue,isCompleteCoordinate,parseCoordinatePaste,parseCoordinateStringToSegments,validateCoordinateSegments}from'./components/coordinate-field/coordinate-utils.js';export{CoordinateField}from'./components/coordinate-field/index.js';export{EXPECTED_SEGMENT_COUNTS,GROUP_SEPARATOR,ddSegmentConfigs,ddmSegmentConfigs,dmsSegmentConfigs,getEditableSegmentCount,getFormatDescription,getSegmentConfigs,getSegmentLabel,mgrsSegmentConfigs,utmSegmentConfigs}from'./components/coordinate-field/segment-configs.js';export{CoordinateSegment}from'./components/coordinate-field/segment.js';export{COORDINATE_FORMAT_LABELS,COORDINATE_FORMAT_NAMES,COORDINATE_SYSTEMS}from'./components/coordinate-field/types.js';export{DateField}from'./components/date-field/index.js';export{DetailsListContext,DetailsListProvider}from'./components/details-list/context.js';export{DetailsList}from'./components/details-list/index.js';export{DetailsListLabel}from'./components/details-list/label.js';export{DetailsListValue}from'./components/details-list/value.js';export{DialogContent}from'./components/dialog/content.js';export{DialogContext}from'./components/dialog/context.js';export{DialogFooter}from'./components/dialog/footer.js';export{Dialog}from'./components/dialog/index.js';export{DialogTitle}from'./components/dialog/title.js';export{DialogTrigger}from'./components/dialog/trigger.js';export{DividerContext,DividerProvider}from'./components/divider/context.js';export{Divider}from'./components/divider/index.js';export{DrawerBack}from'./components/drawer/back.js';export{DrawerClose}from'./components/drawer/close.js';export{DrawerContent}from'./components/drawer/content.js';export{DrawerContext,DrawerEventHandlers,bus,useDrawerEmit}from'./components/drawer/context.js';export{DrawerEventNamespace,DrawerEventTypes}from'./components/drawer/events.js';export{DrawerFooter}from'./components/drawer/footer.js';export{DrawerHeaderTitle}from'./components/drawer/header-title.js';export{DrawerHeader}from'./components/drawer/header.js';export{Drawer}from'./components/drawer/index.js';export{DrawerLayoutMain}from'./components/drawer/layout-main.js';export{DrawerLayout}from'./components/drawer/layout.js';export{DrawerMenuItem}from'./components/drawer/menu-item.js';export{DrawerMenu}from'./components/drawer/menu.js';export{DrawerPanel}from'./components/drawer/panel.js';export{DrawerTrigger}from'./components/drawer/trigger.js';export{DrawerView}from'./components/drawer/view.js';export{Flashcard,FlashcardAdditionalData,FlashcardContext,FlashcardDetailsLabel,FlashcardDetailsList,FlashcardDetailsValue,FlashcardHero}from'./components/flashcard/index.js';export{HeroContext}from'./components/hero/context.js';export{Hero}from'./components/hero/index.js';export{HeroSubtitle}from'./components/hero/subtitle.js';export{HeroTitle}from'./components/hero/title.js';export{HotkeyContext,HotkeyProvider}from'./components/hotkey/context.js';export{Hotkey}from'./components/hotkey/index.js';export{HotkeySet}from'./components/hotkey/set.js';export{IconContext,IconProvider}from'./components/icon/context.js';export{Icon}from'./components/icon/index.js';export{InputContext}from'./components/input/context.js';export{Input}from'./components/input/index.js';export{KanbanCardBody}from'./components/kanban/card-body.js';export{KanbanCardHeaderActions}from'./components/kanban/card-header-actions.js';export{KanbanCardHeaderTitle}from'./components/kanban/card-header-title.js';export{KanbanCardHeader}from'./components/kanban/card-header.js';export{KanbanCard}from'./components/kanban/card.js';export{KanbanColumnActions}from'./components/kanban/column-actions.js';export{KanbanColumnContainer}from'./components/kanban/column-container.js';export{KanbanColumnContent}from'./components/kanban/column-content.js';export{KanbanColumnHeaderActions}from'./components/kanban/column-header-actions.js';export{KanbanColumnHeaderDragHandle}from'./components/kanban/column-header-drag-handle.js';export{KanbanColumnHeaderTitle}from'./components/kanban/column-header-title.js';export{KanbanColumnHeader}from'./components/kanban/column-header.js';export{KanbanColumn}from'./components/kanban/column.js';export{KanbanProvider,calculateClosestEdge,getInsertIndex,parseDropTarget,useKanban,validateMoveCard}from'./components/kanban/context.js';export{KanbanHeaderActions}from'./components/kanban/header-actions.js';export{KanbanHeaderSearch}from'./components/kanban/header-search.js';export{KanbanHeaderTitle}from'./components/kanban/header-title.js';export{KanbanHeader}from'./components/kanban/header.js';export{DragContext,Kanban,useDragContext}from'./components/kanban/kanban.js';export{columnData}from'./components/kanban/mock-data.js';export{LabelContext,LabelProvider}from'./components/label/context.js';export{Label}from'./components/label/index.js';export{Lines}from'./components/lines/index.js';export{LinkProvider}from'./components/link/context.js';export{Link}from'./components/link/index.js';export{MenuContext}from'./components/menu/context.js';export{Menu}from'./components/menu/index.js';export{MenuItemDescription}from'./components/menu/item-description.js';export{MenuItemLabel}from'./components/menu/item-label.js';export{MenuItem}from'./components/menu/item.js';export{MenuSection}from'./components/menu/section.js';export{MenuSeparator}from'./components/menu/separator.js';export{MenuSubmenu}from'./components/menu/submenu.js';export{MenuTrigger}from'./components/menu/trigger.js';export{NoticeEventNamespace,NoticeEventTypes}from'./components/notice/events.js';export{Notice}from'./components/notice/index.js';export{NoticeList}from'./components/notice/list.js';export{NoticeIcon}from'./components/notice/notice-icon.js';export{matchesMetadata}from'./components/notice/utils.js';export{OptionsContext}from'./components/options/context.js';export{Options}from'./components/options/index.js';export{OptionsItemContent}from'./components/options/item-content.js';export{OptionsItemDescription}from'./components/options/item-description.js';export{OptionsItemLabel}from'./components/options/item-label.js';export{OptionsItem}from'./components/options/item.js';export{OptionsSection}from'./components/options/section.js';export{PaginationContext}from'./components/pagination/context.js';export{Pagination}from'./components/pagination/index.js';export{PaginationNext}from'./components/pagination/next.js';export{PaginationPages}from'./components/pagination/pages.js';export{PaginationPrev}from'./components/pagination/prev.js';export{PopoverContent}from'./components/popover/content.js';export{PopoverFooter}from'./components/popover/footer.js';export{Popover}from'./components/popover/index.js';export{PopoverTitle}from'./components/popover/title.js';export{PopoverTrigger}from'./components/popover/trigger.js';export{CloneAction,LockAction,RemoveRuleAction}from'./components/query-builder/actions.js';export{CombinatorSelector}from'./components/query-builder/combinator-selector.js';export{QueryBuilder}from'./components/query-builder/index.js';export{RadioContext}from'./components/radio/context.js';export{RadioGroup}from'./components/radio/group.js';export{Radio}from'./components/radio/index.js';export{SearchFieldContext,SearchFieldProvider}from'./components/search-field/context.js';export{SearchField}from'./components/search-field/index.js';export{SelectFieldContext,SelectFieldProvider}from'./components/select-field/context.js';export{SelectField}from'./components/select-field/index.js';export{SidenavAvatar}from'./components/sidenav/avatar.js';export{SidenavContent}from'./components/sidenav/content.js';export{SidenavContext}from'./components/sidenav/context.js';export{SidenavEventNamespace,SidenavEventTypes}from'./components/sidenav/events.js';export{SidenavFooter}from'./components/sidenav/footer.js';export{SidenavHeader}from'./components/sidenav/header.js';export{Sidenav}from'./components/sidenav/index.js';export{SidenavItem}from'./components/sidenav/item.js';export{SidenavLink}from'./components/sidenav/link.js';export{SidenavMenuItem}from'./components/sidenav/menu-item.js';export{SidenavMenu}from'./components/sidenav/menu.js';export{SidenavTrigger}from'./components/sidenav/trigger.js';export{Skeleton}from'./components/skeleton/index.js';export{Slider}from'./components/slider/index.js';export{SwitchContext,SwitchProvider}from'./components/switch/context.js';export{Switch}from'./components/switch/index.js';export{HeaderColumnAction,SortDirection,headerColumnActionValues,sortDirectionValues}from'./components/table/constants/table.js';export{TableContext}from'./components/table/context.js';export{Table}from'./components/table/index.js';export{TabsContext,TabsProvider}from'./components/tabs/context.js';export{Tabs}from'./components/tabs/index.js';export{TabList}from'./components/tabs/list.js';export{TabPanel}from'./components/tabs/panel.js';export{Tab}from'./components/tabs/tab.js';export{TextAreaFieldContext,TextAreaFieldProvider}from'./components/text-area-field/context.js';export{TextAreaField}from'./components/text-area-field/index.js';export{TextFieldContext,TextFieldProvider}from'./components/text-field/context.js';export{TextField}from'./components/text-field/index.js';export{TimeField}from'./components/time-field/index.js';export{TooltipContext}from'./components/tooltip/context.js';export{Tooltip}from'./components/tooltip/index.js';export{TooltipTrigger}from'./components/tooltip/trigger.js';export{TreeContext,TreeItemContext}from'./components/tree/context.js';export{Tree}from'./components/tree/index.js';export{TreeItemActions}from'./components/tree/item-actions.js';export{TreeItemContent}from'./components/tree/item-content.js';export{TreeItemDescription}from'./components/tree/item-description.js';export{TreeItemLabel}from'./components/tree/item-label.js';export{TreeItemPrefixIcon}from'./components/tree/item-prefix-icon.js';export{TreeItem}from'./components/tree/item.js';export{TreeLines}from'./components/tree/lines.js';export{ViewStackContext,ViewStackEventHandlers,useViewStackEmit}from'./components/view-stack/context.js';export{ViewStackEventNamespace,ViewStackEventTypes}from'./components/view-stack/events.js';export{ViewStack}from'./components/view-stack/index.js';export{ViewStackTrigger}from'./components/view-stack/trigger.js';export{ViewStackView}from'./components/view-stack/view.js';export{useCoordinateCopy}from'./hooks/coordinate-field/use-coordinate-copy.js';export{useCoordinateFieldState}from'./hooks/coordinate-field/use-coordinate-field-state.js';export{useCoordinateField}from'./hooks/coordinate-field/use-coordinate-field.js';export{useCoordinateFocus}from'./hooks/coordinate-field/use-coordinate-focus.js';export{useCoordinatePaste}from'./hooks/coordinate-field/use-coordinate-paste.js';export{useTimeoutCleanup}from'./hooks/coordinate-field/use-timeout-cleanup.js';export{useCardInteractions,useColumnInteractions}from'./hooks/kanban/index.js';export{useTreeActions}from'./hooks/use-tree/actions/index.js';export{useTreeState}from'./hooks/use-tree/state/index.js';export{isSlottedContextValue}from'./lib/utils.js';export{PortalProvider}from'./providers/portal.js';export{ThemeProvider,useTheme}from'./providers/theme-provider.js';//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|