@cratis/scene.blueprint.default 1.1.0 → 3.0.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/.storybook/preview.tsx +44 -0
- package/README.md +25 -12
- package/dist/cjs/shell/Breadcrumb.js +47 -10
- package/dist/cjs/shell/Breadcrumb.js.map +1 -1
- package/dist/cjs/shell/ConfigPanel.js +111 -82
- package/dist/cjs/shell/ConfigPanel.js.map +1 -1
- package/dist/cjs/shell/Sidebar.js +7 -3
- package/dist/cjs/shell/Sidebar.js.map +1 -1
- package/dist/cjs/shell/Topbar.js +7 -3
- package/dist/cjs/shell/Topbar.js.map +1 -1
- package/dist/cjs/shell/UserMenu.js +48 -21
- package/dist/cjs/shell/UserMenu.js.map +1 -1
- package/dist/esm/for_AppShell/when_rendering_a_gallery_screen.js +2 -1
- package/dist/esm/for_AppShell/when_rendering_a_gallery_screen.js.map +1 -1
- package/dist/esm/shell/Breadcrumb.d.ts.map +1 -1
- package/dist/esm/shell/Breadcrumb.js +49 -12
- package/dist/esm/shell/Breadcrumb.js.map +1 -1
- package/dist/esm/shell/ConfigPanel.d.ts.map +1 -1
- package/dist/esm/shell/ConfigPanel.js +112 -83
- package/dist/esm/shell/ConfigPanel.js.map +1 -1
- package/dist/esm/shell/MenuEntry.d.ts +6 -0
- package/dist/esm/shell/MenuEntry.d.ts.map +1 -0
- package/dist/esm/shell/MenuEntry.js +2 -0
- package/dist/esm/shell/MenuEntry.js.map +1 -0
- package/dist/esm/shell/Sidebar.d.ts.map +1 -1
- package/dist/esm/shell/Sidebar.js +7 -3
- package/dist/esm/shell/Sidebar.js.map +1 -1
- package/dist/esm/shell/Topbar.d.ts.map +1 -1
- package/dist/esm/shell/Topbar.js +7 -3
- package/dist/esm/shell/Topbar.js.map +1 -1
- package/dist/esm/shell/UserMenu.d.ts.map +1 -1
- package/dist/esm/shell/UserMenu.js +48 -21
- package/dist/esm/shell/UserMenu.js.map +1 -1
- package/dist/esm/shell/index.d.ts +1 -0
- package/dist/esm/shell/index.d.ts.map +1 -1
- package/dist/esm/shell/index.js +1 -0
- package/dist/esm/shell/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/for_AppShell/when_rendering_a_gallery_screen.tsx +10 -1
- package/package.json +28 -12
- package/shell/Breadcrumb.tsx +44 -8
- package/shell/ConfigPanel.tsx +72 -61
- package/shell/MenuEntry.ts +27 -0
- package/shell/Sidebar.tsx +5 -4
- package/shell/Topbar.tsx +5 -4
- package/shell/UserMenu.tsx +32 -17
- package/shell/index.ts +1 -0
- package/shell/layout.css +5 -5
- package/.storybook/preview.ts +0 -20
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import type { Preview } from '@storybook/react';
|
|
5
|
+
import { PrimeReactProvider } from '@primereact/core';
|
|
6
|
+
import Lara from '@primeuix/themes/lara';
|
|
7
|
+
|
|
8
|
+
// PrimeReact 11 ships zero CSS - there is no `primereact/resources` directory to import a base sheet or a
|
|
9
|
+
// theme from any more. A look is a preset: a plain JavaScript token object that `@primeuix/styled` turns
|
|
10
|
+
// into `--p-*` custom properties at runtime when the provider is handed one. Lara is the same family this
|
|
11
|
+
// preview used to load as `lara-light-indigo`, so the stories keep the look they were written against.
|
|
12
|
+
//
|
|
13
|
+
// `primeicons` is still a stylesheet, and the shell's own sheet still layers on top of both. Loading them
|
|
14
|
+
// here rather than from a story keeps every story looking the same and matches what a host does once, at
|
|
15
|
+
// its entry point.
|
|
16
|
+
import 'primeicons/primeicons.css';
|
|
17
|
+
import '../shell/layout.css';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Every story renders inside `PrimeReactProvider`, because PrimeReact 11 requires it: each component
|
|
21
|
+
* resolves its configuration, theme and z-index registry through that context and throws without one. The
|
|
22
|
+
* shell reaches for PrimeReact in five places - the topbar toggle, the sidebar pin, the user menu, the
|
|
23
|
+
* breadcrumb and the configurator's drawer - so this is not optional decoration, it is what makes the
|
|
24
|
+
* stories render at all.
|
|
25
|
+
*
|
|
26
|
+
* No `license` is supplied here: PrimeReact 11 is commercially licensed and its provider verifies a key on
|
|
27
|
+
* mount, so a preview without one logs a warning and shows PrimeTek's banner. That is the honest state of
|
|
28
|
+
* an unlicensed development preview rather than something to hide - a host supplies its own key through
|
|
29
|
+
* the same prop.
|
|
30
|
+
*/
|
|
31
|
+
const preview: Preview = {
|
|
32
|
+
decorators: [
|
|
33
|
+
Story => (
|
|
34
|
+
<PrimeReactProvider theme={{ preset: Lara }}>
|
|
35
|
+
<Story />
|
|
36
|
+
</PrimeReactProvider>
|
|
37
|
+
),
|
|
38
|
+
],
|
|
39
|
+
parameters: {
|
|
40
|
+
controls: { matchers: { color: /(background|color)$/i, date: /Date$/i } },
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default preview;
|
package/README.md
CHANGED
|
@@ -99,7 +99,7 @@ rule below references a `--scene-*` name - the same bridge pattern `@cratis/comp
|
|
|
99
99
|
|
|
100
100
|
The stylesheet is a plain `.css` file rather than an import from TypeScript, because this repo's rollup
|
|
101
101
|
config has no CSS plugin and adding one is not this package's call. A host imports
|
|
102
|
-
`@cratis/scene.blueprint.default/styles` once; Storybook does it in `.storybook/preview.
|
|
102
|
+
`@cratis/scene.blueprint.default/styles` once; Storybook does it in `.storybook/preview.tsx`.
|
|
103
103
|
|
|
104
104
|
## Theme attribution
|
|
105
105
|
|
|
@@ -149,22 +149,35 @@ papered-over one. A host with all four bundles uses `galleryProfile` and sees th
|
|
|
149
149
|
|
|
150
150
|
## PrimeReact 11
|
|
151
151
|
|
|
152
|
-
This
|
|
153
|
-
|
|
154
|
-
reveal and drawer behaviors have nowhere to come from but a stylesheet.
|
|
152
|
+
This package builds on PrimeReact 11. Two things about that upgrade are worth knowing before editing any
|
|
153
|
+
shell component.
|
|
155
154
|
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
**`Sidebar` and `Drawer` swapped meanings, and the swap is silent.** v10's `Sidebar` was an overlay
|
|
156
|
+
drawer; v11 calls that `primereact/drawer` and gives the name `primereact/sidebar` to a genuinely new
|
|
157
|
+
app-shell primitive (`SidebarLayout`, `SidebarAside`, `SidebarPanel`, `SidebarMenu`…). An import that kept
|
|
158
|
+
the v10 name still resolves, still compiles, and quietly renders an app shell where an overlay used to be.
|
|
159
|
+
`ConfigPanel` is the one place here that used it, and it is on `Drawer`. Nothing in this package imports
|
|
160
|
+
`primereact/sidebar` - `shell/Sidebar.tsx` is *this blueprint's own* component for the docked panel's
|
|
161
|
+
chrome and has nothing to do with either.
|
|
158
162
|
|
|
159
|
-
|
|
160
|
-
- the
|
|
161
|
-
|
|
162
|
-
|
|
163
|
+
**Every widget is compositional.** `model` arrays are gone, so the breadcrumb and the user menu render
|
|
164
|
+
their entries as children, and `primereact/menuitem` - the data type those arrays were made of - was
|
|
165
|
+
removed with them. This package owns the replacement shape as `shell/MenuEntry.ts`. `Button` lost `icon`,
|
|
166
|
+
`label`, `text` and `outlined`: an icon is a child, and `text`/`outlined` are values of `variant`.
|
|
167
|
+
|
|
168
|
+
The app-shell `Sidebar` primitive is a **standing opportunity, not a completed port**. Every mode here is
|
|
169
|
+
still hand-written CSS. Adopting it would collapse:
|
|
170
|
+
|
|
171
|
+
- the docked/off-canvas rules (`layout-static*`, `layout-overlay*`) into its variant and overlay props;
|
|
172
|
+
- the reveal and drawer hover machinery, and most of `isSidebarRevealed`, into its hover-open behavior;
|
|
173
|
+
- the rail widths (`slim`, `slim-plus`, `compact`) into a collapsible width token;
|
|
174
|
+
- the wrapper-class plumbing in `layoutWrapperClasses` into `SidebarLayout`.
|
|
163
175
|
|
|
164
176
|
What would **not** collapse, and would stay this package's own: the mobile forcing at 991px, the
|
|
165
177
|
persistence, the menu-theme axis, and `horizontal` (a sidebar that stops being a sidebar is not a sidebar
|
|
166
|
-
variant).
|
|
167
|
-
|
|
178
|
+
variant). That is a deliberate follow-up rather than part of the version bump - rewriting eight layout
|
|
179
|
+
modes onto a new primitive is a behavior change, and doing it inside a dependency upgrade would make both
|
|
180
|
+
impossible to review.
|
|
168
181
|
|
|
169
182
|
## Deliberately not built
|
|
170
183
|
|
|
@@ -1,30 +1,67 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var react = require('react');
|
|
4
5
|
var breadcrumb = require('primereact/breadcrumb');
|
|
5
6
|
var elementProperties = require('./elementProperties.js');
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* The trail above the content.
|
|
9
10
|
*
|
|
10
|
-
* PrimeReact's own `
|
|
11
|
+
* PrimeReact's own `Breadcrumb` does the rendering rather than hand-written markup, because a breadcrumb
|
|
11
12
|
* is an ordinary component with no layout-mode behavior at all - it looks the same in every one of the
|
|
12
|
-
* eight modes. The shell only writes CSS where PrimeReact
|
|
13
|
-
*
|
|
13
|
+
* eight modes. The shell only writes CSS where PrimeReact genuinely has no answer, and this is not one of
|
|
14
|
+
* those places: `Breadcrumb.Root` still supplies the `nav`, its `aria-label` and the list semantics, which
|
|
15
|
+
* is the part that is easy to get wrong by hand.
|
|
16
|
+
*
|
|
17
|
+
* What PrimeReact 11 no longer supplies is the `model` array - the component is composed now, and the
|
|
18
|
+
* `primereact/menuitem` type the array was made of is gone with it, which is why the trail is mapped into
|
|
19
|
+
* this package's own {@link MenuEntry}. The last entry is `Breadcrumb.Current` rather than a link: a trail
|
|
20
|
+
* whose final crumb navigates to the page already open is a link that does nothing, and it takes
|
|
21
|
+
* `aria-current='page'` away from the one element that should carry it.
|
|
14
22
|
*/ function Breadcrumb({ element }) {
|
|
15
23
|
const home = elementProperties.readOptionalString(element, 'homeTargetScreen');
|
|
16
|
-
const
|
|
24
|
+
const trail = elementProperties.readRecords(element, 'items').map((item)=>({
|
|
17
25
|
label: elementProperties.recordString(item, 'label'),
|
|
18
26
|
url: elementProperties.recordString(item, 'targetScreen') ? `#/${elementProperties.recordString(item, 'targetScreen')}` : undefined
|
|
19
27
|
}));
|
|
20
28
|
return /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
21
29
|
"data-scene-id": element.id,
|
|
22
|
-
children: /*#__PURE__*/ jsxRuntime.jsx(breadcrumb.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(breadcrumb.Breadcrumb.Root, {
|
|
31
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs(breadcrumb.Breadcrumb.List, {
|
|
32
|
+
children: [
|
|
33
|
+
home && /*#__PURE__*/ jsxRuntime.jsx(breadcrumb.Breadcrumb.Item, {
|
|
34
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(breadcrumb.Breadcrumb.Link, {
|
|
35
|
+
as: "a",
|
|
36
|
+
href: `#/${home}`,
|
|
37
|
+
"aria-label": "Home",
|
|
38
|
+
children: /*#__PURE__*/ jsxRuntime.jsx("i", {
|
|
39
|
+
className: "pi pi-home",
|
|
40
|
+
"aria-hidden": "true"
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
}),
|
|
44
|
+
trail.map((entry, index)=>/*#__PURE__*/ jsxRuntime.jsxs(react.Fragment, {
|
|
45
|
+
children: [
|
|
46
|
+
(!!home || index > 0) && /*#__PURE__*/ jsxRuntime.jsx(breadcrumb.Breadcrumb.Separator, {
|
|
47
|
+
children: /*#__PURE__*/ jsxRuntime.jsx("i", {
|
|
48
|
+
className: "pi pi-chevron-right",
|
|
49
|
+
"aria-hidden": "true"
|
|
50
|
+
})
|
|
51
|
+
}),
|
|
52
|
+
/*#__PURE__*/ jsxRuntime.jsx(breadcrumb.Breadcrumb.Item, {
|
|
53
|
+
children: entry.url ? /*#__PURE__*/ jsxRuntime.jsx(breadcrumb.Breadcrumb.Link, {
|
|
54
|
+
as: "a",
|
|
55
|
+
href: entry.url,
|
|
56
|
+
children: entry.label
|
|
57
|
+
}) : /*#__PURE__*/ jsxRuntime.jsx(breadcrumb.Breadcrumb.Current, {
|
|
58
|
+
children: entry.label
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
]
|
|
62
|
+
}, `${index}-${entry.label}`))
|
|
63
|
+
]
|
|
64
|
+
})
|
|
28
65
|
})
|
|
29
66
|
});
|
|
30
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumb.js","sources":["../../../shell/Breadcrumb.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport {
|
|
1
|
+
{"version":3,"file":"Breadcrumb.js","sources":["../../../shell/Breadcrumb.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Fragment } from 'react';\nimport { Breadcrumb as PrimeBreadcrumb } from 'primereact/breadcrumb';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { MenuEntry } from './MenuEntry';\nimport { readOptionalString, readRecords, recordString } from './elementProperties';\n\n/**\n * The trail above the content.\n *\n * PrimeReact's own `Breadcrumb` does the rendering rather than hand-written markup, because a breadcrumb\n * is an ordinary component with no layout-mode behavior at all - it looks the same in every one of the\n * eight modes. The shell only writes CSS where PrimeReact genuinely has no answer, and this is not one of\n * those places: `Breadcrumb.Root` still supplies the `nav`, its `aria-label` and the list semantics, which\n * is the part that is easy to get wrong by hand.\n *\n * What PrimeReact 11 no longer supplies is the `model` array - the component is composed now, and the\n * `primereact/menuitem` type the array was made of is gone with it, which is why the trail is mapped into\n * this package's own {@link MenuEntry}. The last entry is `Breadcrumb.Current` rather than a link: a trail\n * whose final crumb navigates to the page already open is a link that does nothing, and it takes\n * `aria-current='page'` away from the one element that should carry it.\n */\nexport function Breadcrumb({ element }: RegisteredComponentProps) {\n const home = readOptionalString(element, 'homeTargetScreen');\n const trail = readRecords(element, 'items').map(\n (item): MenuEntry => ({\n label: recordString(item, 'label'),\n url: recordString(item, 'targetScreen') ? `#/${recordString(item, 'targetScreen')}` : undefined,\n }),\n );\n\n return (\n <div data-scene-id={element.id}>\n <PrimeBreadcrumb.Root>\n <PrimeBreadcrumb.List>\n {home && (\n <PrimeBreadcrumb.Item>\n <PrimeBreadcrumb.Link as='a' href={`#/${home}`} aria-label='Home'>\n <i className='pi pi-home' aria-hidden='true' />\n </PrimeBreadcrumb.Link>\n </PrimeBreadcrumb.Item>\n )}\n {trail.map((entry, index) => (\n <Fragment key={`${index}-${entry.label}`}>\n {(!!home || index > 0) && (\n <PrimeBreadcrumb.Separator>\n <i className='pi pi-chevron-right' aria-hidden='true' />\n </PrimeBreadcrumb.Separator>\n )}\n <PrimeBreadcrumb.Item>\n {entry.url ? (\n <PrimeBreadcrumb.Link as='a' href={entry.url}>\n {entry.label}\n </PrimeBreadcrumb.Link>\n ) : (\n <PrimeBreadcrumb.Current>{entry.label}</PrimeBreadcrumb.Current>\n )}\n </PrimeBreadcrumb.Item>\n </Fragment>\n ))}\n </PrimeBreadcrumb.List>\n </PrimeBreadcrumb.Root>\n </div>\n );\n}\n"],"names":["Breadcrumb","element","home","readOptionalString","trail","readRecords","map","item","label","recordString","url","undefined","_jsx","div","data-scene-id","id","PrimeBreadcrumb","Root","_jsxs","List","Item","Link","as","href","aria-label","i","className","aria-hidden","entry","index","Fragment","Separator","Current"],"mappings":";;;;;;;AASA;;;;;;;;;;;;;;AAcC,IACM,SAASA,UAAAA,CAAW,EAAEC,OAAO,EAA4B,EAAA;IAC5D,MAAMC,IAAAA,GAAOC,qCAAmBF,OAAAA,EAAS,kBAAA,CAAA;IACzC,MAAMG,KAAAA,GAAQC,8BAAYJ,OAAAA,EAAS,OAAA,CAAA,CAASK,GAAG,CAC3C,CAACC,QAAqB;AAClBC,YAAAA,KAAAA,EAAOC,+BAAaF,IAAAA,EAAM,OAAA,CAAA;YAC1BG,GAAAA,EAAKD,8BAAAA,CAAaF,MAAM,cAAA,CAAA,GAAkB,CAAC,EAAE,EAAEE,8BAAAA,CAAaF,IAAAA,EAAM,cAAA,CAAA,CAAA,CAAiB,GAAGI;SAC1F,CAAA,CAAA;AAGJ,IAAA,qBACIC,cAAA,CAACC,KAAAA,EAAAA;AAAIC,QAAAA,eAAAA,EAAeb,QAAQc,EAAE;gCAC1BH,cAAA,CAACI,sBAAgBC,IAAI,EAAA;oCACjBC,eAAA,CAACF,sBAAgBG,IAAI,EAAA;;oBAChBjB,IAAAA,kBACGU,cAAA,CAACI,sBAAgBI,IAAI,EAAA;gDACjBR,cAAA,CAACI,sBAAgBK,IAAI,EAAA;4BAACC,EAAAA,EAAG,GAAA;4BAAIC,IAAAA,EAAM,CAAC,EAAE,EAAErB,IAAAA,CAAAA,CAAM;4BAAEsB,YAAAA,EAAW,MAAA;AACvD,4BAAA,QAAA,gBAAAZ,cAAA,CAACa,GAAAA,EAAAA;gCAAEC,SAAAA,EAAU,YAAA;gCAAaC,aAAAA,EAAY;;;;AAIjDvB,oBAAAA,KAAAA,CAAME,GAAG,CAAC,CAACsB,KAAAA,EAAOC,sBACfX,eAAA,CAACY,cAAAA,EAAAA;;gCACK,CAAA,CAAC,CAAC5B,IAAAA,IAAQ2B,KAAAA,GAAQ,CAAA,mBAChBjB,cAAA,CAACI,sBAAgBe,SAAS,EAAA;AACtB,oCAAA,QAAA,gBAAAnB,cAAA,CAACa,GAAAA,EAAAA;wCAAEC,SAAAA,EAAU,qBAAA;wCAAsBC,aAAAA,EAAY;;;AAGvD,8CAAAf,cAAA,CAACI,sBAAgBI,IAAI,EAAA;AAChBQ,oCAAAA,QAAAA,EAAAA,KAAAA,CAAMlB,GAAG,iBACNE,cAAA,CAACI,qBAAAA,CAAgBK,IAAI,EAAA;wCAACC,EAAAA,EAAG,GAAA;AAAIC,wCAAAA,IAAAA,EAAMK,MAAMlB,GAAG;AACvCkB,wCAAAA,QAAAA,EAAAA,KAAAA,CAAMpB;AAGX,qCAAA,CAAA,iBAAAI,cAAA,CAACI,sBAAgBgB,OAAO,EAAA;AAAEJ,wCAAAA,QAAAA,EAAAA,KAAAA,CAAMpB;;;;AAZ7B,yBAAA,EAAA,CAAA,EAAGqB,KAAAA,CAAM,CAAC,EAAED,KAAAA,CAAMpB,KAAK,CAAA,CAAE,CAAA;;;;;AAqBhE;;;;"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var react = require('react');
|
|
5
4
|
var button = require('primereact/button');
|
|
6
|
-
var
|
|
5
|
+
var drawer = require('primereact/drawer');
|
|
7
6
|
var ColorScheme = require('../configuration/ColorScheme.js');
|
|
8
7
|
var MenuTheme = require('../configuration/MenuTheme.js');
|
|
9
8
|
var LayoutConfigProvider = require('../configuration/LayoutConfigProvider.js');
|
|
@@ -27,98 +26,128 @@ var elementProperties = require('./elementProperties.js');
|
|
|
27
26
|
* theme - because those are the four choices that actually change how an application feels, and a
|
|
28
27
|
* configurator with more knobs than that becomes a settings screen nobody finishes reading.
|
|
29
28
|
*
|
|
30
|
-
* The panel
|
|
31
|
-
*
|
|
32
|
-
*
|
|
29
|
+
* The panel is `primereact/drawer`, which is the slide-in overlay this component has always wanted.
|
|
30
|
+
* PrimeReact 11 gave the name `Sidebar` to something else entirely - a new app-shell primitive with
|
|
31
|
+
* `SidebarLayout`/`SidebarAside`/`SidebarPanel` parts - so the v10 `Sidebar` import this file used to
|
|
32
|
+
* carry would still resolve after the upgrade and would silently render an app shell inside the shell.
|
|
33
|
+
* That is the one rename in the whole library that fails quietly rather than loudly, which is why it is
|
|
34
|
+
* called out here: this is `Drawer`, deliberately, and it is not the {@link Sidebar} next door either -
|
|
35
|
+
* that one is this package's own component for the docked panel's chrome.
|
|
36
|
+
*
|
|
37
|
+
* Open state is the drawer's own. `Drawer.Trigger` renders in place through `Drawer.Root`'s fragment, so
|
|
38
|
+
* the floating cog sits exactly where it did while getting `aria-expanded`/`aria-controls` from the
|
|
39
|
+
* component rather than from hand-written props that can drift out of step with the panel.
|
|
33
40
|
*/ function ConfigPanel({ element, slots }) {
|
|
34
|
-
const [isVisible, setIsVisible] = react.useState(false);
|
|
35
41
|
const { config, setColorScheme, setMenuTheme } = LayoutConfigProvider.useLayoutConfig();
|
|
36
42
|
const title = elementProperties.readString(element, 'title', 'Settings');
|
|
37
43
|
const showsMenuTheme = elementProperties.readBoolean(element, 'showMenuTheme', true);
|
|
38
44
|
const showsMode = elementProperties.readBoolean(element, 'showLayoutMode', true);
|
|
39
|
-
return /*#__PURE__*/ jsxRuntime.jsxs(
|
|
45
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(drawer.Drawer.Root, {
|
|
46
|
+
position: "right",
|
|
40
47
|
children: [
|
|
41
|
-
/*#__PURE__*/ jsxRuntime.jsx(
|
|
42
|
-
|
|
48
|
+
/*#__PURE__*/ jsxRuntime.jsx(drawer.Drawer.Trigger, {
|
|
49
|
+
as: button.Button,
|
|
43
50
|
rounded: true,
|
|
44
|
-
|
|
51
|
+
iconOnly: true,
|
|
45
52
|
className: "layout-config-button",
|
|
46
53
|
"aria-label": title,
|
|
47
54
|
"data-scene-id": element.id,
|
|
48
|
-
|
|
55
|
+
children: /*#__PURE__*/ jsxRuntime.jsx("i", {
|
|
56
|
+
className: "pi pi-cog",
|
|
57
|
+
"aria-hidden": "true"
|
|
58
|
+
})
|
|
49
59
|
}),
|
|
50
|
-
/*#__PURE__*/ jsxRuntime.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
60
|
+
/*#__PURE__*/ jsxRuntime.jsxs(drawer.Drawer.Portal, {
|
|
61
|
+
children: [
|
|
62
|
+
/*#__PURE__*/ jsxRuntime.jsx(drawer.Drawer.Backdrop, {}),
|
|
63
|
+
/*#__PURE__*/ jsxRuntime.jsxs(drawer.Drawer.Popup, {
|
|
64
|
+
children: [
|
|
65
|
+
/*#__PURE__*/ jsxRuntime.jsxs(drawer.Drawer.Header, {
|
|
66
|
+
children: [
|
|
67
|
+
/*#__PURE__*/ jsxRuntime.jsx(drawer.Drawer.Title, {
|
|
68
|
+
children: title
|
|
69
|
+
}),
|
|
70
|
+
/*#__PURE__*/ jsxRuntime.jsx(drawer.Drawer.Close, {
|
|
71
|
+
"aria-label": `Close ${title}`,
|
|
72
|
+
children: /*#__PURE__*/ jsxRuntime.jsx("i", {
|
|
73
|
+
className: "pi pi-times",
|
|
74
|
+
"aria-hidden": "true"
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
]
|
|
78
|
+
}),
|
|
79
|
+
/*#__PURE__*/ jsxRuntime.jsx(drawer.Drawer.Content, {
|
|
80
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
81
|
+
className: "layout-config-panel",
|
|
82
|
+
children: [
|
|
83
|
+
/*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
84
|
+
children: [
|
|
85
|
+
/*#__PURE__*/ jsxRuntime.jsx("h3", {
|
|
86
|
+
className: "layout-config-section-title",
|
|
87
|
+
children: "Color scheme"
|
|
88
|
+
}),
|
|
89
|
+
/*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
90
|
+
className: "layout-config-options",
|
|
91
|
+
role: "group",
|
|
92
|
+
"aria-label": "Color scheme",
|
|
93
|
+
children: ColorScheme.colorSchemes.map((scheme)=>/*#__PURE__*/ jsxRuntime.jsx("button", {
|
|
94
|
+
type: "button",
|
|
95
|
+
className: "layout-config-option",
|
|
96
|
+
"aria-pressed": config.colorScheme === scheme,
|
|
97
|
+
onClick: ()=>setColorScheme(scheme),
|
|
98
|
+
children: colorSchemeLabels[scheme]
|
|
99
|
+
}, scheme))
|
|
100
|
+
})
|
|
101
|
+
]
|
|
102
|
+
}),
|
|
103
|
+
/*#__PURE__*/ jsxRuntime.jsx(ThemeSwitcher.ThemeSwitcher, {
|
|
104
|
+
element: {
|
|
105
|
+
...element,
|
|
106
|
+
id: `${element.id}-theme`,
|
|
107
|
+
properties: {
|
|
108
|
+
...element.properties,
|
|
109
|
+
label: 'Theme'
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
slots: {}
|
|
113
|
+
}),
|
|
114
|
+
showsMode && /*#__PURE__*/ jsxRuntime.jsx(LayoutModeSwitcher.LayoutModeSwitcher, {
|
|
115
|
+
element: {
|
|
116
|
+
...element,
|
|
117
|
+
id: `${element.id}-mode`,
|
|
118
|
+
properties: {
|
|
119
|
+
label: 'Menu mode'
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
slots: {}
|
|
123
|
+
}),
|
|
124
|
+
showsMenuTheme && /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
125
|
+
children: [
|
|
126
|
+
/*#__PURE__*/ jsxRuntime.jsx("h3", {
|
|
127
|
+
className: "layout-config-section-title",
|
|
128
|
+
children: "Menu theme"
|
|
129
|
+
}),
|
|
130
|
+
/*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
131
|
+
className: "layout-config-options",
|
|
132
|
+
role: "group",
|
|
133
|
+
"aria-label": "Menu theme",
|
|
134
|
+
children: MenuTheme.menuThemes.map((menuTheme)=>/*#__PURE__*/ jsxRuntime.jsx("button", {
|
|
135
|
+
type: "button",
|
|
136
|
+
className: "layout-config-option",
|
|
137
|
+
"aria-pressed": config.menuTheme === menuTheme,
|
|
138
|
+
onClick: ()=>setMenuTheme(menuTheme),
|
|
139
|
+
children: menuThemeLabels[menuTheme]
|
|
140
|
+
}, menuTheme))
|
|
141
|
+
})
|
|
142
|
+
]
|
|
143
|
+
}),
|
|
144
|
+
slots.content
|
|
145
|
+
]
|
|
75
146
|
})
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
...element,
|
|
81
|
-
id: `${element.id}-theme`,
|
|
82
|
-
properties: {
|
|
83
|
-
...element.properties,
|
|
84
|
-
label: 'Theme'
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
slots: {}
|
|
88
|
-
}),
|
|
89
|
-
showsMode && /*#__PURE__*/ jsxRuntime.jsx(LayoutModeSwitcher.LayoutModeSwitcher, {
|
|
90
|
-
element: {
|
|
91
|
-
...element,
|
|
92
|
-
id: `${element.id}-mode`,
|
|
93
|
-
properties: {
|
|
94
|
-
label: 'Menu mode'
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
slots: {}
|
|
98
|
-
}),
|
|
99
|
-
showsMenuTheme && /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
100
|
-
children: [
|
|
101
|
-
/*#__PURE__*/ jsxRuntime.jsx("h3", {
|
|
102
|
-
className: "layout-config-section-title",
|
|
103
|
-
children: "Menu theme"
|
|
104
|
-
}),
|
|
105
|
-
/*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
106
|
-
className: "layout-config-options",
|
|
107
|
-
role: "group",
|
|
108
|
-
"aria-label": "Menu theme",
|
|
109
|
-
children: MenuTheme.menuThemes.map((menuTheme)=>/*#__PURE__*/ jsxRuntime.jsx("button", {
|
|
110
|
-
type: "button",
|
|
111
|
-
className: "layout-config-option",
|
|
112
|
-
"aria-pressed": config.menuTheme === menuTheme,
|
|
113
|
-
onClick: ()=>setMenuTheme(menuTheme),
|
|
114
|
-
children: menuThemeLabels[menuTheme]
|
|
115
|
-
}, menuTheme))
|
|
116
|
-
})
|
|
117
|
-
]
|
|
118
|
-
}),
|
|
119
|
-
slots.content
|
|
120
|
-
]
|
|
121
|
-
})
|
|
147
|
+
})
|
|
148
|
+
]
|
|
149
|
+
})
|
|
150
|
+
]
|
|
122
151
|
})
|
|
123
152
|
]
|
|
124
153
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigPanel.js","sources":["../../../shell/ConfigPanel.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useState } from 'react';\nimport { Button } from 'primereact/button';\nimport { Sidebar } from 'primereact/sidebar';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { ColorScheme, MenuTheme, colorSchemes, menuThemes, useLayoutConfig } from '../configuration';\nimport { LayoutModeSwitcher } from './LayoutModeSwitcher';\nimport { ThemeSwitcher } from './ThemeSwitcher';\nimport { readBoolean, readString } from './elementProperties';\n\n/** What each color scheme is called in the configurator. */\nconst colorSchemeLabels: Record<ColorScheme, string> = {\n [ColorScheme.Light]: 'Light',\n [ColorScheme.Dark]: 'Dark',\n};\n\n/** What each menu theme is called in the configurator. */\nconst menuThemeLabels: Record<MenuTheme, string> = {\n [MenuTheme.Light]: 'Light',\n [MenuTheme.Dark]: 'Dark',\n [MenuTheme.Primary]: 'Primary',\n};\n\n/**\n * The floating configurator.\n *\n * The axes are the ones the modern PrimeTek templates expose - color scheme, menu mode, menu theme and\n * theme - because those are the four choices that actually change how an application feels, and a\n * configurator with more knobs than that becomes a settings screen nobody finishes reading.\n *\n * The panel itself is PrimeReact 10's `Sidebar`, which is an overlay drawer rather than an app-shell\n * sidebar - this is the one use it was designed for. (v11 renames it `Drawer` precisely to stop the\n * confusion, and gives the app-shell role to a new `Sidebar`.)\n */\nexport function ConfigPanel({ element, slots }: RegisteredComponentProps) {\n const [isVisible, setIsVisible] = useState(false);\n const { config, setColorScheme, setMenuTheme } = useLayoutConfig();\n const title = readString(element, 'title', 'Settings');\n const showsMenuTheme = readBoolean(element, 'showMenuTheme', true);\n const showsMode = readBoolean(element, 'showLayoutMode', true);\n\n return (\n <>\n <Button\n type='button'\n rounded\n icon='pi pi-cog'\n className='layout-config-button'\n aria-label={title}\n data-scene-id={element.id}\n onClick={() => setIsVisible(true)}\n />\n <Sidebar visible={isVisible} position='right' header={title} onHide={() => setIsVisible(false)}>\n <div className='layout-config-panel'>\n <div>\n <h3 className='layout-config-section-title'>Color scheme</h3>\n <div className='layout-config-options' role='group' aria-label='Color scheme'>\n {colorSchemes.map(scheme => (\n <button\n key={scheme}\n type='button'\n className='layout-config-option'\n aria-pressed={config.colorScheme === scheme}\n onClick={() => setColorScheme(scheme)}>\n {colorSchemeLabels[scheme]}\n </button>\n ))}\n </div>\n </div>\n\n <ThemeSwitcher\n element={{ ...element, id: `${element.id}-theme`, properties: { ...element.properties, label: 'Theme' } }}\n slots={{}}\n />\n\n {showsMode && (\n <LayoutModeSwitcher element={{ ...element, id: `${element.id}-mode`, properties: { label: 'Menu mode' } }} slots={{}} />\n )}\n\n {showsMenuTheme && (\n <div>\n <h3 className='layout-config-section-title'>Menu theme</h3>\n <div className='layout-config-options' role='group' aria-label='Menu theme'>\n {menuThemes.map(menuTheme => (\n <button\n key={menuTheme}\n type='button'\n className='layout-config-option'\n aria-pressed={config.menuTheme === menuTheme}\n onClick={() => setMenuTheme(menuTheme)}>\n {menuThemeLabels[menuTheme]}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {slots.content}\n </div>\n </Sidebar>\n </>\n );\n}\n"],"names":["colorSchemeLabels","ColorScheme","Light","Dark","menuThemeLabels","MenuTheme","Primary","ConfigPanel","element","slots","isVisible","setIsVisible","useState","config","setColorScheme","setMenuTheme","useLayoutConfig","title","readString","showsMenuTheme","readBoolean","showsMode","_jsxs","_Fragment","_jsx","Button","type","rounded","icon","className","aria-label","data-scene-id","id","onClick","Sidebar","visible","position","header","onHide","div","h3","role","colorSchemes","map","scheme","button","aria-pressed","colorScheme","ThemeSwitcher","properties","label","LayoutModeSwitcher","menuThemes","menuTheme","content"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ConfigPanel.js","sources":["../../../shell/ConfigPanel.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Button } from 'primereact/button';\nimport { Drawer } from 'primereact/drawer';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { ColorScheme, MenuTheme, colorSchemes, menuThemes, useLayoutConfig } from '../configuration';\nimport { LayoutModeSwitcher } from './LayoutModeSwitcher';\nimport { ThemeSwitcher } from './ThemeSwitcher';\nimport { readBoolean, readString } from './elementProperties';\n\n/** What each color scheme is called in the configurator. */\nconst colorSchemeLabels: Record<ColorScheme, string> = {\n [ColorScheme.Light]: 'Light',\n [ColorScheme.Dark]: 'Dark',\n};\n\n/** What each menu theme is called in the configurator. */\nconst menuThemeLabels: Record<MenuTheme, string> = {\n [MenuTheme.Light]: 'Light',\n [MenuTheme.Dark]: 'Dark',\n [MenuTheme.Primary]: 'Primary',\n};\n\n/**\n * The floating configurator.\n *\n * The axes are the ones the modern PrimeTek templates expose - color scheme, menu mode, menu theme and\n * theme - because those are the four choices that actually change how an application feels, and a\n * configurator with more knobs than that becomes a settings screen nobody finishes reading.\n *\n * The panel is `primereact/drawer`, which is the slide-in overlay this component has always wanted.\n * PrimeReact 11 gave the name `Sidebar` to something else entirely - a new app-shell primitive with\n * `SidebarLayout`/`SidebarAside`/`SidebarPanel` parts - so the v10 `Sidebar` import this file used to\n * carry would still resolve after the upgrade and would silently render an app shell inside the shell.\n * That is the one rename in the whole library that fails quietly rather than loudly, which is why it is\n * called out here: this is `Drawer`, deliberately, and it is not the {@link Sidebar} next door either -\n * that one is this package's own component for the docked panel's chrome.\n *\n * Open state is the drawer's own. `Drawer.Trigger` renders in place through `Drawer.Root`'s fragment, so\n * the floating cog sits exactly where it did while getting `aria-expanded`/`aria-controls` from the\n * component rather than from hand-written props that can drift out of step with the panel.\n */\nexport function ConfigPanel({ element, slots }: RegisteredComponentProps) {\n const { config, setColorScheme, setMenuTheme } = useLayoutConfig();\n const title = readString(element, 'title', 'Settings');\n const showsMenuTheme = readBoolean(element, 'showMenuTheme', true);\n const showsMode = readBoolean(element, 'showLayoutMode', true);\n\n return (\n <Drawer.Root position='right'>\n <Drawer.Trigger as={Button} rounded iconOnly className='layout-config-button' aria-label={title} data-scene-id={element.id}>\n <i className='pi pi-cog' aria-hidden='true' />\n </Drawer.Trigger>\n <Drawer.Portal>\n <Drawer.Backdrop />\n <Drawer.Popup>\n <Drawer.Header>\n <Drawer.Title>{title}</Drawer.Title>\n <Drawer.Close aria-label={`Close ${title}`}>\n <i className='pi pi-times' aria-hidden='true' />\n </Drawer.Close>\n </Drawer.Header>\n <Drawer.Content>\n <div className='layout-config-panel'>\n <div>\n <h3 className='layout-config-section-title'>Color scheme</h3>\n <div className='layout-config-options' role='group' aria-label='Color scheme'>\n {colorSchemes.map(scheme => (\n <button\n key={scheme}\n type='button'\n className='layout-config-option'\n aria-pressed={config.colorScheme === scheme}\n onClick={() => setColorScheme(scheme)}>\n {colorSchemeLabels[scheme]}\n </button>\n ))}\n </div>\n </div>\n\n <ThemeSwitcher\n element={{ ...element, id: `${element.id}-theme`, properties: { ...element.properties, label: 'Theme' } }}\n slots={{}}\n />\n\n {showsMode && (\n <LayoutModeSwitcher element={{ ...element, id: `${element.id}-mode`, properties: { label: 'Menu mode' } }} slots={{}} />\n )}\n\n {showsMenuTheme && (\n <div>\n <h3 className='layout-config-section-title'>Menu theme</h3>\n <div className='layout-config-options' role='group' aria-label='Menu theme'>\n {menuThemes.map(menuTheme => (\n <button\n key={menuTheme}\n type='button'\n className='layout-config-option'\n aria-pressed={config.menuTheme === menuTheme}\n onClick={() => setMenuTheme(menuTheme)}>\n {menuThemeLabels[menuTheme]}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {slots.content}\n </div>\n </Drawer.Content>\n </Drawer.Popup>\n </Drawer.Portal>\n </Drawer.Root>\n );\n}\n"],"names":["colorSchemeLabels","ColorScheme","Light","Dark","menuThemeLabels","MenuTheme","Primary","ConfigPanel","element","slots","config","setColorScheme","setMenuTheme","useLayoutConfig","title","readString","showsMenuTheme","readBoolean","showsMode","_jsxs","Drawer","Root","position","_jsx","Trigger","as","Button","rounded","iconOnly","className","aria-label","data-scene-id","id","i","aria-hidden","Portal","Backdrop","Popup","Header","Title","Close","Content","div","h3","role","colorSchemes","map","scheme","button","type","aria-pressed","colorScheme","onClick","ThemeSwitcher","properties","label","LayoutModeSwitcher","menuThemes","menuTheme","content"],"mappings":"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"}
|
|
@@ -33,12 +33,16 @@ var elementProperties = require('./elementProperties.js');
|
|
|
33
33
|
}),
|
|
34
34
|
isPinnable && /*#__PURE__*/ jsxRuntime.jsx(button.Button, {
|
|
35
35
|
type: "button",
|
|
36
|
-
|
|
36
|
+
variant: "text",
|
|
37
37
|
rounded: true,
|
|
38
|
-
|
|
38
|
+
iconOnly: true,
|
|
39
39
|
"aria-label": config.isSidebarAnchored ? 'Unpin the menu' : 'Pin the menu open',
|
|
40
40
|
"aria-pressed": config.isSidebarAnchored,
|
|
41
|
-
onClick: toggleSidebarAnchor
|
|
41
|
+
onClick: toggleSidebarAnchor,
|
|
42
|
+
children: /*#__PURE__*/ jsxRuntime.jsx("i", {
|
|
43
|
+
className: config.isSidebarAnchored ? 'pi pi-lock' : 'pi pi-lock-open',
|
|
44
|
+
"aria-hidden": "true"
|
|
45
|
+
})
|
|
42
46
|
})
|
|
43
47
|
]
|
|
44
48
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar.js","sources":["../../../shell/Sidebar.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Button } from 'primereact/button';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { isPointerRevealMode, useLayoutConfig } from '../configuration';\nimport { readString } from './elementProperties';\n\n/**\n * The sidebar's own chrome, inside the panel {@link AppShell} positions.\n *\n * The panel and its contents are deliberately different components. Everything about *where* the sidebar\n * is - translated off-canvas, collapsed to a rail, growing on hover - belongs to the mode and therefore to\n * the shell; everything about *what is in it* belongs to the screen. A template can replace this header\n * wholesale without any of the mode CSS noticing.\n *\n * The pin button only appears in `reveal` and `drawer`, the two modes where the sidebar answers to the\n * pointer and therefore needs a way to be made to stay.\n */\nexport function Sidebar({ element, slots }: RegisteredComponentProps) {\n const { effectiveMode, config, toggleSidebarAnchor } = useLayoutConfig();\n const title = readString(element, 'title');\n const isPinnable = isPointerRevealMode(effectiveMode);\n\n return (\n <>\n <div className='layout-sidebar-header' data-scene-id={element.id}>\n {slots.logo}\n {title && <span className='layout-sidebar-title'>{title}</span>}\n {isPinnable && (\n <Button\n type='button'\n text\n rounded\n
|
|
1
|
+
{"version":3,"file":"Sidebar.js","sources":["../../../shell/Sidebar.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Button } from 'primereact/button';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { isPointerRevealMode, useLayoutConfig } from '../configuration';\nimport { readString } from './elementProperties';\n\n/**\n * The sidebar's own chrome, inside the panel {@link AppShell} positions.\n *\n * The panel and its contents are deliberately different components. Everything about *where* the sidebar\n * is - translated off-canvas, collapsed to a rail, growing on hover - belongs to the mode and therefore to\n * the shell; everything about *what is in it* belongs to the screen. A template can replace this header\n * wholesale without any of the mode CSS noticing.\n *\n * The pin button only appears in `reveal` and `drawer`, the two modes where the sidebar answers to the\n * pointer and therefore needs a way to be made to stay.\n */\nexport function Sidebar({ element, slots }: RegisteredComponentProps) {\n const { effectiveMode, config, toggleSidebarAnchor } = useLayoutConfig();\n const title = readString(element, 'title');\n const isPinnable = isPointerRevealMode(effectiveMode);\n\n return (\n <>\n <div className='layout-sidebar-header' data-scene-id={element.id}>\n {slots.logo}\n {title && <span className='layout-sidebar-title'>{title}</span>}\n {isPinnable && (\n <Button\n type='button'\n variant='text'\n rounded\n iconOnly\n aria-label={config.isSidebarAnchored ? 'Unpin the menu' : 'Pin the menu open'}\n aria-pressed={config.isSidebarAnchored}\n onClick={toggleSidebarAnchor}>\n <i className={config.isSidebarAnchored ? 'pi pi-lock' : 'pi pi-lock-open'} aria-hidden='true' />\n </Button>\n )}\n </div>\n {slots.content}\n </>\n );\n}\n"],"names":["Sidebar","element","slots","effectiveMode","config","toggleSidebarAnchor","useLayoutConfig","title","readString","isPinnable","isPointerRevealMode","_jsxs","_Fragment","div","className","data-scene-id","id","logo","_jsx","span","Button","type","variant","rounded","iconOnly","aria-label","isSidebarAnchored","aria-pressed","onClick","i","aria-hidden","content"],"mappings":";;;;;;;;AAQA;;;;;;;;;;AAUC,IACM,SAASA,OAAAA,CAAQ,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AAChE,IAAA,MAAM,EAAEC,aAAa,EAAEC,MAAM,EAAEC,mBAAmB,EAAE,GAAGC,oCAAAA,EAAAA;IACvD,MAAMC,KAAAA,GAAQC,6BAAWP,OAAAA,EAAS,OAAA,CAAA;AAClC,IAAA,MAAMQ,aAAaC,2CAAAA,CAAoBP,aAAAA,CAAAA;IAEvC,qBACIQ,eAAA,CAAAC,mBAAA,EAAA;;0BACID,eAAA,CAACE,KAAAA,EAAAA;gBAAIC,SAAAA,EAAU,uBAAA;AAAwBC,gBAAAA,eAAAA,EAAed,QAAQe,EAAE;;AAC3Dd,oBAAAA,KAAAA,CAAMe,IAAI;AACVV,oBAAAA,KAAAA,kBAASW,cAAA,CAACC,MAAAA,EAAAA;wBAAKL,SAAAA,EAAU,sBAAA;AAAwBP,wBAAAA,QAAAA,EAAAA;;AACjDE,oBAAAA,UAAAA,kBACGS,cAAA,CAACE,aAAAA,EAAAA;wBACGC,IAAAA,EAAK,QAAA;wBACLC,OAAAA,EAAQ,MAAA;wBACRC,OAAO,EAAA,IAAA;wBACPC,QAAQ,EAAA,IAAA;wBACRC,YAAAA,EAAYrB,MAAAA,CAAOsB,iBAAiB,GAAG,gBAAA,GAAmB,mBAAA;AAC1DC,wBAAAA,cAAAA,EAAcvB,OAAOsB,iBAAiB;wBACtCE,OAAAA,EAASvB,mBAAAA;AACT,wBAAA,QAAA,gBAAAa,cAAA,CAACW,GAAAA,EAAAA;4BAAEf,SAAAA,EAAWV,MAAAA,CAAOsB,iBAAiB,GAAG,YAAA,GAAe,iBAAA;4BAAmBI,aAAAA,EAAY;;;;;AAIlG5B,YAAAA,KAAAA,CAAM6B;;;AAGnB;;;;"}
|
package/dist/cjs/shell/Topbar.js
CHANGED
|
@@ -27,12 +27,16 @@ var elementProperties = require('./elementProperties.js');
|
|
|
27
27
|
children: [
|
|
28
28
|
showsToggle && /*#__PURE__*/ jsxRuntime.jsx(button.Button, {
|
|
29
29
|
type: "button",
|
|
30
|
-
|
|
30
|
+
variant: "text",
|
|
31
31
|
rounded: true,
|
|
32
|
-
|
|
32
|
+
iconOnly: true,
|
|
33
33
|
"aria-label": config.isSidebarOpen ? 'Close the menu' : 'Open the menu',
|
|
34
34
|
"aria-expanded": config.isSidebarOpen,
|
|
35
|
-
onClick: toggleSidebar
|
|
35
|
+
onClick: toggleSidebar,
|
|
36
|
+
children: /*#__PURE__*/ jsxRuntime.jsx("i", {
|
|
37
|
+
className: "pi pi-bars",
|
|
38
|
+
"aria-hidden": "true"
|
|
39
|
+
})
|
|
36
40
|
}),
|
|
37
41
|
slots.logo,
|
|
38
42
|
slots.start
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Topbar.js","sources":["../../../shell/Topbar.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Button } from 'primereact/button';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { LayoutMode, useLayoutConfig } from '../configuration';\nimport { readBoolean } from './elementProperties';\n\n/**\n * The fixed strip across the top of the application shell.\n *\n * It owns the one control every mode needs: the sidebar toggle. In `horizontal` mode it also hosts the\n * menu itself, which is why the menu arrives here as a slot rather than being hard-wired into the\n * sidebar - the same navigation markup has to be able to render in two places.\n *\n * The toggle hides itself in the rail modes, where there is nothing to toggle: `slim`, `slim-plus` and\n * `compact` are always showing, `reveal` and `drawer` answer to the pointer and the pin, and `horizontal`\n * has no sidebar at all. A button that does nothing is worse than no button.\n */\nexport function Topbar({ element, slots }: RegisteredComponentProps) {\n const { effectiveMode, config, toggleSidebar } = useLayoutConfig();\n const showsToggle = readBoolean(element, 'showToggle', true) && togglesSidebar(effectiveMode);\n\n return (\n <>\n <div className='layout-topbar-start' data-scene-id={element.id}>\n {showsToggle && (\n <Button\n type='button'\n text\n rounded\n
|
|
1
|
+
{"version":3,"file":"Topbar.js","sources":["../../../shell/Topbar.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Button } from 'primereact/button';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { LayoutMode, useLayoutConfig } from '../configuration';\nimport { readBoolean } from './elementProperties';\n\n/**\n * The fixed strip across the top of the application shell.\n *\n * It owns the one control every mode needs: the sidebar toggle. In `horizontal` mode it also hosts the\n * menu itself, which is why the menu arrives here as a slot rather than being hard-wired into the\n * sidebar - the same navigation markup has to be able to render in two places.\n *\n * The toggle hides itself in the rail modes, where there is nothing to toggle: `slim`, `slim-plus` and\n * `compact` are always showing, `reveal` and `drawer` answer to the pointer and the pin, and `horizontal`\n * has no sidebar at all. A button that does nothing is worse than no button.\n */\nexport function Topbar({ element, slots }: RegisteredComponentProps) {\n const { effectiveMode, config, toggleSidebar } = useLayoutConfig();\n const showsToggle = readBoolean(element, 'showToggle', true) && togglesSidebar(effectiveMode);\n\n return (\n <>\n <div className='layout-topbar-start' data-scene-id={element.id}>\n {showsToggle && (\n <Button\n type='button'\n variant='text'\n rounded\n iconOnly\n aria-label={config.isSidebarOpen ? 'Close the menu' : 'Open the menu'}\n aria-expanded={config.isSidebarOpen}\n onClick={toggleSidebar}>\n <i className='pi pi-bars' aria-hidden='true' />\n </Button>\n )}\n {slots.logo}\n {slots.start}\n </div>\n {slots.menu}\n <div className='layout-topbar-end'>{slots.end}</div>\n </>\n );\n}\n\nfunction togglesSidebar(mode: LayoutMode): boolean {\n return mode === LayoutMode.Static || mode === LayoutMode.Overlay;\n}\n"],"names":["Topbar","element","slots","effectiveMode","config","toggleSidebar","useLayoutConfig","showsToggle","readBoolean","togglesSidebar","_jsxs","_Fragment","div","className","data-scene-id","id","_jsx","Button","type","variant","rounded","iconOnly","aria-label","isSidebarOpen","aria-expanded","onClick","i","aria-hidden","logo","start","menu","end","mode","LayoutMode","Static","Overlay"],"mappings":";;;;;;;;AAQA;;;;;;;;;;AAUC,IACM,SAASA,MAAAA,CAAO,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AAC/D,IAAA,MAAM,EAAEC,aAAa,EAAEC,MAAM,EAAEC,aAAa,EAAE,GAAGC,oCAAAA,EAAAA;AACjD,IAAA,MAAMC,WAAAA,GAAcC,6BAAAA,CAAYP,OAAAA,EAAS,YAAA,EAAc,SAASQ,cAAAA,CAAeN,aAAAA,CAAAA;IAE/E,qBACIO,eAAA,CAAAC,mBAAA,EAAA;;0BACID,eAAA,CAACE,KAAAA,EAAAA;gBAAIC,SAAAA,EAAU,qBAAA;AAAsBC,gBAAAA,eAAAA,EAAeb,QAAQc,EAAE;;AACzDR,oBAAAA,WAAAA,kBACGS,cAAA,CAACC,aAAAA,EAAAA;wBACGC,IAAAA,EAAK,QAAA;wBACLC,OAAAA,EAAQ,MAAA;wBACRC,OAAO,EAAA,IAAA;wBACPC,QAAQ,EAAA,IAAA;wBACRC,YAAAA,EAAYlB,MAAAA,CAAOmB,aAAa,GAAG,gBAAA,GAAmB,eAAA;AACtDC,wBAAAA,eAAAA,EAAepB,OAAOmB,aAAa;wBACnCE,OAAAA,EAASpB,aAAAA;AACT,wBAAA,QAAA,gBAAAW,cAAA,CAACU,GAAAA,EAAAA;4BAAEb,SAAAA,EAAU,YAAA;4BAAac,aAAAA,EAAY;;;AAG7CzB,oBAAAA,KAAAA,CAAM0B,IAAI;AACV1B,oBAAAA,KAAAA,CAAM2B;;;AAEV3B,YAAAA,KAAAA,CAAM4B,IAAI;0BACXd,cAAA,CAACJ,KAAAA,EAAAA;gBAAIC,SAAAA,EAAU,mBAAA;AAAqBX,gBAAAA,QAAAA,EAAAA,KAAAA,CAAM6B;;;;AAGtD;AAEA,SAAStB,eAAeuB,IAAgB,EAAA;AACpC,IAAA,OAAOA,SAASC,qBAAAA,CAAWC,MAAM,IAAIF,IAAAA,KAASC,sBAAWE,OAAO;AACpE;;;;"}
|