@dataverse-kit/fluent-theme 0.2.0 → 0.3.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/README.md CHANGED
@@ -21,6 +21,7 @@ import { createDynamicsV9Theme } from '@dataverse-kit/fluent-theme';
21
21
  | `createDynamicsV9Theme(brand?)` | Light theme. Pass your own `BrandVariants` to rebrand. |
22
22
  | `createDynamicsV9DarkTheme(brand?)` | Dark theme, same ramp. |
23
23
  | `dynamicsV9Theme` / `dynamicsV9DarkTheme` | Memoized module singletons. |
24
+ | `createDynamicsCeTheme()` / `dynamicsCeTheme` | The Dynamics CE model-driven **new look**. Measured on a live org: every form colour, shadow and radius, *including the brand* (`#0f6cbd`, with links in `#115ea3`), is an unmodified `webLightTheme` token (typography is not fully stock; see design-tokens `ceForm`). Use this when a surface must look identical to a current Dynamics form, and the V9 theme above when it must match the classic `#0078d4`. Returns a copy. Evidence: `apps/ce-parity/reference/`. |
24
25
 
25
26
  ## Why this is a package
26
27
 
package/dist/index.cjs CHANGED
@@ -20,9 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
+ createDynamicsCeTheme: () => createDynamicsCeTheme,
23
24
  createDynamicsV9DarkTheme: () => createDynamicsV9DarkTheme,
24
25
  createDynamicsV9Theme: () => createDynamicsV9Theme,
25
26
  dynamicsBrandRamp: () => dynamicsBrandRamp,
27
+ dynamicsCeTheme: () => dynamicsCeTheme,
26
28
  dynamicsV9DarkTheme: () => dynamicsV9DarkTheme,
27
29
  dynamicsV9Theme: () => dynamicsV9Theme
28
30
  });
@@ -63,11 +65,17 @@ function createDynamicsV9DarkTheme(brand = defaultBrand) {
63
65
  }
64
66
  var dynamicsV9Theme = createDynamicsV9Theme();
65
67
  var dynamicsV9DarkTheme = createDynamicsV9DarkTheme();
68
+ function createDynamicsCeTheme() {
69
+ return { ...import_react_components.webLightTheme };
70
+ }
71
+ var dynamicsCeTheme = createDynamicsCeTheme();
66
72
  // Annotate the CommonJS export names for ESM import in node:
67
73
  0 && (module.exports = {
74
+ createDynamicsCeTheme,
68
75
  createDynamicsV9DarkTheme,
69
76
  createDynamicsV9Theme,
70
77
  dynamicsBrandRamp,
78
+ dynamicsCeTheme,
71
79
  dynamicsV9DarkTheme,
72
80
  dynamicsV9Theme
73
81
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/brand.ts","../src/theme.ts"],"sourcesContent":["// @dataverse-kit/fluent-theme — the Dynamics CE Fluent UI v9 theme, declared once.\n//\n// Consumed by grid-kit/v9, surface-kit/v9 and agent-kit. See ./brand for why this is a\n// package of its own rather than an addition to @dataverse-kit/design-tokens.\nexport { dynamicsBrandRamp } from './brand';\nexport {\n createDynamicsV9Theme,\n createDynamicsV9DarkTheme,\n dynamicsV9Theme,\n dynamicsV9DarkTheme,\n} from './theme';\n","// The Dynamics CE brand ramp for Fluent UI v9 — THE single declaration.\n//\n// ★ This package exists because this ramp, and the three builders beside it in ./theme,\n// were declared TWICE: packages/surface-kit/src/v9/theme.ts and\n// packages/grid-kit/src/v9/theme.ts, byte-identical across all 16 slots, each with a\n// docstring asserting it was the canonical one. grid-kit's copy even explained itself\n// (\"grid-kit does not depend on @dataverse-kit/design-tokens, so the triad is inlined\n// here\") — which is exactly the shape .claude/rules/verification-lessons.md §4 warns\n// about: a fix applied to one of N copies leaves the other N-1 actively defended by\n// their own comments.\n//\n// ★ It is NOT in @dataverse-kit/design-tokens, which would otherwise be the obvious home,\n// because the builders in ./theme need `createLightTheme` from @fluentui/react-components\n// and design-tokens is zero-dependency by rule (its tsconfig pins `\"paths\": {}`). Moving\n// the ramp alone would have de-duplicated one export of four and left the other three\n// duplicated — so the ramp and its builders travel together, here.\nimport { colors } from '@dataverse-kit/design-tokens';\n\n/**\n * The Fluent web brand ramp (a blue family that already matches Dynamics CE), with the\n * three most-visible shades pinned to the canonical design-tokens brand triad so the v9\n * brand colours come from the same source as the v8 skins'.\n *\n * ★ `BrandVariants` is a structural `Record<Brands, string>` with sixteen required\n * numeric-literal keys (10…160) — no nominal branding. It is typed here by inference\n * rather than as `Record<number, string>`: an index signature does NOT satisfy those\n * sixteen required properties, so that annotation would fail at every `createLightTheme`\n * call site. `theme.ts` asserts the assignability for real.\n */\nexport const dynamicsBrandRamp = {\n 10: '#061724',\n 20: '#082338',\n 30: '#0a2e4a',\n 40: '#0c3b5e',\n 50: '#0e4775',\n 60: colors.brandDark, // #005a9e — colorBrandBackgroundPressed\n 70: colors.brandHover, // #106ebe — colorBrandBackground(Hover/Selected)\n 80: colors.brand, // #0078d4 — colorBrandBackground + colorBrandForeground1 (the Dynamics blue)\n 90: '#2886de',\n 100: '#479ef5',\n 110: '#62abf5',\n 120: '#77b7f7',\n 130: '#96c6fa',\n 140: '#b4d6fa',\n 150: '#cfe4fa',\n 160: '#ebf3fc',\n} as const;\n","// The Dynamics CE Fluent v9 theme builders — the v9 counterpart of surface-kit's v8\n// `createDynamicsTheme()`. Both feed the SAME brand triad (brand / brandHover / brandDark)\n// into their respective theme factories, so a Dynamics-blue button is #0078d4 whichever\n// skin renders it.\nimport {\n createLightTheme,\n createDarkTheme,\n type BrandVariants,\n type Theme,\n} from '@fluentui/react-components';\nimport { dynamicsBrandRamp } from './brand';\n\n// ★ The assignability check that makes ./brand's inferred type safe. If someone re-annotates\n// the ramp as `Record<number, string>` (an index signature, which does not satisfy\n// BrandVariants' sixteen required literal keys) this line fails to compile — at the\n// declaration, not at some downstream consumer's call site.\nconst defaultBrand: BrandVariants = dynamicsBrandRamp;\n\n/**\n * Build a Fluent v9 `Theme` for the Dynamics surfaces. Defaults to the Dynamics-blue brand\n * ramp; pass a custom `BrandVariants` (e.g. from your org's brand) to override.\n * Wrap the app or subtree in `<FluentProvider theme={createDynamicsV9Theme()}>`.\n */\nexport function createDynamicsV9Theme(brand: BrandVariants = defaultBrand): Theme {\n return createLightTheme(brand);\n}\n\n/** Dark-mode variant of the Dynamics v9 theme (same brand ramp). */\nexport function createDynamicsV9DarkTheme(brand: BrandVariants = defaultBrand): Theme {\n return createDarkTheme(brand);\n}\n\n/** The default light Dynamics v9 theme (memoized module singleton). */\nexport const dynamicsV9Theme: Theme = createDynamicsV9Theme();\n\n/** The default dark Dynamics v9 theme (memoized module singleton). */\nexport const dynamicsV9DarkTheme: Theme = createDynamicsV9DarkTheme();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgBA,2BAAuB;AAahB,IAAM,oBAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,4BAAO;AAAA;AAAA,EACX,IAAI,4BAAO;AAAA;AAAA,EACX,IAAI,4BAAO;AAAA;AAAA,EACX,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;;;AC1CA,8BAKO;AAOP,IAAM,eAA8B;AAO7B,SAAS,sBAAsB,QAAuB,cAAqB;AAChF,aAAO,0CAAiB,KAAK;AAC/B;AAGO,SAAS,0BAA0B,QAAuB,cAAqB;AACpF,aAAO,yCAAgB,KAAK;AAC9B;AAGO,IAAM,kBAAyB,sBAAsB;AAGrD,IAAM,sBAA6B,0BAA0B;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/brand.ts","../src/theme.ts"],"sourcesContent":["// @dataverse-kit/fluent-theme — the Dynamics CE Fluent UI v9 theme, declared once.\n//\n// Consumed by grid-kit/v9, surface-kit/v9 and agent-kit. See ./brand for why this is a\n// package of its own rather than an addition to @dataverse-kit/design-tokens.\nexport { dynamicsBrandRamp } from './brand';\nexport {\n createDynamicsV9Theme,\n createDynamicsV9DarkTheme,\n dynamicsV9Theme,\n dynamicsV9DarkTheme,\n createDynamicsCeTheme,\n dynamicsCeTheme,\n} from './theme';\n","// The Dynamics CE brand ramp for Fluent UI v9 — THE single declaration.\n//\n// ★ This package exists because this ramp, and the three builders beside it in ./theme,\n// were declared TWICE: packages/surface-kit/src/v9/theme.ts and\n// packages/grid-kit/src/v9/theme.ts, byte-identical across all 16 slots, each with a\n// docstring asserting it was the canonical one. grid-kit's copy even explained itself\n// (\"grid-kit does not depend on @dataverse-kit/design-tokens, so the triad is inlined\n// here\") — which is exactly the shape .claude/rules/verification-lessons.md §4 warns\n// about: a fix applied to one of N copies leaves the other N-1 actively defended by\n// their own comments.\n//\n// ★ It is NOT in @dataverse-kit/design-tokens, which would otherwise be the obvious home,\n// because the builders in ./theme need `createLightTheme` from @fluentui/react-components\n// and design-tokens is zero-dependency by rule (its tsconfig pins `\"paths\": {}`). Moving\n// the ramp alone would have de-duplicated one export of four and left the other three\n// duplicated — so the ramp and its builders travel together, here.\nimport { colors } from '@dataverse-kit/design-tokens';\n\n/**\n * The Fluent web brand ramp (a blue family that already matches Dynamics CE), with the\n * three most-visible shades pinned to the canonical design-tokens brand triad so the v9\n * brand colours come from the same source as the v8 skins'.\n *\n * ★ `BrandVariants` is a structural `Record<Brands, string>` with sixteen required\n * numeric-literal keys (10…160) — no nominal branding. It is typed here by inference\n * rather than as `Record<number, string>`: an index signature does NOT satisfy those\n * sixteen required properties, so that annotation would fail at every `createLightTheme`\n * call site. `theme.ts` asserts the assignability for real.\n */\nexport const dynamicsBrandRamp = {\n 10: '#061724',\n 20: '#082338',\n 30: '#0a2e4a',\n 40: '#0c3b5e',\n 50: '#0e4775',\n 60: colors.brandDark, // #005a9e — colorBrandBackgroundPressed\n 70: colors.brandHover, // #106ebe — colorBrandBackground(Hover/Selected)\n 80: colors.brand, // #0078d4 — colorBrandBackground + colorBrandForeground1 (the Dynamics blue)\n 90: '#2886de',\n 100: '#479ef5',\n 110: '#62abf5',\n 120: '#77b7f7',\n 130: '#96c6fa',\n 140: '#b4d6fa',\n 150: '#cfe4fa',\n 160: '#ebf3fc',\n} as const;\n","// The Dynamics CE Fluent v9 theme builders — the v9 counterpart of surface-kit's v8\n// `createDynamicsTheme()`. Both feed the SAME brand triad (brand / brandHover / brandDark)\n// into their respective theme factories, so a Dynamics-blue button is #0078d4 whichever\n// skin renders it.\nimport {\n createLightTheme,\n createDarkTheme,\n webLightTheme,\n type BrandVariants,\n type Theme,\n} from '@fluentui/react-components';\nimport { dynamicsBrandRamp } from './brand';\n\n// ★ The assignability check that makes ./brand's inferred type safe. If someone re-annotates\n// the ramp as `Record<number, string>` (an index signature, which does not satisfy\n// BrandVariants' sixteen required literal keys) this line fails to compile — at the\n// declaration, not at some downstream consumer's call site.\nconst defaultBrand: BrandVariants = dynamicsBrandRamp;\n\n/**\n * Build a Fluent v9 `Theme` for the Dynamics surfaces. Defaults to the Dynamics-blue brand\n * ramp; pass a custom `BrandVariants` (e.g. from your org's brand) to override.\n * Wrap the app or subtree in `<FluentProvider theme={createDynamicsV9Theme()}>`.\n */\nexport function createDynamicsV9Theme(brand: BrandVariants = defaultBrand): Theme {\n return createLightTheme(brand);\n}\n\n/** Dark-mode variant of the Dynamics v9 theme (same brand ramp). */\nexport function createDynamicsV9DarkTheme(brand: BrandVariants = defaultBrand): Theme {\n return createDarkTheme(brand);\n}\n\n/** The default light Dynamics v9 theme (memoized module singleton). */\nexport const dynamicsV9Theme: Theme = createDynamicsV9Theme();\n\n/** The default dark Dynamics v9 theme (memoized module singleton). */\nexport const dynamicsV9DarkTheme: Theme = createDynamicsV9DarkTheme();\n\n/**\n * The Dynamics 365 CE model-driven \"new look\" theme: Fluent 2 web light, whose colours, shadows\n * and radii the new look uses unmodified.\n *\n * Measured on a live org (dynamics-ui-kit `apps/ce-parity/reference/`), every colour, shadow and\n * radius the new-look form renders is an unmodified `webLightTheme` token, and so is its brand.\n * Typography is NOT fully stock (tabs are 16px on a 28px line); that lives in the\n * `@dataverse-kit/design-tokens` `ceForm` metrics, which components apply on top of this theme. The tab\n * underline is `#0f6cbd` and links are `#115ea3`. That is Fluent's default web brand ramp, NOT\n * the classic Dynamics `#0078d4` that {@link createDynamicsV9Theme} pins. Use this theme when\n * the goal is to look identical to a current Dynamics form, and `createDynamicsV9Theme` when a\n * surface must match the classic blue.\n *\n * Returns a fresh copy so callers can override tokens without mutating Fluent's singleton.\n */\nexport function createDynamicsCeTheme(): Theme {\n return { ...webLightTheme };\n}\n\n/** The default CE new-look theme (module singleton). */\nexport const dynamicsCeTheme: Theme = createDynamicsCeTheme();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgBA,2BAAuB;AAahB,IAAM,oBAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,4BAAO;AAAA;AAAA,EACX,IAAI,4BAAO;AAAA;AAAA,EACX,IAAI,4BAAO;AAAA;AAAA,EACX,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;;;AC1CA,8BAMO;AAOP,IAAM,eAA8B;AAO7B,SAAS,sBAAsB,QAAuB,cAAqB;AAChF,aAAO,0CAAiB,KAAK;AAC/B;AAGO,SAAS,0BAA0B,QAAuB,cAAqB;AACpF,aAAO,yCAAgB,KAAK;AAC9B;AAGO,IAAM,kBAAyB,sBAAsB;AAGrD,IAAM,sBAA6B,0BAA0B;AAiB7D,SAAS,wBAA+B;AAC7C,SAAO,EAAE,GAAG,sCAAc;AAC5B;AAGO,IAAM,kBAAyB,sBAAsB;","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { BrandVariants, Theme } from '@fluentui/react-components';
1
+ import { Theme, BrandVariants } from '@fluentui/react-components';
2
2
 
3
3
  /**
4
4
  * The Fluent web brand ramp (a blue family that already matches Dynamics CE), with the
@@ -42,5 +42,23 @@ declare function createDynamicsV9DarkTheme(brand?: BrandVariants): Theme;
42
42
  declare const dynamicsV9Theme: Theme;
43
43
  /** The default dark Dynamics v9 theme (memoized module singleton). */
44
44
  declare const dynamicsV9DarkTheme: Theme;
45
+ /**
46
+ * The Dynamics 365 CE model-driven "new look" theme: Fluent 2 web light, whose colours, shadows
47
+ * and radii the new look uses unmodified.
48
+ *
49
+ * Measured on a live org (dynamics-ui-kit `apps/ce-parity/reference/`), every colour, shadow and
50
+ * radius the new-look form renders is an unmodified `webLightTheme` token, and so is its brand.
51
+ * Typography is NOT fully stock (tabs are 16px on a 28px line); that lives in the
52
+ * `@dataverse-kit/design-tokens` `ceForm` metrics, which components apply on top of this theme. The tab
53
+ * underline is `#0f6cbd` and links are `#115ea3`. That is Fluent's default web brand ramp, NOT
54
+ * the classic Dynamics `#0078d4` that {@link createDynamicsV9Theme} pins. Use this theme when
55
+ * the goal is to look identical to a current Dynamics form, and `createDynamicsV9Theme` when a
56
+ * surface must match the classic blue.
57
+ *
58
+ * Returns a fresh copy so callers can override tokens without mutating Fluent's singleton.
59
+ */
60
+ declare function createDynamicsCeTheme(): Theme;
61
+ /** The default CE new-look theme (module singleton). */
62
+ declare const dynamicsCeTheme: Theme;
45
63
 
46
- export { createDynamicsV9DarkTheme, createDynamicsV9Theme, dynamicsBrandRamp, dynamicsV9DarkTheme, dynamicsV9Theme };
64
+ export { createDynamicsCeTheme, createDynamicsV9DarkTheme, createDynamicsV9Theme, dynamicsBrandRamp, dynamicsCeTheme, dynamicsV9DarkTheme, dynamicsV9Theme };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BrandVariants, Theme } from '@fluentui/react-components';
1
+ import { Theme, BrandVariants } from '@fluentui/react-components';
2
2
 
3
3
  /**
4
4
  * The Fluent web brand ramp (a blue family that already matches Dynamics CE), with the
@@ -42,5 +42,23 @@ declare function createDynamicsV9DarkTheme(brand?: BrandVariants): Theme;
42
42
  declare const dynamicsV9Theme: Theme;
43
43
  /** The default dark Dynamics v9 theme (memoized module singleton). */
44
44
  declare const dynamicsV9DarkTheme: Theme;
45
+ /**
46
+ * The Dynamics 365 CE model-driven "new look" theme: Fluent 2 web light, whose colours, shadows
47
+ * and radii the new look uses unmodified.
48
+ *
49
+ * Measured on a live org (dynamics-ui-kit `apps/ce-parity/reference/`), every colour, shadow and
50
+ * radius the new-look form renders is an unmodified `webLightTheme` token, and so is its brand.
51
+ * Typography is NOT fully stock (tabs are 16px on a 28px line); that lives in the
52
+ * `@dataverse-kit/design-tokens` `ceForm` metrics, which components apply on top of this theme. The tab
53
+ * underline is `#0f6cbd` and links are `#115ea3`. That is Fluent's default web brand ramp, NOT
54
+ * the classic Dynamics `#0078d4` that {@link createDynamicsV9Theme} pins. Use this theme when
55
+ * the goal is to look identical to a current Dynamics form, and `createDynamicsV9Theme` when a
56
+ * surface must match the classic blue.
57
+ *
58
+ * Returns a fresh copy so callers can override tokens without mutating Fluent's singleton.
59
+ */
60
+ declare function createDynamicsCeTheme(): Theme;
61
+ /** The default CE new-look theme (module singleton). */
62
+ declare const dynamicsCeTheme: Theme;
45
63
 
46
- export { createDynamicsV9DarkTheme, createDynamicsV9Theme, dynamicsBrandRamp, dynamicsV9DarkTheme, dynamicsV9Theme };
64
+ export { createDynamicsCeTheme, createDynamicsV9DarkTheme, createDynamicsV9Theme, dynamicsBrandRamp, dynamicsCeTheme, dynamicsV9DarkTheme, dynamicsV9Theme };
package/dist/index.mjs CHANGED
@@ -25,7 +25,8 @@ var dynamicsBrandRamp = {
25
25
  // src/theme.ts
26
26
  import {
27
27
  createLightTheme,
28
- createDarkTheme
28
+ createDarkTheme,
29
+ webLightTheme
29
30
  } from "@fluentui/react-components";
30
31
  var defaultBrand = dynamicsBrandRamp;
31
32
  function createDynamicsV9Theme(brand = defaultBrand) {
@@ -36,10 +37,16 @@ function createDynamicsV9DarkTheme(brand = defaultBrand) {
36
37
  }
37
38
  var dynamicsV9Theme = createDynamicsV9Theme();
38
39
  var dynamicsV9DarkTheme = createDynamicsV9DarkTheme();
40
+ function createDynamicsCeTheme() {
41
+ return { ...webLightTheme };
42
+ }
43
+ var dynamicsCeTheme = createDynamicsCeTheme();
39
44
  export {
45
+ createDynamicsCeTheme,
40
46
  createDynamicsV9DarkTheme,
41
47
  createDynamicsV9Theme,
42
48
  dynamicsBrandRamp,
49
+ dynamicsCeTheme,
43
50
  dynamicsV9DarkTheme,
44
51
  dynamicsV9Theme
45
52
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/brand.ts","../src/theme.ts"],"sourcesContent":["// The Dynamics CE brand ramp for Fluent UI v9 — THE single declaration.\n//\n// ★ This package exists because this ramp, and the three builders beside it in ./theme,\n// were declared TWICE: packages/surface-kit/src/v9/theme.ts and\n// packages/grid-kit/src/v9/theme.ts, byte-identical across all 16 slots, each with a\n// docstring asserting it was the canonical one. grid-kit's copy even explained itself\n// (\"grid-kit does not depend on @dataverse-kit/design-tokens, so the triad is inlined\n// here\") — which is exactly the shape .claude/rules/verification-lessons.md §4 warns\n// about: a fix applied to one of N copies leaves the other N-1 actively defended by\n// their own comments.\n//\n// ★ It is NOT in @dataverse-kit/design-tokens, which would otherwise be the obvious home,\n// because the builders in ./theme need `createLightTheme` from @fluentui/react-components\n// and design-tokens is zero-dependency by rule (its tsconfig pins `\"paths\": {}`). Moving\n// the ramp alone would have de-duplicated one export of four and left the other three\n// duplicated — so the ramp and its builders travel together, here.\nimport { colors } from '@dataverse-kit/design-tokens';\n\n/**\n * The Fluent web brand ramp (a blue family that already matches Dynamics CE), with the\n * three most-visible shades pinned to the canonical design-tokens brand triad so the v9\n * brand colours come from the same source as the v8 skins'.\n *\n * ★ `BrandVariants` is a structural `Record<Brands, string>` with sixteen required\n * numeric-literal keys (10…160) — no nominal branding. It is typed here by inference\n * rather than as `Record<number, string>`: an index signature does NOT satisfy those\n * sixteen required properties, so that annotation would fail at every `createLightTheme`\n * call site. `theme.ts` asserts the assignability for real.\n */\nexport const dynamicsBrandRamp = {\n 10: '#061724',\n 20: '#082338',\n 30: '#0a2e4a',\n 40: '#0c3b5e',\n 50: '#0e4775',\n 60: colors.brandDark, // #005a9e — colorBrandBackgroundPressed\n 70: colors.brandHover, // #106ebe — colorBrandBackground(Hover/Selected)\n 80: colors.brand, // #0078d4 — colorBrandBackground + colorBrandForeground1 (the Dynamics blue)\n 90: '#2886de',\n 100: '#479ef5',\n 110: '#62abf5',\n 120: '#77b7f7',\n 130: '#96c6fa',\n 140: '#b4d6fa',\n 150: '#cfe4fa',\n 160: '#ebf3fc',\n} as const;\n","// The Dynamics CE Fluent v9 theme builders — the v9 counterpart of surface-kit's v8\n// `createDynamicsTheme()`. Both feed the SAME brand triad (brand / brandHover / brandDark)\n// into their respective theme factories, so a Dynamics-blue button is #0078d4 whichever\n// skin renders it.\nimport {\n createLightTheme,\n createDarkTheme,\n type BrandVariants,\n type Theme,\n} from '@fluentui/react-components';\nimport { dynamicsBrandRamp } from './brand';\n\n// ★ The assignability check that makes ./brand's inferred type safe. If someone re-annotates\n// the ramp as `Record<number, string>` (an index signature, which does not satisfy\n// BrandVariants' sixteen required literal keys) this line fails to compile — at the\n// declaration, not at some downstream consumer's call site.\nconst defaultBrand: BrandVariants = dynamicsBrandRamp;\n\n/**\n * Build a Fluent v9 `Theme` for the Dynamics surfaces. Defaults to the Dynamics-blue brand\n * ramp; pass a custom `BrandVariants` (e.g. from your org's brand) to override.\n * Wrap the app or subtree in `<FluentProvider theme={createDynamicsV9Theme()}>`.\n */\nexport function createDynamicsV9Theme(brand: BrandVariants = defaultBrand): Theme {\n return createLightTheme(brand);\n}\n\n/** Dark-mode variant of the Dynamics v9 theme (same brand ramp). */\nexport function createDynamicsV9DarkTheme(brand: BrandVariants = defaultBrand): Theme {\n return createDarkTheme(brand);\n}\n\n/** The default light Dynamics v9 theme (memoized module singleton). */\nexport const dynamicsV9Theme: Theme = createDynamicsV9Theme();\n\n/** The default dark Dynamics v9 theme (memoized module singleton). */\nexport const dynamicsV9DarkTheme: Theme = createDynamicsV9DarkTheme();\n"],"mappings":";AAgBA,SAAS,cAAc;AAahB,IAAM,oBAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,OAAO;AAAA;AAAA,EACX,IAAI,OAAO;AAAA;AAAA,EACX,IAAI,OAAO;AAAA;AAAA,EACX,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;;;AC1CA;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAOP,IAAM,eAA8B;AAO7B,SAAS,sBAAsB,QAAuB,cAAqB;AAChF,SAAO,iBAAiB,KAAK;AAC/B;AAGO,SAAS,0BAA0B,QAAuB,cAAqB;AACpF,SAAO,gBAAgB,KAAK;AAC9B;AAGO,IAAM,kBAAyB,sBAAsB;AAGrD,IAAM,sBAA6B,0BAA0B;","names":[]}
1
+ {"version":3,"sources":["../src/brand.ts","../src/theme.ts"],"sourcesContent":["// The Dynamics CE brand ramp for Fluent UI v9 — THE single declaration.\n//\n// ★ This package exists because this ramp, and the three builders beside it in ./theme,\n// were declared TWICE: packages/surface-kit/src/v9/theme.ts and\n// packages/grid-kit/src/v9/theme.ts, byte-identical across all 16 slots, each with a\n// docstring asserting it was the canonical one. grid-kit's copy even explained itself\n// (\"grid-kit does not depend on @dataverse-kit/design-tokens, so the triad is inlined\n// here\") — which is exactly the shape .claude/rules/verification-lessons.md §4 warns\n// about: a fix applied to one of N copies leaves the other N-1 actively defended by\n// their own comments.\n//\n// ★ It is NOT in @dataverse-kit/design-tokens, which would otherwise be the obvious home,\n// because the builders in ./theme need `createLightTheme` from @fluentui/react-components\n// and design-tokens is zero-dependency by rule (its tsconfig pins `\"paths\": {}`). Moving\n// the ramp alone would have de-duplicated one export of four and left the other three\n// duplicated — so the ramp and its builders travel together, here.\nimport { colors } from '@dataverse-kit/design-tokens';\n\n/**\n * The Fluent web brand ramp (a blue family that already matches Dynamics CE), with the\n * three most-visible shades pinned to the canonical design-tokens brand triad so the v9\n * brand colours come from the same source as the v8 skins'.\n *\n * ★ `BrandVariants` is a structural `Record<Brands, string>` with sixteen required\n * numeric-literal keys (10…160) — no nominal branding. It is typed here by inference\n * rather than as `Record<number, string>`: an index signature does NOT satisfy those\n * sixteen required properties, so that annotation would fail at every `createLightTheme`\n * call site. `theme.ts` asserts the assignability for real.\n */\nexport const dynamicsBrandRamp = {\n 10: '#061724',\n 20: '#082338',\n 30: '#0a2e4a',\n 40: '#0c3b5e',\n 50: '#0e4775',\n 60: colors.brandDark, // #005a9e — colorBrandBackgroundPressed\n 70: colors.brandHover, // #106ebe — colorBrandBackground(Hover/Selected)\n 80: colors.brand, // #0078d4 — colorBrandBackground + colorBrandForeground1 (the Dynamics blue)\n 90: '#2886de',\n 100: '#479ef5',\n 110: '#62abf5',\n 120: '#77b7f7',\n 130: '#96c6fa',\n 140: '#b4d6fa',\n 150: '#cfe4fa',\n 160: '#ebf3fc',\n} as const;\n","// The Dynamics CE Fluent v9 theme builders — the v9 counterpart of surface-kit's v8\n// `createDynamicsTheme()`. Both feed the SAME brand triad (brand / brandHover / brandDark)\n// into their respective theme factories, so a Dynamics-blue button is #0078d4 whichever\n// skin renders it.\nimport {\n createLightTheme,\n createDarkTheme,\n webLightTheme,\n type BrandVariants,\n type Theme,\n} from '@fluentui/react-components';\nimport { dynamicsBrandRamp } from './brand';\n\n// ★ The assignability check that makes ./brand's inferred type safe. If someone re-annotates\n// the ramp as `Record<number, string>` (an index signature, which does not satisfy\n// BrandVariants' sixteen required literal keys) this line fails to compile — at the\n// declaration, not at some downstream consumer's call site.\nconst defaultBrand: BrandVariants = dynamicsBrandRamp;\n\n/**\n * Build a Fluent v9 `Theme` for the Dynamics surfaces. Defaults to the Dynamics-blue brand\n * ramp; pass a custom `BrandVariants` (e.g. from your org's brand) to override.\n * Wrap the app or subtree in `<FluentProvider theme={createDynamicsV9Theme()}>`.\n */\nexport function createDynamicsV9Theme(brand: BrandVariants = defaultBrand): Theme {\n return createLightTheme(brand);\n}\n\n/** Dark-mode variant of the Dynamics v9 theme (same brand ramp). */\nexport function createDynamicsV9DarkTheme(brand: BrandVariants = defaultBrand): Theme {\n return createDarkTheme(brand);\n}\n\n/** The default light Dynamics v9 theme (memoized module singleton). */\nexport const dynamicsV9Theme: Theme = createDynamicsV9Theme();\n\n/** The default dark Dynamics v9 theme (memoized module singleton). */\nexport const dynamicsV9DarkTheme: Theme = createDynamicsV9DarkTheme();\n\n/**\n * The Dynamics 365 CE model-driven \"new look\" theme: Fluent 2 web light, whose colours, shadows\n * and radii the new look uses unmodified.\n *\n * Measured on a live org (dynamics-ui-kit `apps/ce-parity/reference/`), every colour, shadow and\n * radius the new-look form renders is an unmodified `webLightTheme` token, and so is its brand.\n * Typography is NOT fully stock (tabs are 16px on a 28px line); that lives in the\n * `@dataverse-kit/design-tokens` `ceForm` metrics, which components apply on top of this theme. The tab\n * underline is `#0f6cbd` and links are `#115ea3`. That is Fluent's default web brand ramp, NOT\n * the classic Dynamics `#0078d4` that {@link createDynamicsV9Theme} pins. Use this theme when\n * the goal is to look identical to a current Dynamics form, and `createDynamicsV9Theme` when a\n * surface must match the classic blue.\n *\n * Returns a fresh copy so callers can override tokens without mutating Fluent's singleton.\n */\nexport function createDynamicsCeTheme(): Theme {\n return { ...webLightTheme };\n}\n\n/** The default CE new-look theme (module singleton). */\nexport const dynamicsCeTheme: Theme = createDynamicsCeTheme();\n"],"mappings":";AAgBA,SAAS,cAAc;AAahB,IAAM,oBAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,OAAO;AAAA;AAAA,EACX,IAAI,OAAO;AAAA;AAAA,EACX,IAAI,OAAO;AAAA;AAAA,EACX,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;;;AC1CA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAOP,IAAM,eAA8B;AAO7B,SAAS,sBAAsB,QAAuB,cAAqB;AAChF,SAAO,iBAAiB,KAAK;AAC/B;AAGO,SAAS,0BAA0B,QAAuB,cAAqB;AACpF,SAAO,gBAAgB,KAAK;AAC9B;AAGO,IAAM,kBAAyB,sBAAsB;AAGrD,IAAM,sBAA6B,0BAA0B;AAiB7D,SAAS,wBAA+B;AAC7C,SAAO,EAAE,GAAG,cAAc;AAC5B;AAGO,IAAM,kBAAyB,sBAAsB;","names":[]}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@dataverse-kit/fluent-theme",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "license": "MIT",
5
- "description": "The Dynamics CE Fluent UI v9 theme, in one place: the `dynamicsBrandRamp` BrandVariants ramp (60/70/80 pinned to the canonical @dataverse-kit/design-tokens brand triad) plus the light/dark theme builders. Consumed by grid-kit/v9, surface-kit/v9 and agent-kit so a Dynamics-blue accent is #0078d4 from ONE declaration.",
5
+ "description": "The Dynamics CE Fluent UI v9 themes, in one place: the classic `dynamicsBrandRamp` (#0078d4, 60/70/80 pinned to the @dataverse-kit/design-tokens brand triad) with its light/dark builders, and `dynamicsCeTheme`, the measured model-driven 'new look' whose colours, shadows and radii are stock Fluent 2 web light (brand #0f6cbd). Consumed by grid-kit/v9, surface-kit/v9 and agent-kit.",
6
6
  "type": "module",
7
7
  "main": "./dist/index.cjs",
8
8
  "module": "./dist/index.mjs",
@@ -30,7 +30,7 @@
30
30
  "clean": "rimraf dist coverage tsconfig.tsbuildinfo"
31
31
  },
32
32
  "dependencies": {
33
- "@dataverse-kit/design-tokens": "^0.1.1"
33
+ "@dataverse-kit/design-tokens": "^0.2.0"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@fluentui/react-components": "^9.46.2"