Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 3 additions & 32 deletions src/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,9 @@ import {

import classnames from 'classnames';

import './editor.scss';

// Custom hook for number formatting
function useNumberFormatter(number, decimalSeparator, minimumFractionDigits) {
const formatNumber = (numberToFormat) => {
if (!numberToFormat && numberToFormat !== 0) {
return numberToFormat;
}

if (decimalSeparator === 'none') {
return numberToFormat.toString();
} else if (decimalSeparator === '.' || decimalSeparator === ',') {
return (numberToFormat || 0)
.toString()
.replace('.', decimalSeparator);
}

const options = {
minimumFractionDigits: minimumFractionDigits || 0,
};
import { formatNumber } from './utils/format-number';

try {
return new Intl.NumberFormat(decimalSeparator, options).format(
numberToFormat
);
} catch (error) {
return numberToFormat.toString();
}
};

return formatNumber(number);
}
import './editor.scss';

export default function Edit({ attributes, setAttributes }) {
const {
Expand All @@ -63,7 +34,7 @@ export default function Edit({ attributes, setAttributes }) {
} = attributes;

const numberRef = useRef();
const formattedNumber = useNumberFormatter(
const formattedNumber = formatNumber(
number,
decimalSeparator,
minimumFractionDigits
Expand Down
28 changes: 2 additions & 26 deletions src/number-formatter.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,8 @@
/**
* Number formatting utility for Key Figure blocks
* Frontend-only formatting (editor formatting handled in React components)
* Number formatting utility for Key Figure blocks (frontend).
*/

function formatNumber(numberToFormat, decimalSeparator, minimumFractionDigits) {
if (!numberToFormat && numberToFormat !== 0) {
return numberToFormat;
}

if (decimalSeparator === 'none') {
return numberToFormat.toString();
} else if (decimalSeparator === '.' || decimalSeparator === ',') {
return (numberToFormat || 0).toString().replace('.', decimalSeparator);
}

const options = {
minimumFractionDigits: minimumFractionDigits || 0,
};

try {
return new Intl.NumberFormat(decimalSeparator, options).format(
numberToFormat
);
} catch (error) {
// Fallback to simple string conversion if formatting fails
return numberToFormat.toString();
}
}
import { formatNumber } from './utils/format-number';

function initializeNumberFormatting() {
// Only run on frontend (not in editor)
Expand Down
54 changes: 54 additions & 0 deletions src/utils/format-number.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Intl.NumberFormat (e.g. fr-FR) may insert U+202F (narrow no-break space) as the
* thousands separator. Some fonts in Chromium ignore letter-spacing on text that
* contains U+202F. Thin space (U+2009) keeps grouped digits readable and allows
* CSS tracking (letter-spacing).
*/
const INTNL_NARROW_NO_BREAK_SPACE = /\u202f/g;
const THIN_SPACE = '\u2009';

/**
* @param {string} formatted Formatted number string from Intl.
* @return {string} Formatted number with thousands separators safe for CSS tracking.
*/
function normalizeIntlFormattedNumber(formatted) {
return formatted.replace(INTNL_NARROW_NO_BREAK_SPACE, THIN_SPACE);
}

/**
* @param {number} numberToFormat Value to format.
* @param {string} decimalSeparator Locale id, "none", or literal "." / "," separator.
* @param {number|string} minimumFractionDigits Minimum fraction digits for Intl locales.
* @return {string|number|undefined} Formatted value, or the input when formatting is skipped.
*/
export function formatNumber(
numberToFormat,
decimalSeparator,
minimumFractionDigits
) {
if (!numberToFormat && numberToFormat !== 0) {
return numberToFormat;
}

if (decimalSeparator === 'none') {
return numberToFormat.toString();
}

if (decimalSeparator === '.' || decimalSeparator === ',') {
return (numberToFormat || 0).toString().replace('.', decimalSeparator);
}

const options = {
minimumFractionDigits: minimumFractionDigits || 0,
};

try {
return normalizeIntlFormattedNumber(
new Intl.NumberFormat(decimalSeparator, options).format(
numberToFormat
)
);
} catch (error) {
return numberToFormat.toString();
}
}
Loading