@flipdish/ui-library 0.28.0 → 0.29.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.
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var cx = require('@flipdish/ui-library/utilities/cx');
5
+ var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
6
+
7
+ /**
8
+ * Layout-only template for an app shell: navigation beside a content column that stacks the
9
+ * header above the page, with an optional side panel that pushes the page instead of covering it.
10
+ * The shell is exactly the height of the window and the document never scrolls: the page content
11
+ * scrolls in its own area under the header, so the header, navigation and side panel stay in place
12
+ * with no sticky positioning. It holds no state and renders whatever is passed to its slots, so the
13
+ * app keeps ownership of navigation, search and panel state.
14
+ *
15
+ * @summary window-height layout template placing navigation, header, a scrolling page area and a side panel
16
+ */
17
+ const AppShell = ({ sidebar, header, panel, children, scrollAreaProps, className, 'data-testid': dataTestId }) => {
18
+ const appShellTestId = testIdUtils.useResolvedTestId({ testId: dataTestId, segment: 'app-shell', rootName: 'app-shell' });
19
+ return (
20
+ // A column below `lg`, so a navigation that renders its own mobile top bar stacks above the content.
21
+ jsxRuntime.jsxs("div", { "data-testid": appShellTestId, className: cx.cx('flex h-dvh w-full flex-col overflow-hidden bg-primary lg:flex-row', className), children: [sidebar, jsxRuntime.jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [header, jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1", children: [jsxRuntime.jsx("div", { id: scrollAreaProps?.id, ref: scrollAreaProps?.ref, "data-testid": scrollAreaProps?.['data-testid'] ?? testIdUtils.joinTestId(appShellTestId, 'scroll-area'),
22
+ // Focusable so keyboard users can scroll a page that has no focusable content of its own (axe: scrollable-region-focusable).
23
+ // biome-ignore lint/a11y/noNoninteractiveTabindex: a scrollable region must be reachable by keyboard
24
+ tabIndex: 0, className: "flex min-w-0 flex-1 flex-col overflow-y-auto outline-focus-ring focus-visible:outline-2 focus-visible:-outline-offset-2", children: children }), panel] })] })] }));
25
+ };
26
+
27
+ exports.AppShell = AppShell;
28
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../../../../src/components/templates/AppShell/index.tsx"],"sourcesContent":[null],"names":["useResolvedTestId","_jsxs","cx","_jsx","joinTestId"],"mappings":";;;;;;AAmCA;;;;;;;;;AASG;MACU,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAiB,KAAe;AAChJ,IAAA,MAAM,cAAc,GAAGA,6BAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IAE7G;;IAEEC,eAAA,CAAA,KAAA,EAAA,EAAA,aAAA,EAAkB,cAAc,EAAE,SAAS,EAAEC,KAAE,CAAC,mEAAmE,EAAE,SAAS,CAAC,EAAA,QAAA,EAAA,CAC5H,OAAO,EAGRD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,sCAAsC,aAClD,MAAM,EAEPA,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,qBAAqB,aAClCE,cAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,eAAe,EAAE,EAAE,EACvB,GAAG,EAAE,eAAe,EAAE,GAAG,iBACZ,eAAe,GAAG,aAAa,CAAC,IAAIC,sBAAU,CAAC,cAAc,EAAE,aAAa,CAAC;;;AAG1F,gCAAA,QAAQ,EAAE,CAAC,EACX,SAAS,EAAC,yHAAyH,EAAA,QAAA,EAElI,QAAQ,EAAA,CACL,EAEL,KAAK,CAAA,EAAA,CACF,CAAA,EAAA,CACF,CAAA,EAAA,CACF;AAEV;;;;"}
@@ -0,0 +1,40 @@
1
+ import type { ReactNode, Ref } from 'react';
2
+ export interface AppShellScrollAreaProps {
3
+ /** `id` for the scrolling element, e.g. for a scroll-to-top helper that looks it up. */
4
+ id?: string;
5
+ /** Ref to the scrolling element, e.g. to reset `scrollTop` on navigation or attach a scroll listener. */
6
+ ref?: Ref<HTMLDivElement>;
7
+ /** Overrides the scrolling element's `data-testid` (defaults to `<root>--scroll-area`). */
8
+ 'data-testid'?: string;
9
+ }
10
+ export interface AppShellProps {
11
+ /** Primary navigation, rendered first beside the content column. Compose `<SidebarNavigation>` here. */
12
+ sidebar?: ReactNode;
13
+ /** Top bar, rendered at the top of the content column. It stays in place while the page area scrolls. Compose `<ApplicationHeader>` here. */
14
+ header?: ReactNode;
15
+ /**
16
+ * Side panel rendered under the header, beside the page area, which narrows to make room. It fills
17
+ * the height under the header and stays in view while the page area scrolls.
18
+ */
19
+ panel?: ReactNode;
20
+ /** Page content, normally a `<PageLayout>`. Rendered inside the shell's scroll area. */
21
+ children: ReactNode;
22
+ /** Hooks for the element that scrolls the page content, since the document itself does not scroll. */
23
+ scrollAreaProps?: AppShellScrollAreaProps;
24
+ /** Extra classes merged onto the root element. */
25
+ className?: string;
26
+ /** Overrides the `data-testid` (defaults to `fd-app-shell`). */
27
+ 'data-testid'?: string;
28
+ }
29
+ /**
30
+ * Layout-only template for an app shell: navigation beside a content column that stacks the
31
+ * header above the page, with an optional side panel that pushes the page instead of covering it.
32
+ * The shell is exactly the height of the window and the document never scrolls: the page content
33
+ * scrolls in its own area under the header, so the header, navigation and side panel stay in place
34
+ * with no sticky positioning. It holds no state and renders whatever is passed to its slots, so the
35
+ * app keeps ownership of navigation, search and panel state.
36
+ *
37
+ * @summary window-height layout template placing navigation, header, a scrolling page area and a side panel
38
+ */
39
+ export declare const AppShell: ({ sidebar, header, panel, children, scrollAreaProps, className, "data-testid": dataTestId }: AppShellProps) => ReactNode;
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/templates/AppShell/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAE5C,MAAM,WAAW,uBAAuB;IACtC,wFAAwF;IACxF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yGAAyG;IACzG,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1B,2FAA2F;IAC3F,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,wGAAwG;IACxG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,6IAA6I;IAC7I,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,wFAAwF;IACxF,QAAQ,EAAE,SAAS,CAAC;IACpB,sGAAsG;IACtG,eAAe,CAAC,EAAE,uBAAuB,CAAC;IAC1C,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,GAAI,6FAA6F,aAAa,KAAG,SA8BrI,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { cx } from '@flipdish/ui-library/utilities/cx';
3
+ import { useResolvedTestId, joinTestId } from '@flipdish/ui-library/utilities/testIdUtils';
4
+
5
+ /**
6
+ * Layout-only template for an app shell: navigation beside a content column that stacks the
7
+ * header above the page, with an optional side panel that pushes the page instead of covering it.
8
+ * The shell is exactly the height of the window and the document never scrolls: the page content
9
+ * scrolls in its own area under the header, so the header, navigation and side panel stay in place
10
+ * with no sticky positioning. It holds no state and renders whatever is passed to its slots, so the
11
+ * app keeps ownership of navigation, search and panel state.
12
+ *
13
+ * @summary window-height layout template placing navigation, header, a scrolling page area and a side panel
14
+ */
15
+ const AppShell = ({ sidebar, header, panel, children, scrollAreaProps, className, 'data-testid': dataTestId }) => {
16
+ const appShellTestId = useResolvedTestId({ testId: dataTestId, segment: 'app-shell', rootName: 'app-shell' });
17
+ return (
18
+ // A column below `lg`, so a navigation that renders its own mobile top bar stacks above the content.
19
+ jsxs("div", { "data-testid": appShellTestId, className: cx('flex h-dvh w-full flex-col overflow-hidden bg-primary lg:flex-row', className), children: [sidebar, jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [header, jsxs("div", { className: "flex min-h-0 flex-1", children: [jsx("div", { id: scrollAreaProps?.id, ref: scrollAreaProps?.ref, "data-testid": scrollAreaProps?.['data-testid'] ?? joinTestId(appShellTestId, 'scroll-area'),
20
+ // Focusable so keyboard users can scroll a page that has no focusable content of its own (axe: scrollable-region-focusable).
21
+ // biome-ignore lint/a11y/noNoninteractiveTabindex: a scrollable region must be reachable by keyboard
22
+ tabIndex: 0, className: "flex min-w-0 flex-1 flex-col overflow-y-auto outline-focus-ring focus-visible:outline-2 focus-visible:-outline-offset-2", children: children }), panel] })] })] }));
23
+ };
24
+
25
+ export { AppShell };
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/templates/AppShell/index.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx"],"mappings":";;;;AAmCA;;;;;;;;;AASG;MACU,QAAQ,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAiB,KAAe;AAChJ,IAAA,MAAM,cAAc,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IAE7G;;IAEEA,IAAA,CAAA,KAAA,EAAA,EAAA,aAAA,EAAkB,cAAc,EAAE,SAAS,EAAE,EAAE,CAAC,mEAAmE,EAAE,SAAS,CAAC,EAAA,QAAA,EAAA,CAC5H,OAAO,EAGRA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,sCAAsC,aAClD,MAAM,EAEPA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,qBAAqB,aAClCC,GAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,eAAe,EAAE,EAAE,EACvB,GAAG,EAAE,eAAe,EAAE,GAAG,iBACZ,eAAe,GAAG,aAAa,CAAC,IAAI,UAAU,CAAC,cAAc,EAAE,aAAa,CAAC;;;AAG1F,gCAAA,QAAQ,EAAE,CAAC,EACX,SAAS,EAAC,yHAAyH,EAAA,QAAA,EAElI,QAAQ,EAAA,CACL,EAEL,KAAK,CAAA,EAAA,CACF,CAAA,EAAA,CACF,CAAA,EAAA,CACF;AAEV;;;;"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `AppShell` has no React Native implementation.
3
+ *
4
+ * This is a generated types-only stub (scripts/emit-native-stubs.mjs). It exists so
5
+ * that importing `@flipdish/ui-library/components/templates/AppShell` from React Native fails at
6
+ * compile time rather than resolving to the web build's types. There is no
7
+ * matching `index.js`, so Metro cannot bundle this module either.
8
+ *
9
+ * To make `AppShell` available on React Native, add an `index.native.tsx` beside
10
+ * its `index.tsx` — the build picks it up automatically and this stub disappears.
11
+ */
12
+ export declare const __NO_REACT_NATIVE_IMPLEMENTATION__: never;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flipdish/ui-library",
3
- "version": "0.28.0",
3
+ "version": "0.29.0",
4
4
  "description": "Flipdish Design System — atomic-design component library (Tailwind v4 + UntitledUI + React Aria).",
5
5
  "type": "module",
6
6
  "imports": {