diff --git a/docs/components/mdx/CodeTabs.jsx b/docs/components/mdx/CodeTabs.jsx
index dd3c6fbc3f7e8..b20269df0b2b5 100644
--- a/docs/components/mdx/CodeTabs.jsx
+++ b/docs/components/mdx/CodeTabs.jsx
@@ -1,6 +1,6 @@
'use client'
-import React, { useState, useEffect, useRef, useCallback } from 'react'
+import React, { useState, useEffect, useLayoutEffect, useRef, useCallback } from 'react'
import styles from './CodeTabs.module.css'
const langs = {
@@ -23,6 +23,7 @@ const PREFERRED_LANGS = ['yaml', 'python']
export const CodeTabs = ({ children }) => {
const containerRef = useRef(null)
+ const scrollAnchorRef = useRef(null)
const [codeBlocks, setCodeBlocks] = useState([])
const [selectedTab, setSelectedTab] = useState(null)
const [isInitialized, setIsInitialized] = useState(false)
@@ -99,7 +100,7 @@ export const CodeTabs = ({ children }) => {
}, [codeBlocks, isInitialized])
// Update visibility of code blocks based on selected tab
- useEffect(() => {
+ useLayoutEffect(() => {
if (!containerRef.current || !selectedTab || codeBlocks.length === 0) return
codeBlocks.forEach((block) => {
@@ -107,6 +108,16 @@ export const CodeTabs = ({ children }) => {
block.wrapper.style.display = block.lang === selectedTab ? 'block' : 'none'
}
})
+
+ // Correct scroll when tab heights change across synced CodeTabs instances
+ if (scrollAnchorRef.current) {
+ const newTop = containerRef.current.getBoundingClientRect().top
+ const delta = newTop - scrollAnchorRef.current
+ if (delta !== 0) {
+ window.scrollBy(0, delta)
+ }
+ scrollAnchorRef.current = null
+ }
}, [selectedTab, codeBlocks])
// Get unique languages maintaining order
@@ -123,6 +134,10 @@ export const CodeTabs = ({ children }) => {
const handleTabClick = useCallback((lang) => {
if (lang !== selectedTab) {
+ if (containerRef.current) {
+ scrollAnchorRef.current = containerRef.current.getBoundingClientRect().top
+ }
+
if (lang === 'python' || lang === 'javascript' || lang === 'yaml') {
localStorage.setItem(STORAGE_KEY, lang)
window.dispatchEvent(
diff --git a/docs/content/cube-core-logo.png b/docs/content/cube-core-logo.png
new file mode 100644
index 0000000000000..2132bf291a841
Binary files /dev/null and b/docs/content/cube-core-logo.png differ
diff --git a/docs/content/product/data-modeling/reference/types-and-formats.mdx b/docs/content/product/data-modeling/reference/types-and-formats.mdx
index ff394b4b86b6f..e6011881eb927 100644
--- a/docs/content/product/data-modeling/reference/types-and-formats.mdx
+++ b/docs/content/product/data-modeling/reference/types-and-formats.mdx
@@ -624,6 +624,100 @@ cubes:
+### Custom numeric formats
+
+Measures with numeric types support custom formatting
+using [d3-format][link-d3-format] specifier strings.
+
+
+
+Custom numeric formatting is subject to support in [visualization tools][ref-viz-tools].
+Check [APIs & Integrations][ref-apis-support] for details.
+
+
+
+
+
+```javascript
+cube(`orders`, {
+ // ...
+
+ measures: {
+ total_amount: {
+ sql: `amount`,
+ type: `sum`,
+ format: `$,.2f`
+ }
+ }
+})
+```
+
+```yaml
+cubes:
+ - name: orders
+ # ...
+
+ measures:
+ - name: total_amount
+ sql: amount
+ type: sum
+ format: "$,.2f"
+```
+
+
+
+#### Common format examples
+
+| Format string | Description | Example output |
+|---------------|-------------|----------------|
+| `.2f` | Fixed-point, 2 decimal places | 1234.57 |
+| `,.0f` | Grouped thousands, no decimals | 1,235 |
+| `$,.2f` | Currency with grouped thousands | $1,234.57 |
+| `.0%` | Percentage, no decimals | 12% |
+| `.2s` | SI prefix, 2 significant digits | 1.2k |
+| `+.2f` | Explicit sign, 2 decimal places | +1234.57 |
+| `.2~f` | Trimmed trailing zeros, 2 decimals | 1234.5 |
+
+#### Format specifier syntax
+
+The full syntax for a d3-format specifier is:
+
+```
+[[fill]align][sign][symbol][0][width][,][.precision][~][type]
+```
+
+| Component | Description |
+|-----------|-------------|
+| `fill` | Character to use for padding |
+| `align` | `>` (right), `<` (left), `^` (center), `=` (pad after sign) |
+| `sign` | `-` (negative only, default), `+` (positive and negative), `(` (parentheses for negative) |
+| `symbol` | `$` (currency prefix), `#` (alternate form for binary/octal/hex) |
+| `0` | Enable zero-padding (shorthand for `fill=0` with `align==`) |
+| `width` | Minimum field width |
+| `,` | Enable comma grouping separator |
+| `.precision` | Number of digits after the decimal point (for `f`, `%`) or significant digits (for other types) |
+| `~` | Trim trailing zeros |
+| `type` | Output format type (see table below) |
+
+#### Supported type characters
+
+| Type | Description |
+|------|-------------|
+| `f` | Fixed-point notation |
+| `e` | Exponent notation |
+| `g` | Either decimal or exponent notation, rounded to significant digits |
+| `r` | Decimal notation, rounded to significant digits |
+| `s` | Decimal notation with an SI prefix, rounded to significant digits |
+| `%` | Multiply by 100 and format with `f`, followed by percent sign |
+| `p` | Multiply by 100, round to significant digits, followed by percent sign |
+| `d` | Integer; ignores non-integer values |
+| `b` | Binary |
+| `o` | Octal |
+| `x` | Hexadecimal (lowercase) |
+| `X` | Hexadecimal (uppercase) |
+| `c` | Character data (converts integer to Unicode) |
+| (none) | Similar to `g`, but trims trailing zeros |
+
## Dimension Types
This section describes the various types that can be assigned to a
@@ -832,7 +926,7 @@ cubes:
When `switch` dimensions are queried or introspected using the [`/v1/meta` REST API
-endpoint][ref-meta-api], they are represented as dimensions of type `string`.
+endpoint][ref-meta-api], they are represented as dimensions of type `string`.
@@ -1073,6 +1167,52 @@ cubes:
+### Custom numeric formats
+
+Dimensions with the `number` type support custom formatting using
+[d3-format][link-d3-format] specifier strings.
+
+
+
+Custom numeric formatting is subject to support in [visualization tools][ref-viz-tools].
+Check [APIs & Integrations][ref-apis-support] for details.
+
+
+
+
+
+```javascript
+cube(`orders`, {
+ // ...
+
+ dimensions: {
+ amount: {
+ sql: `amount`,
+ type: `number`,
+ format: `$,.2f`
+ }
+ }
+})
+```
+
+```yaml
+cubes:
+ - name: orders
+ # ...
+
+ dimensions:
+ - name: amount
+ sql: amount
+ type: number
+ format: "$,.2f"
+```
+
+
+
+See the [Custom numeric formats](#custom-numeric-formats) section under [Measure
+Formats](#measure-formats) for the full format specifier syntax and supported
+type characters.
+
### Custom time formats
Dimensions with `time` type support custom formatting using
@@ -1179,4 +1319,5 @@ cubes:
[ref-meta-api]: /product/apis-integrations/rest-api/reference#base_pathv1meta
[ref-explore]: /product/exploration/explore
[ref-workbooks]: /product/exploration/workbooks
-[ref-dashboards]: /product/presentation/dashboards
\ No newline at end of file
+[ref-dashboards]: /product/presentation/dashboards
+[link-d3-format]: https://d3js.org/d3-format
diff --git a/docs/package.json b/docs/package.json
index 16e522e3f130b..401ed047950be 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -15,7 +15,7 @@
"@radix-ui/react-navigation-menu": "^1.2.14",
"algoliasearch": "^5.49.0",
"cubedev-tracking": "1.1.0",
- "next": "^16.1.6",
+ "next": "^16.1.7",
"nextra": "^4.6.1",
"nextra-theme-docs": "^4.6.1",
"react": "^19.2.4",
diff --git a/docs/yarn.lock b/docs/yarn.lock
index ecee9ac22e093..d2ecd3ff8c8c3 100644
--- a/docs/yarn.lock
+++ b/docs/yarn.lock
@@ -670,50 +670,50 @@
"@napi-rs/simple-git-win32-ia32-msvc" "0.1.22"
"@napi-rs/simple-git-win32-x64-msvc" "0.1.22"
-"@next/env@16.1.6":
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/@next/env/-/env-16.1.6.tgz#0f85979498249a94ef606ef535042a831f905e89"
- integrity sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==
-
-"@next/swc-darwin-arm64@16.1.6":
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.6.tgz#fbe1e360efdcc9ebd0a10301518275bc59e12a91"
- integrity sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==
-
-"@next/swc-darwin-x64@16.1.6":
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.6.tgz#0e3781ef3abc8251c2a21addc733d9a87f44829b"
- integrity sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==
-
-"@next/swc-linux-arm64-gnu@16.1.6":
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.6.tgz#b24511af2c6129f2deaf5c8c04d297fe09cd40d7"
- integrity sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==
-
-"@next/swc-linux-arm64-musl@16.1.6":
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.6.tgz#9d4ed0565689fc6a867250f994736a5b8c542ccb"
- integrity sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==
-
-"@next/swc-linux-x64-gnu@16.1.6":
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.6.tgz#cc757f4384e7eab7d3dba704a97f737518bae0d2"
- integrity sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==
-
-"@next/swc-linux-x64-musl@16.1.6":
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.6.tgz#ef1341740f29717deea7c6ec27ae6269386e20d1"
- integrity sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==
-
-"@next/swc-win32-arm64-msvc@16.1.6":
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.6.tgz#fee8719242aecf9c39c3a66f1f73821f7884dd16"
- integrity sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==
-
-"@next/swc-win32-x64-msvc@16.1.6":
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.6.tgz#60c27323c30f35722b20fd6d62449fbb768e46d9"
- integrity sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==
+"@next/env@16.1.7":
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/@next/env/-/env-16.1.7.tgz#169482a9a76aab0d9360813df898a88667d79ffc"
+ integrity sha512-rJJbIdJB/RQr2F1nylZr/PJzamvNNhfr3brdKP6s/GW850jbtR70QlSfFselvIBbcPUOlQwBakexjFzqLzF6pg==
+
+"@next/swc-darwin-arm64@16.1.7":
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.7.tgz#6022bec143c23837ca4744fee4ab48b0f74b0faa"
+ integrity sha512-b2wWIE8sABdyafc4IM8r5Y/dS6kD80JRtOGrUiKTsACFQfWWgUQ2NwoUX1yjFMXVsAwcQeNpnucF2ZrujsBBPg==
+
+"@next/swc-darwin-x64@16.1.7":
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.7.tgz#3f1604e5a59645a0394b74e50791ff2c477167b8"
+ integrity sha512-zcnVaaZulS1WL0Ss38R5Q6D2gz7MtBu8GZLPfK+73D/hp4GFMrC2sudLky1QibfV7h6RJBJs/gOFvYP0X7UVlQ==
+
+"@next/swc-linux-arm64-gnu@16.1.7":
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.7.tgz#458c98c8b790efa30bc2866f715352ba3cb47cb5"
+ integrity sha512-2ant89Lux/Q3VyC8vNVg7uBaFVP9SwoK2jJOOR0L8TQnX8CAYnh4uctAScy2Hwj2dgjVHqHLORQZJ2wH6VxhSQ==
+
+"@next/swc-linux-arm64-musl@16.1.7":
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.7.tgz#1a6ae4d0894f8751f8951ca0fed6e103e27bfc7a"
+ integrity sha512-uufcze7LYv0FQg9GnNeZ3/whYfo+1Q3HnQpm16o6Uyi0OVzLlk2ZWoY7j07KADZFY8qwDbsmFnMQP3p3+Ftprw==
+
+"@next/swc-linux-x64-gnu@16.1.7":
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.7.tgz#183126cfbf45a96e3b3b37e35b5429e4c48795bd"
+ integrity sha512-KWVf2gxYvHtvuT+c4MBOGxuse5TD7DsMFYSxVxRBnOzok/xryNeQSjXgxSv9QpIVlaGzEn/pIuI6Koosx8CGWA==
+
+"@next/swc-linux-x64-musl@16.1.7":
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.7.tgz#59906d387aa934fc2d066ff6c0ba695ebc904381"
+ integrity sha512-HguhaGwsGr1YAGs68uRKc4aGWxLET+NevJskOcCAwXbwj0fYX0RgZW2gsOCzr9S11CSQPIkxmoSbuVaBp4Z3dA==
+
+"@next/swc-win32-arm64-msvc@16.1.7":
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.7.tgz#e97a31605ca10e5ca493555f840e4972496ce350"
+ integrity sha512-S0n3KrDJokKTeFyM/vGGGR8+pCmXYrjNTk2ZozOL1C/JFdfUIL9O1ATaJOl5r2POe56iRChbsszrjMAdWSv7kQ==
+
+"@next/swc-win32-x64-msvc@16.1.7":
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.7.tgz#eeaf9fb75de437232e1c8b46d16d1ba8b0c635c2"
+ integrity sha512-mwgtg8CNZGYm06LeEd+bNnOUfwOyNem/rOiP14Lsz+AnUY92Zq/LXwtebtUiaeVkhbroRCQ0c8GlR4UT1U+0yg==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
@@ -1471,10 +1471,10 @@ balanced-match@^4.0.2:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.3.tgz#6337a2f23e0604a30481423432f99eac603599f9"
integrity sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==
-baseline-browser-mapping@^2.8.3:
- version "2.9.19"
- resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488"
- integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==
+baseline-browser-mapping@^2.9.19:
+ version "2.10.8"
+ resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.8.tgz#23d1cea1a85b181c2b8660b6cfe626dc2fb15630"
+ integrity sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ==
better-react-mathjax@^2.3.0:
version "2.3.0"
@@ -3278,26 +3278,26 @@ next-themes@^0.4.0:
resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.4.6.tgz#8d7e92d03b8fea6582892a50a928c9b23502e8b6"
integrity sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==
-next@^16.1.6:
- version "16.1.6"
- resolved "https://registry.yarnpkg.com/next/-/next-16.1.6.tgz#24a861371cbe211be7760d9a89ddf2415e3824de"
- integrity sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==
+next@^16.1.7:
+ version "16.1.7"
+ resolved "https://registry.yarnpkg.com/next/-/next-16.1.7.tgz#fccdda75050ffc11ace27526b8a9ac7c308c8c48"
+ integrity sha512-WM0L7WrSvKwoLegLYr6V+mz+RIofqQgVAfHhMp9a88ms0cFX8iX9ew+snpWlSBwpkURJOUdvCEt3uLl3NNzvWg==
dependencies:
- "@next/env" "16.1.6"
+ "@next/env" "16.1.7"
"@swc/helpers" "0.5.15"
- baseline-browser-mapping "^2.8.3"
+ baseline-browser-mapping "^2.9.19"
caniuse-lite "^1.0.30001579"
postcss "8.4.31"
styled-jsx "5.1.6"
optionalDependencies:
- "@next/swc-darwin-arm64" "16.1.6"
- "@next/swc-darwin-x64" "16.1.6"
- "@next/swc-linux-arm64-gnu" "16.1.6"
- "@next/swc-linux-arm64-musl" "16.1.6"
- "@next/swc-linux-x64-gnu" "16.1.6"
- "@next/swc-linux-x64-musl" "16.1.6"
- "@next/swc-win32-arm64-msvc" "16.1.6"
- "@next/swc-win32-x64-msvc" "16.1.6"
+ "@next/swc-darwin-arm64" "16.1.7"
+ "@next/swc-darwin-x64" "16.1.7"
+ "@next/swc-linux-arm64-gnu" "16.1.7"
+ "@next/swc-linux-arm64-musl" "16.1.7"
+ "@next/swc-linux-x64-gnu" "16.1.7"
+ "@next/swc-linux-x64-musl" "16.1.7"
+ "@next/swc-win32-arm64-msvc" "16.1.7"
+ "@next/swc-win32-x64-msvc" "16.1.7"
sharp "^0.34.4"
nextra-theme-docs@^4.6.1: