@recursica/mantine-adapter 0.14.0 → 0.15.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.
@@ -1,9 +1,17 @@
1
1
  import { Drawer as MantineDrawer, DrawerProps as MantineDrawerProps } from '@mantine/core';
2
2
  import { RecursicaOverStyled } from '../../utils/filterStylingProps';
3
+ export interface RecursicaPanelProps extends MantineDrawerProps {
4
+ /**
5
+ * If true, forces the header text to a single line and truncates with an ellipsis.
6
+ * Note: While the prop is named `wrapHeaderText` for backward compatibility,
7
+ * setting it to `true` actually PREVENTS wrapping (it forces truncation).
8
+ */
9
+ wrapHeaderText?: boolean;
10
+ }
3
11
  /**
4
12
  * Recursica Panel root props. Extends Mantine Drawer.
5
13
  */
6
- export type PanelProps = RecursicaOverStyled<MantineDrawerProps>;
14
+ export type PanelProps = RecursicaOverStyled<RecursicaPanelProps>;
7
15
  /**
8
16
  * Recursica Panel component wrapping Mantine's Drawer.
9
17
  *
@@ -31,7 +39,7 @@ export type PanelProps = RecursicaOverStyled<MantineDrawerProps>;
31
39
  * - `Panel.Stack` — Stacked drawer context
32
40
  */
33
41
  declare const PanelBase: {
34
- ({ overStyled, position, keepMounted, ...rest }: PanelProps): import("react/jsx-runtime").JSX.Element;
42
+ ({ overStyled, position, keepMounted, wrapHeaderText, ...rest }: PanelProps): import("react/jsx-runtime").JSX.Element;
35
43
  displayName: string;
36
44
  };
37
45
  export type PanelFooterProps = RecursicaOverStyled<React.HTMLAttributes<HTMLDivElement>>;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "type": "git",
12
12
  "url": "git+https://github.com/borderux/recursica.git"
13
13
  },
14
- "version": "0.14.0",
14
+ "version": "0.15.0",
15
15
  "type": "module",
16
16
  "main": "./dist/mantine-adapter.cjs",
17
17
  "module": "./dist/mantine-adapter.js",
@@ -33,6 +33,7 @@
33
33
  border-bottom: var(--recursica_ui-kit_components_card_properties_divider-size)
34
34
  solid
35
35
  var(--recursica_ui-kit_components_card_properties_colors_divider-color);
36
+ composes: recursica_brand_typography_h3 from global;
36
37
  }
37
38
 
38
39
  .footer {
@@ -2,6 +2,8 @@ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { Card } from "./Card";
3
3
  import { Layer } from "@recursica/adapter-common";
4
4
  import { Button } from "../Button/Button";
5
+ import { Group } from "../Group/Group";
6
+ import { Text } from "../Text/Text";
5
7
 
6
8
  const meta: Meta<typeof Card> = {
7
9
  title: "UI-Kit/Card",
@@ -32,46 +34,33 @@ export const Default: Story = {
32
34
  args: {},
33
35
  render: ({ ...args }) => {
34
36
  return (
35
- <Layer
36
- layer={0}
37
+ <div
37
38
  style={{
38
39
  padding: "48px",
39
40
  backgroundColor: "var(--recursica_brand_palettes_neutral_050)",
40
41
  }}
41
42
  >
42
- <Card {...args}>
43
- <Card.Header>
44
- <span style={{ fontWeight: 500, fontSize: "1.125rem" }}>
45
- Customer Activity Report
46
- </span>
47
- </Card.Header>
48
- <Card.Content>
49
- <p>
50
- Card inner section content body. Notice how this acts as padded
51
- content natively based on the overarching properties. Recursica's
52
- vertical gutter governs vertical spacing between siblings in the
53
- flex container.
54
- </p>
55
- <p>Another section showing the vertical gutter spacing.</p>
56
- </Card.Content>
57
- <Card.Footer>
58
- <div
59
- style={{
60
- display: "flex",
61
- justifyContent: "space-between",
62
- alignItems: "center",
63
- marginTop: "16px",
64
- marginBottom: "8px",
65
- }}
66
- >
67
- <span style={{ color: "#868e96", fontSize: "0.75rem" }}>
68
- Generated today
69
- </span>
70
- <Button variant="solid">View Details</Button>
71
- </div>
72
- </Card.Footer>
73
- </Card>
74
- </Layer>
43
+ <Layer layer={0}>
44
+ <Card {...args}>
45
+ <Card.Header>Customer Activity Report</Card.Header>
46
+ <Card.Content>
47
+ <Text>
48
+ Card inner section content body. Notice how this acts as padded
49
+ content natively based on the overarching properties.
50
+ Recursica's vertical gutter governs vertical spacing between
51
+ siblings in the flex container.
52
+ </Text>
53
+ <Text>Another section showing the vertical gutter spacing.</Text>
54
+ </Card.Content>
55
+ <Card.Footer>
56
+ <Group justify="space-between" align="center">
57
+ <Text variant="caption">Generated today</Text>
58
+ <Button variant="solid">View Details</Button>
59
+ </Group>
60
+ </Card.Footer>
61
+ </Card>
62
+ </Layer>
63
+ </div>
75
64
  );
76
65
  },
77
66
  };
@@ -80,29 +69,26 @@ export const HeaderlessAndFooterless: Story = {
80
69
  args: {},
81
70
  render: ({ ...args }) => {
82
71
  return (
83
- <Layer
84
- layer={0}
72
+ <div
85
73
  style={{
86
74
  padding: "48px",
87
75
  backgroundColor: "var(--recursica_brand_palettes_neutral_050)",
88
76
  }}
89
77
  >
90
- <Card {...args}>
91
- <Card.Content>
92
- <span style={{ fontWeight: 500, fontSize: "1.125rem" }}>
93
- Notice
94
- </span>
95
- <p>
96
- This is a completely generic card payload dropping the Header and
97
- Footer specific elements, simply acting as a padded elevation
98
- boundary box directly mirroring native composability!
99
- </p>
100
- <Button variant="solid" mt="rec-md">
101
- Acknowledge
102
- </Button>
103
- </Card.Content>
104
- </Card>
105
- </Layer>
78
+ <Layer layer={0}>
79
+ <Card {...args}>
80
+ <Card.Content>
81
+ <Text variant="subtitle">Notice</Text>
82
+ <Text>
83
+ This is a completely generic card payload dropping the Header
84
+ and Footer specific elements, simply acting as a padded
85
+ elevation boundary box directly mirroring native composability!
86
+ </Text>
87
+ <Button variant="solid">Acknowledge</Button>
88
+ </Card.Content>
89
+ </Card>
90
+ </Layer>
91
+ </div>
106
92
  );
107
93
  },
108
94
  };
@@ -122,17 +108,21 @@ export const LayerDemonstration: Story = {
122
108
  <Layer layer={1}>
123
109
  <Card {...args}>
124
110
  <Card.Header>Layer 1 Wrapper</Card.Header>
125
- <p>Content inside layer 1 card.</p>
111
+ <Card.Content>
112
+ <Text>Content inside layer 1 card.</Text>
113
+ </Card.Content>
126
114
  </Card>
127
115
  </Layer>
128
116
 
129
117
  <Layer layer={2}>
130
118
  <Card {...args}>
131
119
  <Card.Header>Layer 2 Wrapper</Card.Header>
132
- <p>
133
- Content inside layer 2 card exposing a higher elevation drop
134
- shadow inherently cascaded.
135
- </p>
120
+ <Card.Content>
121
+ <Text>
122
+ Content inside layer 2 card exposing a higher elevation drop
123
+ shadow inherently cascaded.
124
+ </Text>
125
+ </Card.Content>
136
126
  </Card>
137
127
  </Layer>
138
128
  </div>
@@ -86,11 +86,11 @@ Mantine's Drawer content does not set `border-style` natively. Without this, the
86
86
 
87
87
  ---
88
88
 
89
- ## 7. header-style Token Reference Bug
89
+ ## 7. `header-style` Typography Utility Class
90
90
 
91
- **Decision:** The `header-style: "h3"` token currently outputs as a raw string in the UI kit JSON, breaking our PostCSS compiler when mapped as CSS variable fallbacks. We have explicitly removed these fallbacks.
91
+ **Decision:** The `header-style` token exports as the string `"h3"`, so we use the generated global utility class `.recursica_brand_typography_h3`.
92
92
 
93
- **Implementation:** The design system intended for the `header-style` token to act as a proper typography reference, which would compile into fully expanded properties like `--recursica_ui-kit_components_panel_properties_header-style_fontFamily`. Because the JSON export currently passes it as the raw string `"h3"`, attempting to bind to the non-existent variables breaks the build plugin. Until the JSON export is fixed to compile proper reference nodes, we are stripping typography bindings from the `.title` class and relying purely on `color` and Mantine's defaults.
93
+ **Implementation:** The PostCSS compiler generates `.recursica_brand_typography_<typeName>` classes at the bottom of the scoped variables file to apply full typography definitions without assigning variables inline. We apply this to the `.title` class via `composes: recursica_brand_typography_h3 from global;`.
94
94
 
95
95
  ---
96
96
 
@@ -64,6 +64,17 @@
64
64
 
65
65
  .title {
66
66
  color: var(--recursica_ui-kit_components_panel_properties_colors_title);
67
+ composes: recursica_brand_typography_h3 from global;
68
+ }
69
+
70
+ .titleTruncate {
71
+ composes: title;
72
+ white-space: nowrap;
73
+ overflow: hidden;
74
+ text-overflow: ellipsis;
75
+ display: block;
76
+ flex: 1;
77
+ min-width: 0;
67
78
  }
68
79
 
69
80
  /* ======================================
@@ -29,6 +29,11 @@ const meta: Meta = {
29
29
  control: "boolean",
30
30
  description: "Whether to display the close button in the header.",
31
31
  },
32
+ wrapHeaderText: {
33
+ control: "boolean",
34
+ description:
35
+ "If true, forces the header text to a single line and truncates with an ellipsis.",
36
+ },
32
37
  // Hide auto-detected HTML attributes
33
38
  defaultChecked: { table: { disable: true } },
34
39
  defaultValue: { table: { disable: true } },
@@ -77,8 +82,9 @@ export const Default: Story = {
77
82
  title: "Panel Title",
78
83
  withOverlay: true,
79
84
  withCloseButton: true,
85
+ wrapHeaderText: false,
80
86
  },
81
- render: () => {
87
+ render: ({ wrapHeaderText, ...args }: PanelStoryArgs) => {
82
88
  // eslint-disable-next-line react-hooks/rules-of-hooks
83
89
  const [opened, setOpened] = useState(false);
84
90
 
@@ -92,6 +98,8 @@ export const Default: Story = {
92
98
  onClose={() => setOpened(false)}
93
99
  title="Panel Title"
94
100
  position="right"
101
+ wrapHeaderText={wrapHeaderText}
102
+ {...(args as PanelProps)}
95
103
  >
96
104
  <Text>
97
105
  This is the panel body content area. Panels slide in from the edge
@@ -116,6 +124,7 @@ export const LeftPosition: Story = {
116
124
  title: "Navigation",
117
125
  withOverlay: true,
118
126
  withCloseButton: true,
127
+ wrapHeaderText: false,
119
128
  },
120
129
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
121
130
  render: ({ withLayer, layer, ...args }: PanelStoryArgs) => {
@@ -148,6 +157,7 @@ export const ScrollableContent: Story = {
148
157
  title: "Scrollable Panel",
149
158
  withOverlay: true,
150
159
  withCloseButton: true,
160
+ wrapHeaderText: false,
151
161
  },
152
162
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
153
163
  render: ({ withLayer, layer, ...args }: PanelStoryArgs) => {
@@ -190,6 +200,7 @@ export const LongTitle: Story = {
190
200
  "This is a ridiculously long panel title designed to test how the header CSS handles text overflow and whether it truncates correctly or breaks the layout",
191
201
  withOverlay: true,
192
202
  withCloseButton: true,
203
+ wrapHeaderText: true,
193
204
  },
194
205
  render: ({ ...args }: PanelStoryArgs) => {
195
206
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -13,10 +13,19 @@ import styles from "./Panel.module.css";
13
13
  // PANEL (Drawer)
14
14
  // ============================================================
15
15
 
16
+ export interface RecursicaPanelProps extends MantineDrawerProps {
17
+ /**
18
+ * If true, forces the header text to a single line and truncates with an ellipsis.
19
+ * Note: While the prop is named `wrapHeaderText` for backward compatibility,
20
+ * setting it to `true` actually PREVENTS wrapping (it forces truncation).
21
+ */
22
+ wrapHeaderText?: boolean;
23
+ }
24
+
16
25
  /**
17
26
  * Recursica Panel root props. Extends Mantine Drawer.
18
27
  */
19
- export type PanelProps = RecursicaOverStyled<MantineDrawerProps>;
28
+ export type PanelProps = RecursicaOverStyled<RecursicaPanelProps>;
20
29
 
21
30
  /**
22
31
  * Recursica Panel component wrapping Mantine's Drawer.
@@ -48,6 +57,7 @@ const PanelBase = function Panel({
48
57
  overStyled = false,
49
58
  position = "right",
50
59
  keepMounted = true,
60
+ wrapHeaderText = false,
51
61
  ...rest
52
62
  }: PanelProps) {
53
63
  const sanitizedProps = filterStylingProps(rest, overStyled);
@@ -56,7 +66,7 @@ const PanelBase = function Panel({
56
66
  const mergedClassNames: Partial<Record<string, string>> = {
57
67
  content: styles.content,
58
68
  header: styles.header,
59
- title: styles.title,
69
+ title: wrapHeaderText ? styles.titleTruncate : styles.title,
60
70
  body: styles.body,
61
71
  inner: styles.inner,
62
72
  };