@recursica/adapter-mui-v7 1.3.0 → 1.3.2

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/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "type": "git",
13
13
  "url": "git+https://github.com/borderux/recursica-adapter-mui-v7.git"
14
14
  },
15
- "version": "1.3.0",
15
+ "version": "1.3.2",
16
16
  "publishConfig": {
17
17
  "access": "public"
18
18
  },
@@ -122,7 +122,7 @@
122
122
  "vitest": "^3.2.4"
123
123
  },
124
124
  "dependencies": {
125
- "@recursica/adapter-common": "^1.1.1",
125
+ "@recursica/adapter-common": "^1.2.0",
126
126
  "@recursica/official-release": "^2.8.0",
127
127
  "dayjs": "^1.11.21"
128
128
  },
@@ -3,6 +3,7 @@ import { Card } from "./Card";
3
3
  import { Layer } from "@recursica/adapter-common";
4
4
  import { Button } from "../Button/Button";
5
5
  import { Group } from "../Group/Group";
6
+ import { Heading } from "../Heading/Heading";
6
7
  import { Text } from "../Text/Text";
7
8
 
8
9
  const meta: Meta<typeof Card> = {
@@ -78,7 +79,7 @@ export const HeaderlessAndFooterless: Story = {
78
79
  <Layer layer={0}>
79
80
  <Card {...args}>
80
81
  <Card.Content>
81
- <Text variant="subtitle">Notice</Text>
82
+ <Heading order={6}>Notice</Heading>
82
83
  <Text>
83
84
  This is a completely generic card payload dropping the Header
84
85
  and Footer specific elements, simply acting as a padded
@@ -74,6 +74,8 @@
74
74
 
75
75
  .sliderRoot {
76
76
  width: 100%;
77
+ /* MUI defaults the root to 4px, so the thumb overflows and the block collapses; match the thumb height. */
78
+ height: var(--recursica_ui-kit_components_slider_properties_thumb-size);
77
79
  box-sizing: border-box;
78
80
  color: inherit;
79
81
  font-family: inherit;
@@ -84,6 +86,7 @@
84
86
 
85
87
  .sliderTrack {
86
88
  height: var(--recursica_ui-kit_components_slider_properties_track-height);
89
+ opacity: 1; /* MUI fades the rail to 0.38 by default, which washes out the token color */
87
90
  border-radius: var(
88
91
  --recursica_ui-kit_components_slider_properties_track-border-radius
89
92
  );
@@ -249,6 +252,14 @@
249
252
  display: flex !important;
250
253
  align-items: center !important;
251
254
  justify-content: center !important;
255
+
256
+ /* The transform override above defeats MUI's scale(0) hiding, so hide until MUI marks it open. */
257
+ opacity: 0;
258
+ pointer-events: none;
259
+ }
260
+
261
+ .sliderTooltip:global(.MuiSlider-valueLabelOpen) {
262
+ opacity: 1;
252
263
  }
253
264
 
254
265
  .sliderTooltip * {
@@ -8,3 +8,13 @@ visibly more vertical space between each item in mui's render. Not a component b
8
8
  itself has no opinion on inter-item spacing; the gap is entirely owned by each story's own
9
9
  `<div style={{ display: "flex", flexDirection: "column", gap }}>` wrapper. Fixed by changing the
10
10
  story's `gap` to `"16px"` to match mantine's.
11
+
12
+ ## Removed `body-small`, `subtitle`, `subtitle-small` variants; dev-only missing-style check
13
+
14
+ Forge only exports `h1`-`h6`, `body`, `caption` and `overline`; the three removed variants produced
15
+ a class matching no CSS rule. Any style under `brand.typography` still works by name (`TextVariant`
16
+ accepts any string since `@recursica/adapter-common` 1.2.0). In development, `Text` checks
17
+ `document.styleSheets` (`src/utils/typographyClass.ts`) for `.recursica_brand_typography_<variant>`;
18
+ if absent it logs one `console.error` per name and sets `data-typography-missing`, which
19
+ `Typography.module.css` hides with `visibility: hidden`. The attribute is never set when
20
+ `NODE_ENV === "production"`.
@@ -1,5 +1,15 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { Text } from "./Text";
3
+ import brand from "../../../recursica_brand.json";
4
+
5
+ const BUILT_IN_VARIANTS = ["body", "caption", "overline"];
6
+
7
+ // Custom styles defined under `brand.typography` (beyond h1-h6 and the built-ins above); each has
8
+ // an exported `recursica_brand_typography_<name>` class, so `Text` renders it by name.
9
+ // Sorted so the render order is stable across exports (the visual diff depends on it).
10
+ const customVariants = Object.keys(brand.brand.typography)
11
+ .filter((name) => !/^h[1-6]$/.test(name) && !BUILT_IN_VARIANTS.includes(name))
12
+ .sort();
3
13
 
4
14
  const meta: Meta<typeof Text> = {
5
15
  title: "UI-Kit/Text",
@@ -16,14 +26,7 @@ const meta: Meta<typeof Text> = {
16
26
  argTypes: {
17
27
  variant: {
18
28
  control: "select",
19
- options: [
20
- "body",
21
- "body-small",
22
- "caption",
23
- "overline",
24
- "subtitle",
25
- "subtitle-small",
26
- ],
29
+ options: [...BUILT_IN_VARIANTS, ...customVariants],
27
30
  description:
28
31
  "Controls the standard logical boundary definitions natively extracted from Figma.",
29
32
  },
@@ -62,21 +65,17 @@ export const StaticVariations: Story = {
62
65
  <Text variant="body">
63
66
  Body (Base paragraph and generic information flow)
64
67
  </Text>
65
- <Text variant="body-small">
66
- Body Small (Compacted list items and helper blocks)
67
- </Text>
68
68
  <Text variant="caption">
69
69
  Caption (Data table descriptions or micro-labels)
70
70
  </Text>
71
71
  <Text variant="overline">
72
72
  Overline (Card contextual pre-headers and categorical tags)
73
73
  </Text>
74
- <Text variant="subtitle">
75
- Subtitle (Minor sub-headers avoiding heavy display weights)
76
- </Text>
77
- <Text variant="subtitle-small">
78
- Subtitle Small (Section anchors deep in hierarchy)
79
- </Text>
74
+ {customVariants.map((name) => (
75
+ <Text key={name} variant={name}>
76
+ {name} (Custom style from brand.typography)
77
+ </Text>
78
+ ))}
80
79
  </div>
81
80
  ),
82
81
  };
@@ -3,6 +3,7 @@ import { type TypographyProps as MuiTypographyProps } from "@mui/material";
3
3
  import { Typography } from "../Typography/Typography";
4
4
  import { type RecursicaOverStyled } from "../../utils/filterStylingProps";
5
5
  import { type RecursicaTextProps } from "@recursica/adapter-common";
6
+ import { isTypographyStyleDefined } from "../../utils/typographyClass";
6
7
 
7
8
  export type TextProps = RecursicaOverStyled<
8
9
  Omit<MuiTypographyProps, "variant" | "classes" | "color"> &
@@ -14,6 +15,13 @@ export const Text = forwardRef<HTMLElement, TextProps>(function Text(
14
15
  { variant = "body", emphasis = "high", color = "default", ...rest },
15
16
  ref,
16
17
  ) {
18
+ // Dev only: an unknown variant hides the text (and logs) instead of silently rendering with the
19
+ // UI kit's default styling.
20
+ const typographyMissing =
21
+ process.env.NODE_ENV !== "production" &&
22
+ typeof document !== "undefined" &&
23
+ !isTypographyStyleDefined(variant);
24
+
17
25
  const typographyClass = `recursica_brand_typography_${variant}`;
18
26
  return (
19
27
  <Typography
@@ -21,6 +29,7 @@ export const Text = forwardRef<HTMLElement, TextProps>(function Text(
21
29
  typographyClass={typographyClass}
22
30
  data-color={color}
23
31
  data-emphasis={emphasis}
32
+ data-typography-missing={typographyMissing || undefined}
24
33
  {...rest}
25
34
  />
26
35
  );
@@ -2,6 +2,8 @@
2
2
  * HARDCODED VALUES
3
3
  * - `.root` `text-wrap: balance` — not a design token; a layout algorithm choice requested by
4
4
  * UX (Matt Massey, 2026-08-28) to even out wrapped line lengths. See TEXT_IMPLEMENTATION_NOTES.md.
5
+ * - `.root[data-typography-missing]` `visibility: hidden` — dev-only (the attribute is never set in
6
+ * production); hides text whose typography variant has no exported style. Not a design token.
5
7
  *
6
8
  * Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
7
9
  * Semantic text color and emphasis are layer/theme-level concerns with no per-component UI-kit
@@ -50,3 +52,9 @@
50
52
  .root[data-emphasis="low"] {
51
53
  opacity: var(--recursica_brand_text-emphasis_low);
52
54
  }
55
+
56
+ /* Dev only (the attribute is never set in production): hides text whose typography variant has no
57
+ exported style, so a typo is obvious instead of rendering with the UI kit's defaults. */
58
+ .root[data-typography-missing] {
59
+ visibility: hidden;
60
+ }
@@ -0,0 +1,38 @@
1
+ const found = new Set<string>();
2
+ const reported = new Set<string>();
3
+
4
+ function ruleListDefines(rules: CSSRuleList, selector: string): boolean {
5
+ return Array.from(rules).some((rule) => {
6
+ if (rule instanceof CSSStyleRule) {
7
+ return rule.selectorText.split(",").some((s) => s.trim() === selector);
8
+ }
9
+ const nested = (rule as CSSGroupingRule).cssRules;
10
+ return nested ? ruleListDefines(nested, selector) : false;
11
+ });
12
+ }
13
+
14
+ /**
15
+ * Dev-only: whether a `.recursica_brand_typography_<name>` rule exists in any readable stylesheet.
16
+ * Logs a console error once per missing name. Cross-origin stylesheets can't be read and are
17
+ * skipped, so they never count as defining the class.
18
+ */
19
+ export function isTypographyStyleDefined(name: string): boolean {
20
+ const selector = `.recursica_brand_typography_${name}`;
21
+ if (found.has(selector)) return true;
22
+ const defined = Array.from(document.styleSheets).some((sheet) => {
23
+ try {
24
+ return ruleListDefines(sheet.cssRules, selector);
25
+ } catch {
26
+ return false;
27
+ }
28
+ });
29
+ if (defined) {
30
+ found.add(selector);
31
+ } else if (!reported.has(selector)) {
32
+ reported.add(selector);
33
+ console.error(
34
+ `Text: no "${selector}" rule found. "${name}" is not defined under brand.typography in the exported Recursica CSS, so the text is hidden.`,
35
+ );
36
+ }
37
+ return defined;
38
+ }