@kubit-ui-web/react-charts 1.5.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/charts/lineChart/context/buildLineContextValue.d.ts +1 -3
- package/dist/cjs/charts/lineChart/context/buildLineContextValue.d.ts.map +1 -1
- package/dist/cjs/charts/lineChart/context/buildLineContextValue.js +64 -128
- package/dist/cjs/charts/lineChart/fragments/fixture/contextData.d.ts +2 -43
- package/dist/cjs/charts/lineChart/fragments/fixture/contextData.d.ts.map +1 -1
- package/dist/cjs/charts/lineChart/fragments/fixture/contextData.js +8 -6
- package/dist/cjs/charts/lineChart/fragments/lineChartPath.js +3 -3
- package/dist/cjs/charts/lineChart/fragments/lineChartXAxis.d.ts.map +1 -1
- package/dist/cjs/charts/lineChart/fragments/lineChartXAxis.js +3 -8
- package/dist/cjs/charts/lineChart/fragments/lineChartYAxis.d.ts.map +1 -1
- package/dist/cjs/charts/lineChart/fragments/lineChartYAxis.js +9 -9
- package/dist/cjs/charts/lineChart/lineChart.type.d.ts +12 -7
- package/dist/cjs/charts/lineChart/lineChart.type.d.ts.map +1 -1
- package/dist/cjs/charts/lineChart/lineChartStructure.js +11 -10
- package/dist/cjs/charts/lineChart/utils/getCoordinates.d.ts +25 -0
- package/dist/cjs/charts/lineChart/utils/getCoordinates.d.ts.map +1 -0
- package/dist/cjs/charts/lineChart/utils/getCoordinates.js +55 -0
- package/dist/cjs/charts/lineChart/utils/getExtraSpacing.d.ts +1 -3
- package/dist/cjs/charts/lineChart/utils/getExtraSpacing.d.ts.map +1 -1
- package/dist/cjs/charts/lineChart/utils/getExtraSpacing.js +68 -51
- package/dist/cjs/charts/lineChart/utils/getTicks.d.ts +21 -0
- package/dist/cjs/charts/lineChart/utils/getTicks.d.ts.map +1 -0
- package/dist/cjs/charts/lineChart/utils/getTicks.js +36 -0
- package/dist/cjs/charts/lineChart/utils/handleNodesFocus.d.ts.map +1 -1
- package/dist/cjs/charts/lineChart/utils/handleNodesFocus.js +14 -25
- package/dist/cjs/charts/lineChart/utils/tickTextPosition.d.ts +33 -0
- package/dist/cjs/charts/lineChart/utils/tickTextPosition.d.ts.map +1 -0
- package/dist/cjs/charts/lineChart/utils/tickTextPosition.js +109 -0
- package/dist/cjs/charts/lineChart/utils/validations.d.ts +54 -0
- package/dist/cjs/charts/lineChart/utils/validations.d.ts.map +1 -0
- package/dist/cjs/charts/lineChart/utils/validations.js +117 -0
- package/dist/cjs/components/chartText/chartText.d.ts.map +1 -1
- package/dist/cjs/components/chartText/chartText.js +2 -2
- package/dist/cjs/components/focusRing/components/FocusRingInline.d.ts +25 -0
- package/dist/cjs/components/focusRing/components/FocusRingInline.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/components/FocusRingInline.js +37 -0
- package/dist/cjs/components/focusRing/components/FocusRingRenderer.d.ts +13 -0
- package/dist/cjs/components/focusRing/components/FocusRingRenderer.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/components/FocusRingRenderer.js +25 -0
- package/dist/cjs/components/focusRing/components/FocusRingSeparate.d.ts +40 -0
- package/dist/cjs/components/focusRing/components/FocusRingSeparate.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/components/FocusRingSeparate.js +45 -0
- package/dist/cjs/components/focusRing/focusRing.css +14 -0
- package/dist/cjs/components/focusRing/focusRing.d.ts +35 -0
- package/dist/cjs/components/focusRing/focusRing.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/focusRing.js +44 -0
- package/dist/cjs/components/focusRing/focusRing.types.d.ts +40 -0
- package/dist/cjs/components/focusRing/focusRing.types.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/focusRing.types.js +1 -0
- package/dist/cjs/components/focusRing/hooks/useFocusRingData.d.ts +27 -0
- package/dist/cjs/components/focusRing/hooks/useFocusRingData.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/hooks/useFocusRingData.js +67 -0
- package/dist/cjs/components/focusRing/index.d.ts +3 -0
- package/dist/cjs/components/focusRing/index.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/index.js +1 -0
- package/dist/cjs/components/focusRing/utils/composeRefs.d.ts +7 -0
- package/dist/cjs/components/focusRing/utils/composeRefs.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/utils/composeRefs.js +16 -0
- package/dist/cjs/components/focusRing/utils/createAdaptiveFocusRings.d.ts +24 -0
- package/dist/cjs/components/focusRing/utils/createAdaptiveFocusRings.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/utils/createAdaptiveFocusRings.js +141 -0
- package/dist/cjs/components/focusRing/utils/createBoundingBoxFocusRings.d.ts +33 -0
- package/dist/cjs/components/focusRing/utils/createBoundingBoxFocusRings.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/utils/createBoundingBoxFocusRings.js +126 -0
- package/dist/cjs/components/focusRing/utils/utils.types.d.ts +52 -0
- package/dist/cjs/components/focusRing/utils/utils.types.d.ts.map +1 -0
- package/dist/cjs/components/focusRing/utils/utils.types.js +1 -0
- package/dist/cjs/components/index.d.ts +1 -0
- package/dist/cjs/components/index.d.ts.map +1 -1
- package/dist/cjs/components/index.js +1 -0
- package/dist/cjs/components/line/line.d.ts.map +1 -1
- package/dist/cjs/components/line/line.js +2 -2
- package/dist/cjs/components/line/line.types.d.ts +2 -0
- package/dist/cjs/components/line/line.types.d.ts.map +1 -1
- package/dist/cjs/components/node/node.d.ts.map +1 -1
- package/dist/cjs/components/node/node.js +1 -1
- package/dist/cjs/components/node/node.types.d.ts +2 -0
- package/dist/cjs/components/node/node.types.d.ts.map +1 -1
- package/dist/cjs/components/path/path.js +1 -1
- package/dist/cjs/components/plot/plot.d.ts.map +1 -1
- package/dist/cjs/components/plot/plot.js +7 -19
- package/dist/cjs/components/zoomArea/components/SelectionArea.d.ts +3 -23
- package/dist/cjs/components/zoomArea/components/SelectionArea.d.ts.map +1 -1
- package/dist/cjs/components/zoomArea/components/SelectionArea.js +7 -39
- package/dist/cjs/components/zoomArea/components/ZoomHandler.d.ts +3 -3
- package/dist/cjs/components/zoomArea/components/ZoomHandler.d.ts.map +1 -1
- package/dist/cjs/components/zoomArea/components/ZoomHandler.js +2 -15
- package/dist/cjs/components/zoomArea/components/index.d.ts +1 -1
- package/dist/cjs/components/zoomArea/components/index.d.ts.map +1 -1
- package/dist/cjs/components/zoomArea/components/index.js +1 -1
- package/dist/cjs/components/zoomArea/zoomArea.js +6 -6
- package/dist/cjs/components/zoomArea/zoomArea.type.d.ts +1 -1
- package/dist/cjs/components/zoomArea/zoomArea.type.d.ts.map +1 -1
- package/dist/cjs/types/focusConfig.type.d.ts +15 -3
- package/dist/cjs/types/focusConfig.type.d.ts.map +1 -1
- package/dist/cjs/types/focusConfig.type.js +14 -1
- package/dist/cjs/utils/pickCustomAttributes/pickCustomAttributes.d.ts +7 -6
- package/dist/cjs/utils/pickCustomAttributes/pickCustomAttributes.d.ts.map +1 -1
- package/dist/cjs/utils/pickCustomAttributes/pickCustomAttributes.js +8 -7
- package/dist/esm/charts/lineChart/context/buildLineContextValue.d.ts +1 -3
- package/dist/esm/charts/lineChart/context/buildLineContextValue.d.ts.map +1 -1
- package/dist/esm/charts/lineChart/context/buildLineContextValue.js +64 -128
- package/dist/esm/charts/lineChart/fragments/fixture/contextData.d.ts +2 -43
- package/dist/esm/charts/lineChart/fragments/fixture/contextData.d.ts.map +1 -1
- package/dist/esm/charts/lineChart/fragments/fixture/contextData.js +8 -6
- package/dist/esm/charts/lineChart/fragments/lineChartPath.js +3 -3
- package/dist/esm/charts/lineChart/fragments/lineChartXAxis.d.ts.map +1 -1
- package/dist/esm/charts/lineChart/fragments/lineChartXAxis.js +3 -8
- package/dist/esm/charts/lineChart/fragments/lineChartYAxis.d.ts.map +1 -1
- package/dist/esm/charts/lineChart/fragments/lineChartYAxis.js +9 -9
- package/dist/esm/charts/lineChart/lineChart.type.d.ts +12 -7
- package/dist/esm/charts/lineChart/lineChart.type.d.ts.map +1 -1
- package/dist/esm/charts/lineChart/lineChartStructure.js +11 -10
- package/dist/esm/charts/lineChart/utils/getCoordinates.d.ts +25 -0
- package/dist/esm/charts/lineChart/utils/getCoordinates.d.ts.map +1 -0
- package/dist/esm/charts/lineChart/utils/getCoordinates.js +55 -0
- package/dist/esm/charts/lineChart/utils/getExtraSpacing.d.ts +1 -3
- package/dist/esm/charts/lineChart/utils/getExtraSpacing.d.ts.map +1 -1
- package/dist/esm/charts/lineChart/utils/getExtraSpacing.js +68 -51
- package/dist/esm/charts/lineChart/utils/getTicks.d.ts +21 -0
- package/dist/esm/charts/lineChart/utils/getTicks.d.ts.map +1 -0
- package/dist/esm/charts/lineChart/utils/getTicks.js +36 -0
- package/dist/esm/charts/lineChart/utils/handleNodesFocus.d.ts.map +1 -1
- package/dist/esm/charts/lineChart/utils/handleNodesFocus.js +14 -25
- package/dist/esm/charts/lineChart/utils/tickTextPosition.d.ts +33 -0
- package/dist/esm/charts/lineChart/utils/tickTextPosition.d.ts.map +1 -0
- package/dist/esm/charts/lineChart/utils/tickTextPosition.js +109 -0
- package/dist/esm/charts/lineChart/utils/validations.d.ts +54 -0
- package/dist/esm/charts/lineChart/utils/validations.d.ts.map +1 -0
- package/dist/esm/charts/lineChart/utils/validations.js +117 -0
- package/dist/esm/components/chartText/chartText.d.ts.map +1 -1
- package/dist/esm/components/chartText/chartText.js +2 -2
- package/dist/esm/components/focusRing/components/FocusRingInline.d.ts +25 -0
- package/dist/esm/components/focusRing/components/FocusRingInline.d.ts.map +1 -0
- package/dist/esm/components/focusRing/components/FocusRingInline.js +37 -0
- package/dist/esm/components/focusRing/components/FocusRingRenderer.d.ts +13 -0
- package/dist/esm/components/focusRing/components/FocusRingRenderer.d.ts.map +1 -0
- package/dist/esm/components/focusRing/components/FocusRingRenderer.js +25 -0
- package/dist/esm/components/focusRing/components/FocusRingSeparate.d.ts +40 -0
- package/dist/esm/components/focusRing/components/FocusRingSeparate.d.ts.map +1 -0
- package/dist/esm/components/focusRing/components/FocusRingSeparate.js +45 -0
- package/dist/esm/components/focusRing/focusRing.css +14 -0
- package/dist/esm/components/focusRing/focusRing.d.ts +35 -0
- package/dist/esm/components/focusRing/focusRing.d.ts.map +1 -0
- package/dist/esm/components/focusRing/focusRing.js +44 -0
- package/dist/esm/components/focusRing/focusRing.types.d.ts +40 -0
- package/dist/esm/components/focusRing/focusRing.types.d.ts.map +1 -0
- package/dist/esm/components/focusRing/focusRing.types.js +1 -0
- package/dist/esm/components/focusRing/hooks/useFocusRingData.d.ts +27 -0
- package/dist/esm/components/focusRing/hooks/useFocusRingData.d.ts.map +1 -0
- package/dist/esm/components/focusRing/hooks/useFocusRingData.js +67 -0
- package/dist/esm/components/focusRing/index.d.ts +3 -0
- package/dist/esm/components/focusRing/index.d.ts.map +1 -0
- package/dist/esm/components/focusRing/index.js +1 -0
- package/dist/esm/components/focusRing/utils/composeRefs.d.ts +7 -0
- package/dist/esm/components/focusRing/utils/composeRefs.d.ts.map +1 -0
- package/dist/esm/components/focusRing/utils/composeRefs.js +16 -0
- package/dist/esm/components/focusRing/utils/createAdaptiveFocusRings.d.ts +24 -0
- package/dist/esm/components/focusRing/utils/createAdaptiveFocusRings.d.ts.map +1 -0
- package/dist/esm/components/focusRing/utils/createAdaptiveFocusRings.js +141 -0
- package/dist/esm/components/focusRing/utils/createBoundingBoxFocusRings.d.ts +33 -0
- package/dist/esm/components/focusRing/utils/createBoundingBoxFocusRings.d.ts.map +1 -0
- package/dist/esm/components/focusRing/utils/createBoundingBoxFocusRings.js +126 -0
- package/dist/esm/components/focusRing/utils/utils.types.d.ts +52 -0
- package/dist/esm/components/focusRing/utils/utils.types.d.ts.map +1 -0
- package/dist/esm/components/focusRing/utils/utils.types.js +1 -0
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/components/line/line.d.ts.map +1 -1
- package/dist/esm/components/line/line.js +2 -2
- package/dist/esm/components/line/line.types.d.ts +2 -0
- package/dist/esm/components/line/line.types.d.ts.map +1 -1
- package/dist/esm/components/node/node.d.ts.map +1 -1
- package/dist/esm/components/node/node.js +1 -1
- package/dist/esm/components/node/node.types.d.ts +2 -0
- package/dist/esm/components/node/node.types.d.ts.map +1 -1
- package/dist/esm/components/path/path.js +1 -1
- package/dist/esm/components/plot/plot.d.ts.map +1 -1
- package/dist/esm/components/plot/plot.js +7 -19
- package/dist/esm/components/zoomArea/components/SelectionArea.d.ts +3 -23
- package/dist/esm/components/zoomArea/components/SelectionArea.d.ts.map +1 -1
- package/dist/esm/components/zoomArea/components/SelectionArea.js +7 -39
- package/dist/esm/components/zoomArea/components/ZoomHandler.d.ts +3 -3
- package/dist/esm/components/zoomArea/components/ZoomHandler.d.ts.map +1 -1
- package/dist/esm/components/zoomArea/components/ZoomHandler.js +2 -15
- package/dist/esm/components/zoomArea/components/index.d.ts +1 -1
- package/dist/esm/components/zoomArea/components/index.d.ts.map +1 -1
- package/dist/esm/components/zoomArea/components/index.js +1 -1
- package/dist/esm/components/zoomArea/zoomArea.js +6 -6
- package/dist/esm/components/zoomArea/zoomArea.type.d.ts +1 -1
- package/dist/esm/components/zoomArea/zoomArea.type.d.ts.map +1 -1
- package/dist/esm/types/focusConfig.type.d.ts +15 -3
- package/dist/esm/types/focusConfig.type.d.ts.map +1 -1
- package/dist/esm/types/focusConfig.type.js +14 -1
- package/dist/esm/utils/pickCustomAttributes/pickCustomAttributes.d.ts +7 -6
- package/dist/esm/utils/pickCustomAttributes/pickCustomAttributes.d.ts.map +1 -1
- package/dist/esm/utils/pickCustomAttributes/pickCustomAttributes.js +8 -7
- package/dist/kubit-ui-web-react-charts.cjs.js +1 -1
- package/dist/kubit-ui-web-react-charts.es.js +1 -1
- package/dist/kubit-ui-web-react-charts.umd.js +1 -1
- package/dist/react-charts.css +1 -1
- package/dist/types/charts/lineChart/context/buildLineContextValue.d.ts +1 -3
- package/dist/types/charts/lineChart/context/buildLineContextValue.d.ts.map +1 -1
- package/dist/types/charts/lineChart/fragments/fixture/contextData.d.ts +2 -43
- package/dist/types/charts/lineChart/fragments/fixture/contextData.d.ts.map +1 -1
- package/dist/types/charts/lineChart/fragments/lineChartXAxis.d.ts.map +1 -1
- package/dist/types/charts/lineChart/fragments/lineChartYAxis.d.ts.map +1 -1
- package/dist/types/charts/lineChart/lineChart.type.d.ts +12 -7
- package/dist/types/charts/lineChart/lineChart.type.d.ts.map +1 -1
- package/dist/types/charts/lineChart/utils/getCoordinates.d.ts +25 -0
- package/dist/types/charts/lineChart/utils/getCoordinates.d.ts.map +1 -0
- package/dist/types/charts/lineChart/utils/getExtraSpacing.d.ts +1 -3
- package/dist/types/charts/lineChart/utils/getExtraSpacing.d.ts.map +1 -1
- package/dist/types/charts/lineChart/utils/getTicks.d.ts +21 -0
- package/dist/types/charts/lineChart/utils/getTicks.d.ts.map +1 -0
- package/dist/types/charts/lineChart/utils/handleNodesFocus.d.ts.map +1 -1
- package/dist/types/charts/lineChart/utils/tickTextPosition.d.ts +33 -0
- package/dist/types/charts/lineChart/utils/tickTextPosition.d.ts.map +1 -0
- package/dist/types/charts/lineChart/utils/validations.d.ts +54 -0
- package/dist/types/charts/lineChart/utils/validations.d.ts.map +1 -0
- package/dist/types/components/chartText/chartText.d.ts.map +1 -1
- package/dist/types/components/focusRing/components/FocusRingInline.d.ts +25 -0
- package/dist/types/components/focusRing/components/FocusRingInline.d.ts.map +1 -0
- package/dist/types/components/focusRing/components/FocusRingRenderer.d.ts +13 -0
- package/dist/types/components/focusRing/components/FocusRingRenderer.d.ts.map +1 -0
- package/dist/types/components/focusRing/components/FocusRingSeparate.d.ts +40 -0
- package/dist/types/components/focusRing/components/FocusRingSeparate.d.ts.map +1 -0
- package/dist/types/components/focusRing/focusRing.d.ts +34 -0
- package/dist/types/components/focusRing/focusRing.d.ts.map +1 -0
- package/dist/types/components/focusRing/focusRing.types.d.ts +40 -0
- package/dist/types/components/focusRing/focusRing.types.d.ts.map +1 -0
- package/dist/types/components/focusRing/hooks/useFocusRingData.d.ts +27 -0
- package/dist/types/components/focusRing/hooks/useFocusRingData.d.ts.map +1 -0
- package/dist/types/components/focusRing/index.d.ts +3 -0
- package/dist/types/components/focusRing/index.d.ts.map +1 -0
- package/dist/types/components/focusRing/utils/composeRefs.d.ts +7 -0
- package/dist/types/components/focusRing/utils/composeRefs.d.ts.map +1 -0
- package/dist/types/components/focusRing/utils/createAdaptiveFocusRings.d.ts +24 -0
- package/dist/types/components/focusRing/utils/createAdaptiveFocusRings.d.ts.map +1 -0
- package/dist/types/components/focusRing/utils/createBoundingBoxFocusRings.d.ts +33 -0
- package/dist/types/components/focusRing/utils/createBoundingBoxFocusRings.d.ts.map +1 -0
- package/dist/types/components/focusRing/utils/utils.types.d.ts +52 -0
- package/dist/types/components/focusRing/utils/utils.types.d.ts.map +1 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/components/index.d.ts.map +1 -1
- package/dist/types/components/line/line.d.ts.map +1 -1
- package/dist/types/components/line/line.types.d.ts +2 -0
- package/dist/types/components/line/line.types.d.ts.map +1 -1
- package/dist/types/components/node/node.d.ts.map +1 -1
- package/dist/types/components/node/node.types.d.ts +2 -0
- package/dist/types/components/node/node.types.d.ts.map +1 -1
- package/dist/types/components/plot/plot.d.ts.map +1 -1
- package/dist/types/components/zoomArea/components/SelectionArea.d.ts +3 -23
- package/dist/types/components/zoomArea/components/SelectionArea.d.ts.map +1 -1
- package/dist/types/components/zoomArea/components/ZoomHandler.d.ts +3 -3
- package/dist/types/components/zoomArea/components/ZoomHandler.d.ts.map +1 -1
- package/dist/types/components/zoomArea/components/index.d.ts +1 -1
- package/dist/types/components/zoomArea/components/index.d.ts.map +1 -1
- package/dist/types/components/zoomArea/zoomArea.type.d.ts +1 -1
- package/dist/types/components/zoomArea/zoomArea.type.d.ts.map +1 -1
- package/dist/types/types/focusConfig.type.d.ts +15 -3
- package/dist/types/types/focusConfig.type.d.ts.map +1 -1
- package/dist/types/utils/pickCustomAttributes/pickCustomAttributes.d.ts +7 -6
- package/dist/types/utils/pickCustomAttributes/pickCustomAttributes.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/cjs/utils/calculateFocusOutline/calculateFocusOutline.d.ts +0 -73
- package/dist/cjs/utils/calculateFocusOutline/calculateFocusOutline.d.ts.map +0 -1
- package/dist/cjs/utils/calculateFocusOutline/calculateFocusOutline.js +0 -80
- package/dist/esm/utils/calculateFocusOutline/calculateFocusOutline.d.ts +0 -73
- package/dist/esm/utils/calculateFocusOutline/calculateFocusOutline.d.ts.map +0 -1
- package/dist/esm/utils/calculateFocusOutline/calculateFocusOutline.js +0 -80
- package/dist/types/utils/calculateFocusOutline/calculateFocusOutline.d.ts +0 -73
- package/dist/types/utils/calculateFocusOutline/calculateFocusOutline.d.ts.map +0 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { BuildError, buildCanvasDimensionsError, buildError, } from '../../../utils/buildErrors/buildErrors';
|
|
2
|
+
import { AXIS_VALIDATION } from '../../constants/chartDefaults';
|
|
3
|
+
export const validateData = ({ data, addError }) => {
|
|
4
|
+
let error = undefined;
|
|
5
|
+
if (!data || data.length === 0) {
|
|
6
|
+
const dataError = {
|
|
7
|
+
error: buildError(BuildError.LINE_CHART_NO_DATA),
|
|
8
|
+
};
|
|
9
|
+
addError?.('LINE_CHART_CONTEXT_ERROR', dataError);
|
|
10
|
+
error = dataError;
|
|
11
|
+
}
|
|
12
|
+
if (data && data.length === 1) {
|
|
13
|
+
const singlePointError = {
|
|
14
|
+
error: buildError(BuildError.LINE_CHART_SINGLE_POINT),
|
|
15
|
+
};
|
|
16
|
+
addError?.('LINE_CHART_CONTEXT_ERROR', singlePointError);
|
|
17
|
+
error = singlePointError;
|
|
18
|
+
}
|
|
19
|
+
return { error };
|
|
20
|
+
};
|
|
21
|
+
export const validateCanvasDimensions = ({ canvasWidth, canvasHeight, addError, }) => {
|
|
22
|
+
let error = undefined;
|
|
23
|
+
if (canvasWidth <= 0 || canvasHeight <= 0) {
|
|
24
|
+
const canvasError = {
|
|
25
|
+
error: buildCanvasDimensionsError(canvasWidth, canvasHeight),
|
|
26
|
+
};
|
|
27
|
+
addError?.('LINE_CHART_CONTEXT_ERROR', canvasError);
|
|
28
|
+
error = canvasError;
|
|
29
|
+
}
|
|
30
|
+
return { error };
|
|
31
|
+
};
|
|
32
|
+
export const validateYTickValues = ({ yTickValues, addError }) => {
|
|
33
|
+
let error = undefined;
|
|
34
|
+
if (yTickValues) {
|
|
35
|
+
const hasInsufficientTicks = yTickValues.length < AXIS_VALIDATION.MIN_TICK_COUNT;
|
|
36
|
+
const hasIdenticalValues = yTickValues.length >= AXIS_VALIDATION.MIN_TICK_COUNT &&
|
|
37
|
+
new Set(yTickValues.map(tick => tick.value)).size === AXIS_VALIDATION.UNIQUE_VALUE_THRESHOLD;
|
|
38
|
+
if (hasInsufficientTicks) {
|
|
39
|
+
const yAxisError = {
|
|
40
|
+
error: buildError(BuildError.LINE_CHART_Y_AXIS_INSUFFICIENT_TICKS),
|
|
41
|
+
};
|
|
42
|
+
addError?.('LINE_CHART_Y_AXIS_ERROR', yAxisError);
|
|
43
|
+
if (!error) {
|
|
44
|
+
error = yAxisError;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (hasIdenticalValues) {
|
|
48
|
+
const yAxisError = {
|
|
49
|
+
error: buildError(BuildError.LINE_CHART_Y_AXIS_IDENTICAL_VALUES),
|
|
50
|
+
};
|
|
51
|
+
addError?.('LINE_CHART_Y_AXIS_ERROR', yAxisError);
|
|
52
|
+
if (!error) {
|
|
53
|
+
error = yAxisError;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { error };
|
|
58
|
+
};
|
|
59
|
+
export const validateXTickValues = ({ xTickValues, addError }) => {
|
|
60
|
+
let error = undefined;
|
|
61
|
+
// Validate X-axis tick values
|
|
62
|
+
if (xTickValues) {
|
|
63
|
+
if ((xTickValues ?? []).some(({ position }) => isNaN(position))) {
|
|
64
|
+
const xTickError = {
|
|
65
|
+
error: buildError(BuildError.INVALID_X_TICK),
|
|
66
|
+
};
|
|
67
|
+
addError?.('LINE_CHART_CONTEXT_ERROR', xTickError);
|
|
68
|
+
error = xTickError;
|
|
69
|
+
}
|
|
70
|
+
const hasInsufficientTicks = xTickValues.length < AXIS_VALIDATION.MIN_TICK_COUNT;
|
|
71
|
+
const hasIdenticalValues = xTickValues.length >= AXIS_VALIDATION.MIN_TICK_COUNT &&
|
|
72
|
+
new Set(xTickValues.map(tick => tick.value)).size === AXIS_VALIDATION.UNIQUE_VALUE_THRESHOLD;
|
|
73
|
+
if (hasInsufficientTicks) {
|
|
74
|
+
const xAxisError = {
|
|
75
|
+
error: buildError(BuildError.LINE_CHART_X_AXIS_INSUFFICIENT_TICKS),
|
|
76
|
+
};
|
|
77
|
+
addError?.('LINE_CHART_X_AXIS_ERROR', xAxisError);
|
|
78
|
+
if (!error) {
|
|
79
|
+
error = xAxisError;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (hasIdenticalValues) {
|
|
83
|
+
const xAxisError = {
|
|
84
|
+
error: buildError(BuildError.LINE_CHART_X_AXIS_IDENTICAL_VALUES),
|
|
85
|
+
};
|
|
86
|
+
addError?.('LINE_CHART_X_AXIS_ERROR', xAxisError);
|
|
87
|
+
if (!error) {
|
|
88
|
+
error = xAxisError;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { error };
|
|
93
|
+
};
|
|
94
|
+
export const validateXCoordinates = ({ xCoordinates, addError }) => {
|
|
95
|
+
let error = undefined;
|
|
96
|
+
if (xCoordinates.x1 === xCoordinates.x2) {
|
|
97
|
+
const xAxisError = {
|
|
98
|
+
error: buildError(BuildError.LINE_CHART_X_AXIS_ZERO_LENGTH),
|
|
99
|
+
};
|
|
100
|
+
addError?.('LINE_CHART_X_AXIS_ERROR', xAxisError);
|
|
101
|
+
error = xAxisError;
|
|
102
|
+
}
|
|
103
|
+
return { error };
|
|
104
|
+
};
|
|
105
|
+
export const validateYCoordinates = ({ yCoordinates, addError }) => {
|
|
106
|
+
let error = undefined;
|
|
107
|
+
if (yCoordinates.y1 === yCoordinates.y2) {
|
|
108
|
+
const yAxisError = {
|
|
109
|
+
error: buildError(BuildError.LINE_CHART_Y_AXIS_ZERO_LENGTH),
|
|
110
|
+
};
|
|
111
|
+
addError?.('LINE_CHART_Y_AXIS_ERROR', yAxisError);
|
|
112
|
+
if (!error) {
|
|
113
|
+
error = yAxisError;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return { error };
|
|
117
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chartText.d.ts","sourceRoot":"","sources":["../../../../src/components/chartText/chartText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"chartText.d.ts","sourceRoot":"","sources":["../../../../src/components/chartText/chartText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAMxC,CAAC"}
|
|
@@ -13,6 +13,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
13
13
|
* @param {React.ReactNode} props.children - The text content to be rendered within the `<text>` element.
|
|
14
14
|
* @returns {React.ReactElement} A React element representing the SVG text.
|
|
15
15
|
*/
|
|
16
|
-
export const ChartText = ({ children, className = 'circle',
|
|
17
|
-
return (_jsx("text", { className: className,
|
|
16
|
+
export const ChartText = ({ children, className = 'circle', ...props }) => {
|
|
17
|
+
return (_jsx("text", { className: className, ...props, children: children }));
|
|
18
18
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
import type { FocusConfig } from '../../../types/focusConfig.type';
|
|
3
|
+
export interface FocusRingInlineProps {
|
|
4
|
+
children: ReactElement;
|
|
5
|
+
isFocused: boolean;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
dataTestId?: string;
|
|
8
|
+
focusConfig?: FocusConfig;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* FocusRing component for inline mode (children).
|
|
12
|
+
* Wraps the element and renders focus ring inline with automatic z-order.
|
|
13
|
+
*
|
|
14
|
+
* This component:
|
|
15
|
+
* - Clones the children element and attaches a ref to it
|
|
16
|
+
* - Detects element bounds on mount and when focus state changes
|
|
17
|
+
* - Renders the focus ring BEFORE the element (proper z-order)
|
|
18
|
+
* - Handles both adaptive and bounding-box variants
|
|
19
|
+
* - Preserves any existing ref the children might have
|
|
20
|
+
*
|
|
21
|
+
* @param props - FocusRingInlineProps
|
|
22
|
+
* @returns JSX element with focus ring + wrapped children
|
|
23
|
+
*/
|
|
24
|
+
export declare const FocusRingInline: React.FC<FocusRingInlineProps>;
|
|
25
|
+
//# sourceMappingURL=FocusRingInline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FocusRingInline.d.ts","sourceRoot":"","sources":["../../../../../src/components/focusRing/components/FocusRingInline.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAwB,MAAM,OAAO,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAM5D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAoC1D,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cloneElement, useRef } from 'react';
|
|
3
|
+
import { useFocusRingData } from '../hooks/useFocusRingData';
|
|
4
|
+
import { composeRefs } from '../utils/composeRefs';
|
|
5
|
+
import { FocusRingRenderer } from './FocusRingRenderer';
|
|
6
|
+
/**
|
|
7
|
+
* FocusRing component for inline mode (children).
|
|
8
|
+
* Wraps the element and renders focus ring inline with automatic z-order.
|
|
9
|
+
*
|
|
10
|
+
* This component:
|
|
11
|
+
* - Clones the children element and attaches a ref to it
|
|
12
|
+
* - Detects element bounds on mount and when focus state changes
|
|
13
|
+
* - Renders the focus ring BEFORE the element (proper z-order)
|
|
14
|
+
* - Handles both adaptive and bounding-box variants
|
|
15
|
+
* - Preserves any existing ref the children might have
|
|
16
|
+
*
|
|
17
|
+
* @param props - FocusRingInlineProps
|
|
18
|
+
* @returns JSX element with focus ring + wrapped children
|
|
19
|
+
*/
|
|
20
|
+
export const FocusRingInline = ({ children, dataTestId = 'focus-ring', disabled = false, focusConfig, isFocused, }) => {
|
|
21
|
+
// Create ref for the SVG graphics element
|
|
22
|
+
const childrenRef = useRef(null);
|
|
23
|
+
const { layers } = useFocusRingData({
|
|
24
|
+
elementRef: childrenRef,
|
|
25
|
+
focusConfig,
|
|
26
|
+
isFocused,
|
|
27
|
+
});
|
|
28
|
+
// Extract the ref from children safely
|
|
29
|
+
// Children might have a ref attached, we need to preserve it while adding our own
|
|
30
|
+
const childrenWithRef = children;
|
|
31
|
+
const combinedRef = composeRefs(childrenRef, childrenWithRef.ref);
|
|
32
|
+
// Clone children and add ref (but NOT event handlers - parent manages those)
|
|
33
|
+
const wrappedChildren = cloneElement(children, {
|
|
34
|
+
ref: combinedRef,
|
|
35
|
+
});
|
|
36
|
+
return (_jsxs(_Fragment, { children: [isFocused && !disabled && (_jsx(FocusRingRenderer, { dataTestId: dataTestId, layers: layers ?? undefined })), wrappedChildren] }));
|
|
37
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FocusRingRendererProps } from '../focusRing.types';
|
|
2
|
+
/**
|
|
3
|
+
* Internal component that renders the actual focus ring elements.
|
|
4
|
+
* Supports both adaptive and bounding-box strategies with a unified rendering approach.
|
|
5
|
+
*
|
|
6
|
+
* This is a pure presentational component that receives pre-calculated FocusRingLayers
|
|
7
|
+
* and renders the appropriate SVG elements using React.createElement.
|
|
8
|
+
*
|
|
9
|
+
* @param props - FocusRingRendererProps
|
|
10
|
+
* @returns JSX element with focus ring SVG elements, or null if no valid data
|
|
11
|
+
*/
|
|
12
|
+
export declare const FocusRingRenderer: React.FC<FocusRingRendererProps>;
|
|
13
|
+
//# sourceMappingURL=FocusRingRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FocusRingRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/components/focusRing/components/FocusRingRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAkB9D,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createElement } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Internal component that renders the actual focus ring elements.
|
|
5
|
+
* Supports both adaptive and bounding-box strategies with a unified rendering approach.
|
|
6
|
+
*
|
|
7
|
+
* This is a pure presentational component that receives pre-calculated FocusRingLayers
|
|
8
|
+
* and renders the appropriate SVG elements using React.createElement.
|
|
9
|
+
*
|
|
10
|
+
* @param props - FocusRingRendererProps
|
|
11
|
+
* @returns JSX element with focus ring SVG elements, or null if no valid data
|
|
12
|
+
*/
|
|
13
|
+
export const FocusRingRenderer = ({ dataTestId, layers }) => {
|
|
14
|
+
if (!layers) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
// Unified rendering: both adaptive and bounding-box use the same structure
|
|
18
|
+
return (_jsxs("g", { className: "focus-ring-container", pointerEvents: "none", children: [createElement(layers.outerRing.type, {
|
|
19
|
+
...layers.outerRing.props,
|
|
20
|
+
'data-testid': `${dataTestId}-focus-outer`,
|
|
21
|
+
}), createElement(layers.innerRing.type, {
|
|
22
|
+
...layers.innerRing.props,
|
|
23
|
+
'data-testid': `${dataTestId}-focus-inner`,
|
|
24
|
+
})] }));
|
|
25
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
import type { FocusConfig } from '../../../types/focusConfig.type';
|
|
3
|
+
export interface FocusRingSeparateProps {
|
|
4
|
+
targetRef: RefObject<SVGGraphicsElement>;
|
|
5
|
+
isFocused: boolean;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
dataTestId?: string;
|
|
8
|
+
focusConfig?: FocusConfig;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* FocusRing component for separate mode (targetRef).
|
|
12
|
+
* Renders only the focus ring, allowing precise z-order control.
|
|
13
|
+
*
|
|
14
|
+
* This component:
|
|
15
|
+
* - Uses a ref to the target element (does not wrap it)
|
|
16
|
+
* - Only renders the focus ring (no children cloning)
|
|
17
|
+
* - Allows precise z-order control by controlling where FocusRing is placed in JSX
|
|
18
|
+
* - Handles both adaptive and bounding-box variants
|
|
19
|
+
*
|
|
20
|
+
* **IMPORTANT NOTE: Z-Order with Adaptive Variant**
|
|
21
|
+
*
|
|
22
|
+
* When using `variant: 'adaptive'` (default), the FocusRing **MUST be rendered BEFORE**
|
|
23
|
+
* the target element in SVG document order. Otherwise, focus ring strokes will cover the element.
|
|
24
|
+
*
|
|
25
|
+
* @param props - FocusRingSeparateProps
|
|
26
|
+
* @returns JSX element with only focus ring, or null if not focused/disabled
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* const ref = useRef<SVGCircleElement>(null);
|
|
31
|
+
*
|
|
32
|
+
* // CORRECT: FocusRing before element
|
|
33
|
+
* <>
|
|
34
|
+
* <FocusRingSeparate targetRef={ref} isFocused={true} />
|
|
35
|
+
* <circle ref={ref} cx={50} cy={50} r={30} />
|
|
36
|
+
* </>
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare const FocusRingSeparate: React.FC<FocusRingSeparateProps>;
|
|
40
|
+
//# sourceMappingURL=FocusRingSeparate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FocusRingSeparate.d.ts","sourceRoot":"","sources":["../../../../../src/components/focusRing/components/FocusRingSeparate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAK5D,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;IACzC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAoB9D,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useFocusRingData } from '../hooks/useFocusRingData';
|
|
3
|
+
import { FocusRingRenderer } from './FocusRingRenderer';
|
|
4
|
+
/**
|
|
5
|
+
* FocusRing component for separate mode (targetRef).
|
|
6
|
+
* Renders only the focus ring, allowing precise z-order control.
|
|
7
|
+
*
|
|
8
|
+
* This component:
|
|
9
|
+
* - Uses a ref to the target element (does not wrap it)
|
|
10
|
+
* - Only renders the focus ring (no children cloning)
|
|
11
|
+
* - Allows precise z-order control by controlling where FocusRing is placed in JSX
|
|
12
|
+
* - Handles both adaptive and bounding-box variants
|
|
13
|
+
*
|
|
14
|
+
* **IMPORTANT NOTE: Z-Order with Adaptive Variant**
|
|
15
|
+
*
|
|
16
|
+
* When using `variant: 'adaptive'` (default), the FocusRing **MUST be rendered BEFORE**
|
|
17
|
+
* the target element in SVG document order. Otherwise, focus ring strokes will cover the element.
|
|
18
|
+
*
|
|
19
|
+
* @param props - FocusRingSeparateProps
|
|
20
|
+
* @returns JSX element with only focus ring, or null if not focused/disabled
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* const ref = useRef<SVGCircleElement>(null);
|
|
25
|
+
*
|
|
26
|
+
* // CORRECT: FocusRing before element
|
|
27
|
+
* <>
|
|
28
|
+
* <FocusRingSeparate targetRef={ref} isFocused={true} />
|
|
29
|
+
* <circle ref={ref} cx={50} cy={50} r={30} />
|
|
30
|
+
* </>
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export const FocusRingSeparate = ({ dataTestId = 'focus-ring', disabled = false, focusConfig, isFocused, targetRef, }) => {
|
|
34
|
+
const { layers } = useFocusRingData({
|
|
35
|
+
elementRef: targetRef,
|
|
36
|
+
focusConfig,
|
|
37
|
+
isFocused,
|
|
38
|
+
});
|
|
39
|
+
// Early return if not focused or disabled
|
|
40
|
+
if (!isFocused || disabled) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
// Render focus ring with unified structure
|
|
44
|
+
return _jsx(FocusRingRenderer, { dataTestId: dataTestId, layers: layers });
|
|
45
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.focus-ring-outer {
|
|
2
|
+
/* Ensure focus rings don't interfere with pointer events */
|
|
3
|
+
pointer-events: none;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.focus-ring-inner {
|
|
7
|
+
/* Ensure focus rings don't interfere with pointer events */
|
|
8
|
+
pointer-events: none;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.focus-ring-container {
|
|
12
|
+
/* Ensure focus ring group doesn't interfere with interactions */
|
|
13
|
+
pointer-events: none;
|
|
14
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import './focusRing.css';
|
|
3
|
+
import type { FocusRingProps } from './focusRing.types';
|
|
4
|
+
/**
|
|
5
|
+
* FocusRing - Controlled, purely decorative component for rendering focus rings around SVG elements.
|
|
6
|
+
*
|
|
7
|
+
* **Key Characteristics:**
|
|
8
|
+
* - **Controlled Component**: Parent manages `isFocused` state
|
|
9
|
+
* - **Purely Decorative**: Does not intercept or manage events
|
|
10
|
+
* - **Two Modes**: Inline (children) or Separate (targetRef) rendering
|
|
11
|
+
* - **Zero Configuration**: Automatic element detection
|
|
12
|
+
*
|
|
13
|
+
* **Two Modes:**
|
|
14
|
+
*
|
|
15
|
+
* 1. **Inline (children)** - Wraps element, focus ring rendered inline, z-order handled automatically
|
|
16
|
+
* 2. **Separate (targetRef)** - Only renders focus ring, allows precise z-order control
|
|
17
|
+
*
|
|
18
|
+
* **IMPORTANT NOTE: Z-Order with Adaptive Variant**
|
|
19
|
+
*
|
|
20
|
+
* When using `variant: 'adaptive'` (default) with `targetRef` mode, the FocusRing **MUST be rendered BEFORE**
|
|
21
|
+
* the target element in SVG document order. Otherwise, focus ring strokes will cover the element.
|
|
22
|
+
*
|
|
23
|
+
* ```tsx
|
|
24
|
+
* // CORRECT: FocusRing before element
|
|
25
|
+
* <>
|
|
26
|
+
* <FocusRing targetRef={ref} isFocused={focused} />
|
|
27
|
+
* <circle ref={ref} cx={50} cy={50} r={30} />
|
|
28
|
+
* </>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @param props - FocusRingProps
|
|
32
|
+
* @returns JSX element with focus ring or null
|
|
33
|
+
*/
|
|
34
|
+
export declare const FocusRing: FC<FocusRingProps>;
|
|
35
|
+
//# sourceMappingURL=focusRing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focusRing.d.ts","sourceRoot":"","sources":["../../../../src/components/focusRing/focusRing.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,OAAO,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAsCxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,SAAS,oBAAqB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FocusRingInline } from './components/FocusRingInline';
|
|
3
|
+
import { FocusRingSeparate } from './components/FocusRingSeparate';
|
|
4
|
+
import './focusRing.css';
|
|
5
|
+
const FocusRingComponent = ({ children, dataTestId = 'focus-ring', disabled = false, focusConfig, isFocused, targetRef, }) => {
|
|
6
|
+
if (children) {
|
|
7
|
+
return (_jsx(FocusRingInline, { dataTestId: dataTestId, disabled: disabled, focusConfig: focusConfig, isFocused: isFocused, children: children }));
|
|
8
|
+
}
|
|
9
|
+
if (targetRef) {
|
|
10
|
+
return (_jsx(FocusRingSeparate, { dataTestId: dataTestId, disabled: disabled, focusConfig: focusConfig, isFocused: isFocused, targetRef: targetRef }));
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* FocusRing - Controlled, purely decorative component for rendering focus rings around SVG elements.
|
|
16
|
+
*
|
|
17
|
+
* **Key Characteristics:**
|
|
18
|
+
* - **Controlled Component**: Parent manages `isFocused` state
|
|
19
|
+
* - **Purely Decorative**: Does not intercept or manage events
|
|
20
|
+
* - **Two Modes**: Inline (children) or Separate (targetRef) rendering
|
|
21
|
+
* - **Zero Configuration**: Automatic element detection
|
|
22
|
+
*
|
|
23
|
+
* **Two Modes:**
|
|
24
|
+
*
|
|
25
|
+
* 1. **Inline (children)** - Wraps element, focus ring rendered inline, z-order handled automatically
|
|
26
|
+
* 2. **Separate (targetRef)** - Only renders focus ring, allows precise z-order control
|
|
27
|
+
*
|
|
28
|
+
* **IMPORTANT NOTE: Z-Order with Adaptive Variant**
|
|
29
|
+
*
|
|
30
|
+
* When using `variant: 'adaptive'` (default) with `targetRef` mode, the FocusRing **MUST be rendered BEFORE**
|
|
31
|
+
* the target element in SVG document order. Otherwise, focus ring strokes will cover the element.
|
|
32
|
+
*
|
|
33
|
+
* ```tsx
|
|
34
|
+
* // CORRECT: FocusRing before element
|
|
35
|
+
* <>
|
|
36
|
+
* <FocusRing targetRef={ref} isFocused={focused} />
|
|
37
|
+
* <circle ref={ref} cx={50} cy={50} r={30} />
|
|
38
|
+
* </>
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @param props - FocusRingProps
|
|
42
|
+
* @returns JSX element with focus ring or null
|
|
43
|
+
*/
|
|
44
|
+
export const FocusRing = FocusRingComponent;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ReactElement, RefObject } from 'react';
|
|
2
|
+
import type { FocusConfig } from '../../types/focusConfig.type';
|
|
3
|
+
import type { FocusRingLayers } from './utils/utils.types';
|
|
4
|
+
export interface FocusRingProps {
|
|
5
|
+
/**
|
|
6
|
+
* The SVG graphics element to wrap with focus ring (Mode 1: inline rendering).
|
|
7
|
+
* Must be a renderable SVG element (path, circle, rect, g, etc.).
|
|
8
|
+
* Mutually exclusive with targetRef - provide either children OR targetRef, not both.
|
|
9
|
+
*/
|
|
10
|
+
children?: ReactElement;
|
|
11
|
+
/**
|
|
12
|
+
* Reference to external SVG graphics element (Mode 2: separate rendering).
|
|
13
|
+
* Must be a renderable SVG element (path, circle, rect, g, etc.).
|
|
14
|
+
* When provided, only the focus ring is rendered (not the element itself).
|
|
15
|
+
* Mutually exclusive with children - provide either children OR targetRef, not both.
|
|
16
|
+
*/
|
|
17
|
+
targetRef?: RefObject<SVGGraphicsElement>;
|
|
18
|
+
/**
|
|
19
|
+
* Controlled focus state (REQUIRED).
|
|
20
|
+
* The parent component must manage this state and update it based on focus/blur events.
|
|
21
|
+
* FocusRing is purely decorative and does not manage state internally.
|
|
22
|
+
*/
|
|
23
|
+
isFocused: boolean;
|
|
24
|
+
/** Test identifier for the focus ring elements */
|
|
25
|
+
dataTestId?: string;
|
|
26
|
+
/** Whether the focus ring is disabled */
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
/** Configuration for focus ring appearance */
|
|
29
|
+
focusConfig?: FocusConfig;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Props for the internal FocusRingRenderer component
|
|
33
|
+
*/
|
|
34
|
+
export interface FocusRingRendererProps {
|
|
35
|
+
/** Test identifier for the focus ring elements */
|
|
36
|
+
dataTestId: string;
|
|
37
|
+
/** Pre-computed layers (unified structure for both adaptive and bounding-box modes) */
|
|
38
|
+
layers?: FocusRingLayers;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=focusRing.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focusRing.types.d.ts","sourceRoot":"","sources":["../../../../src/components/focusRing/focusRing.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;IAExB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;IAE1C;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAC;IAEnB,uFAAuF;IACvF,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
import { type FocusConfig } from '../../../types/focusConfig.type';
|
|
3
|
+
import type { FocusRingLayers } from '../utils/utils.types';
|
|
4
|
+
export interface UseFocusRingDataOptions {
|
|
5
|
+
elementRef: RefObject<SVGGraphicsElement>;
|
|
6
|
+
isFocused: boolean;
|
|
7
|
+
focusConfig?: FocusConfig;
|
|
8
|
+
}
|
|
9
|
+
export interface FocusRingData {
|
|
10
|
+
resolvedConfig: Required<FocusConfig>;
|
|
11
|
+
layers: FocusRingLayers | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Hook that handles all focus ring data calculation logic.
|
|
15
|
+
* Separated from rendering concerns for better testability and reusability.
|
|
16
|
+
*
|
|
17
|
+
* This hook:
|
|
18
|
+
* - Generates layers for both adaptive and bounding-box variants
|
|
19
|
+
* - Both variants return the same FocusRingLayers structure
|
|
20
|
+
* - Only calculates what's needed based on the variant
|
|
21
|
+
* - Manages all the state and effects related to focus ring data
|
|
22
|
+
*
|
|
23
|
+
* @param options - Configuration options for the hook
|
|
24
|
+
* @returns Focus ring data including resolved config and calculated layers
|
|
25
|
+
*/
|
|
26
|
+
export declare function useFocusRingData({ elementRef, focusConfig, isFocused, }: UseFocusRingDataOptions): FocusRingData;
|
|
27
|
+
//# sourceMappingURL=useFocusRingData.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFocusRingData.d.ts","sourceRoot":"","sources":["../../../../../src/components/focusRing/hooks/useFocusRingData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAgC,MAAM,OAAO,CAAC;AAErE,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,0BAA0B,CAAC;AAO5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,SAAS,CAAC,kBAAkB,CAAC,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACtC,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;CACrC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,UAAU,EACV,WAAW,EACX,SAAS,GACV,EAAE,uBAAuB,GAAG,aAAa,CA+DzC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { getFocusConfig } from '../../../types/focusConfig.type';
|
|
3
|
+
import { SVG_GEOMETRIC_ATTRIBUTES, createAdaptiveFocusRings, } from '../utils/createAdaptiveFocusRings';
|
|
4
|
+
import { createBoundingBoxFocusRings } from '../utils/createBoundingBoxFocusRings';
|
|
5
|
+
/**
|
|
6
|
+
* Hook that handles all focus ring data calculation logic.
|
|
7
|
+
* Separated from rendering concerns for better testability and reusability.
|
|
8
|
+
*
|
|
9
|
+
* This hook:
|
|
10
|
+
* - Generates layers for both adaptive and bounding-box variants
|
|
11
|
+
* - Both variants return the same FocusRingLayers structure
|
|
12
|
+
* - Only calculates what's needed based on the variant
|
|
13
|
+
* - Manages all the state and effects related to focus ring data
|
|
14
|
+
*
|
|
15
|
+
* @param options - Configuration options for the hook
|
|
16
|
+
* @returns Focus ring data including resolved config and calculated layers
|
|
17
|
+
*/
|
|
18
|
+
export function useFocusRingData({ elementRef, focusConfig, isFocused, }) {
|
|
19
|
+
// Resolve config once at the top
|
|
20
|
+
const resolvedConfig = useMemo(() => getFocusConfig(focusConfig), [focusConfig]);
|
|
21
|
+
const [layers, setLayers] = useState(undefined);
|
|
22
|
+
// Calculation happens when isFocused changes or when focus config changes
|
|
23
|
+
// MutationObserver watches for geometric attribute changes
|
|
24
|
+
// to automatically regenerate layers when the element moves or resizes
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!elementRef?.current || !isFocused) {
|
|
27
|
+
setLayers(undefined);
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const element = elementRef.current;
|
|
31
|
+
// Function to calculate focus ring layers from current DOM state
|
|
32
|
+
const calculateRings = () => {
|
|
33
|
+
// Strategy 1: Adaptive variant - generate layers from DOM element
|
|
34
|
+
if (resolvedConfig.variant === 'adaptive') {
|
|
35
|
+
const adaptiveLayers = createAdaptiveFocusRings(element, resolvedConfig);
|
|
36
|
+
setLayers(adaptiveLayers);
|
|
37
|
+
}
|
|
38
|
+
// Strategy 2: Bounding-box variant - detect bounds and calculate layers
|
|
39
|
+
if (resolvedConfig.variant === 'bounding-box') {
|
|
40
|
+
const boundingBoxLayers = createBoundingBoxFocusRings(element, resolvedConfig);
|
|
41
|
+
setLayers(boundingBoxLayers);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
// Calculate layers initially
|
|
45
|
+
calculateRings();
|
|
46
|
+
// Set up MutationObserver to detect changes in geometric attributes
|
|
47
|
+
// This ensures focus ring updates automatically when the element moves or resizes
|
|
48
|
+
const observer = new MutationObserver(mutations => {
|
|
49
|
+
const hasGeometricChanges = mutations.some(mutation => mutation.type === 'attributes' &&
|
|
50
|
+
SVG_GEOMETRIC_ATTRIBUTES.includes(mutation.attributeName ?? ''));
|
|
51
|
+
if (hasGeometricChanges) {
|
|
52
|
+
// Recalculate focus rings on relevant attribute changes
|
|
53
|
+
calculateRings();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Observe only geometric attributes that affect position and size
|
|
57
|
+
observer.observe(element, {
|
|
58
|
+
attributeFilter: [...SVG_GEOMETRIC_ATTRIBUTES],
|
|
59
|
+
attributes: true,
|
|
60
|
+
});
|
|
61
|
+
return () => observer.disconnect();
|
|
62
|
+
}, [isFocused, resolvedConfig]);
|
|
63
|
+
return {
|
|
64
|
+
layers,
|
|
65
|
+
resolvedConfig,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/focusRing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FocusRing } from './focusRing';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ForwardedRef } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Composes multiple refs into a single ref callback
|
|
4
|
+
* Allows using both internal and external refs simultaneously
|
|
5
|
+
*/
|
|
6
|
+
export declare function composeRefs<T>(...refs: Array<ForwardedRef<T> | undefined>): (instance: T | null) => void;
|
|
7
|
+
//# sourceMappingURL=composeRefs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composeRefs.d.ts","sourceRoot":"","sources":["../../../../../src/components/focusRing/utils/composeRefs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,GAAG,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAC1C,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAU9B"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composes multiple refs into a single ref callback
|
|
3
|
+
* Allows using both internal and external refs simultaneously
|
|
4
|
+
*/
|
|
5
|
+
export function composeRefs(...refs) {
|
|
6
|
+
return (instance) => {
|
|
7
|
+
refs.forEach(ref => {
|
|
8
|
+
if (typeof ref === 'function') {
|
|
9
|
+
ref(instance);
|
|
10
|
+
}
|
|
11
|
+
else if (ref) {
|
|
12
|
+
ref.current = instance;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { FocusConfig } from '../../../types/focusConfig.type';
|
|
2
|
+
import type { FocusRingLayers } from './utils.types';
|
|
3
|
+
/**
|
|
4
|
+
* SVG geometric attributes that define shape position and dimensions.
|
|
5
|
+
* These attributes are extracted from the original element to create focus rings.
|
|
6
|
+
* Also used by MutationObserver to detect when focus rings need to be regenerated.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SVG_GEOMETRIC_ATTRIBUTES: string[];
|
|
9
|
+
/**
|
|
10
|
+
* Creates adaptive focus ring layers from a DOM SVGElement.
|
|
11
|
+
*
|
|
12
|
+
* This function reads properties directly from the DOM element and creates
|
|
13
|
+
* props objects for rendering new SVG elements with scaled stroke-width for the focus rings.
|
|
14
|
+
* The focus rings adapt to the exact shape of the element (circle → circle, path → path, etc.)
|
|
15
|
+
*
|
|
16
|
+
* This unified approach works for both targetRef and children modes by
|
|
17
|
+
* reading from the mounted DOM element.
|
|
18
|
+
*
|
|
19
|
+
* @param element - The SVG graphics element to create focus rings for
|
|
20
|
+
* @param focusConfig - Focus ring configuration (colors, widths, gap)
|
|
21
|
+
* @returns Focus ring layers (outer and inner props) or null if not supported
|
|
22
|
+
*/
|
|
23
|
+
export declare function createAdaptiveFocusRings(element: SVGGraphicsElement, focusConfig: Required<FocusConfig>): FocusRingLayers | undefined;
|
|
24
|
+
//# sourceMappingURL=createAdaptiveFocusRings.d.ts.map
|