editor-shell 0.12.0 → 0.13.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 +31 -4
- package/dist/{chunk-3VMFPQGZ.js → chunk-HYOACICE.js} +11 -5
- package/dist/chunk-HYOACICE.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/rail/index.d.ts +43 -9
- package/dist/rail/index.js +1 -1
- package/dist/rail/rail.css +39 -0
- package/package.json +1 -1
- package/dist/chunk-3VMFPQGZ.js.map +0 -1
package/README.md
CHANGED
|
@@ -50,16 +50,38 @@ export function LeftRail({ view, onView, onAdd }) {
|
|
|
50
50
|
|
|
51
51
|
## API
|
|
52
52
|
|
|
53
|
-
### `<EditorRail items ariaLabel? className? />`
|
|
53
|
+
### `<EditorRail items ariaLabel? className? orientation? />`
|
|
54
54
|
|
|
55
|
-
A **pure presentational**
|
|
56
|
-
|
|
55
|
+
A **pure presentational** toolbar. It owns the look, never the app state — you
|
|
56
|
+
decide which item is `active` and what each `onSelect` does.
|
|
57
57
|
|
|
58
58
|
| prop | type | default | notes |
|
|
59
59
|
|---|---|---|---|
|
|
60
|
-
| `items` | `EditorRailItem[]` | — | buttons,
|
|
60
|
+
| `items` | `EditorRailItem[]` | — | buttons, in render order |
|
|
61
61
|
| `ariaLabel` | `string` | `"Editor"` | names the toolbar for assistive tech |
|
|
62
62
|
| `className` | `string` | — | merged onto `.es-rail` |
|
|
63
|
+
| `orientation` | `'column' \| 'row'` | `'column'` | which way the buttons run |
|
|
64
|
+
|
|
65
|
+
#### `orientation`
|
|
66
|
+
|
|
67
|
+
`'column'` is the rail every editor draws today: a fixed 46px strip wearing its
|
|
68
|
+
own card. It is the default, and it renders exactly what it rendered before this
|
|
69
|
+
prop existed.
|
|
70
|
+
|
|
71
|
+
`'row'` lays the same buttons left to right for a top bar — **no fixed width**
|
|
72
|
+
(as wide as its buttons) and **no card** (no background, radius or shadow),
|
|
73
|
+
because the bar already has its own surface. The button size, icon size, gap and
|
|
74
|
+
every hover/active colour are identical in both directions; only the container
|
|
75
|
+
changes. A row is 34px tall, so a 52px bar centres it with 9px to spare.
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
// The same rail, in the top bar's empty middle.
|
|
79
|
+
<EditorRail orientation="row" ariaLabel="Editor views" items={items} />
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`aria-orientation` follows the layout (`vertical` / `horizontal`); the `toolbar`
|
|
83
|
+
role does not change, because a rail that mixes view toggles with plain actions
|
|
84
|
+
is a toolbar whichever way it runs.
|
|
63
85
|
|
|
64
86
|
### `EditorRailItem`
|
|
65
87
|
|
|
@@ -102,6 +124,11 @@ properties on `.es-rail`). Taken verbatim from the storefront editor's `.sf-rail
|
|
|
102
124
|
| accent (active) | `#2563eb` | `--es-rail-accent` |
|
|
103
125
|
| accent tint (active bg) | `#eff6ff` | `--es-rail-accent-tint` |
|
|
104
126
|
|
|
127
|
+
`orientation="row"` adds **no new token**. It re-points three of the ones above
|
|
128
|
+
— `--es-rail-bg` to `transparent`, `--es-rail-shadow` to `none`,
|
|
129
|
+
`--es-rail-radius` to `0` — so the card look stays declared in one place, and it
|
|
130
|
+
reuses `--es-rail-pad-y` rotated onto the row's ends and `--es-rail-gap` as-is.
|
|
131
|
+
|
|
105
132
|
Re-theme without new CSS by overriding a var on the element:
|
|
106
133
|
`style={{ ['--es-rail-accent']: brand }}`.
|
|
107
134
|
|
|
@@ -24,13 +24,19 @@ function EditorRailButton({
|
|
|
24
24
|
}
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
|
-
function EditorRail({
|
|
27
|
+
function EditorRail({
|
|
28
|
+
items,
|
|
29
|
+
ariaLabel = "Editor",
|
|
30
|
+
className,
|
|
31
|
+
orientation = "column"
|
|
32
|
+
}) {
|
|
33
|
+
const row = orientation === "row";
|
|
28
34
|
return /* @__PURE__ */ jsx(
|
|
29
35
|
"div",
|
|
30
36
|
{
|
|
31
|
-
className: ["es-rail", className ?? ""].filter(Boolean).join(" "),
|
|
37
|
+
className: ["es-rail", row ? "es-rail-row" : "", className ?? ""].filter(Boolean).join(" "),
|
|
32
38
|
role: "toolbar",
|
|
33
|
-
"aria-orientation": "vertical",
|
|
39
|
+
"aria-orientation": row ? "horizontal" : "vertical",
|
|
34
40
|
"aria-label": ariaLabel,
|
|
35
41
|
children: items.map((item) => /* @__PURE__ */ jsx(
|
|
36
42
|
EditorRailButton,
|
|
@@ -102,5 +108,5 @@ var railCssVars = {
|
|
|
102
108
|
};
|
|
103
109
|
|
|
104
110
|
export { EditorRail, EditorRailButton, railCssVars, railTokens };
|
|
105
|
-
//# sourceMappingURL=chunk-
|
|
106
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-HYOACICE.js.map
|
|
112
|
+
//# sourceMappingURL=chunk-HYOACICE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rail/EditorRailButton.tsx","../src/rail/EditorRail.tsx","../src/rail/tokens.ts"],"names":["jsx"],"mappings":"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","file":"chunk-HYOACICE.js","sourcesContent":["import type { EditorRailButtonProps } from './types';\n\n/**\n * A single rail button: an icon in a 34×34 square that hovers, highlights when\n * active, and dims when disabled. Look only — the caller owns the click.\n *\n * `aria-pressed` is emitted **only** when `active` is a real boolean, so a view\n * toggle announces its pressed state while an action button (the quick-add \"+\",\n * whose item omits `active`) stays a plain button rather than a stuck toggle.\n */\nexport function EditorRailButton({\n label,\n icon,\n active,\n disabled,\n onSelect,\n className,\n}: EditorRailButtonProps) {\n const classes = ['es-rail-btn', active ? 'is-active' : '', className ?? '']\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n type=\"button\"\n className={classes}\n title={label}\n aria-label={label}\n aria-pressed={typeof active === 'boolean' ? active : undefined}\n disabled={disabled}\n onClick={disabled ? undefined : onSelect}\n >\n {icon}\n </button>\n );\n}\n","import { EditorRailButton } from './EditorRailButton';\nimport type { EditorRailProps } from './types';\n\n/**\n * The shared icon-rail — one slim strip of icon buttons that every EFFICIENT\n * editor uses to switch panels (Pages / Layers / Styles / Media / Sitemap) and\n * to quick-add (\"+\"). By default it is the vertical strip down the left; pass\n * `orientation=\"row\"` and the same buttons lay into a top bar instead. It is a\n * **pure presentational switcher**: give it `items[]`, it draws them; which one\n * is `active` and what each does is the host's business.\n *\n * No `'use client'` here on purpose — the rail has no hooks or state, so it is a\n * plain module a Next-16 server component can import and even statically render.\n * It's interactive only through the `onSelect` props the host passes, and the\n * host owns its client boundary (both editors' chrome are already client\n * components), so baking a directive into this leaf would only narrow where it\n * can be imported.\n *\n * A `toolbar` (not a `tablist`), because the rail mixes view *toggles* with\n * plain *actions* like the quick-add — a toolbar of buttons models that\n * honestly, where a tablist would force every button to pretend to be a tab.\n * That is true in both directions, so `orientation` moves `aria-orientation`\n * and leaves the role alone: what the rail IS did not change, only which way it\n * runs — and a toolbar's arrow keys follow its orientation, so a row that kept\n * saying `vertical` would describe the wrong keys.\n *\n * `orientation` defaults to `'column'`, and that path is byte-identical to what\n * this component rendered before the prop existed: same class list, same\n * attributes, same order. `'row'` adds ONE modifier class beside `es-rail` —\n * never instead of it, since every button rule and token in rail.css hangs off\n * the base class — and rail.css does the rest.\n */\nexport function EditorRail({\n items,\n ariaLabel = 'Editor',\n className,\n orientation = 'column',\n}: EditorRailProps) {\n const row = orientation === 'row';\n\n return (\n <div\n className={['es-rail', row ? 'es-rail-row' : '', className ?? '']\n .filter(Boolean)\n .join(' ')}\n role=\"toolbar\"\n aria-orientation={row ? 'horizontal' : 'vertical'}\n aria-label={ariaLabel}\n >\n {items.map((item) => (\n <EditorRailButton\n key={item.id}\n label={item.label}\n icon={item.icon}\n active={item.active}\n disabled={item.disabled}\n onSelect={item.onSelect}\n />\n ))}\n </div>\n );\n}\n","/**\n * Rail design tokens — the ONE source both apps' rails converge on.\n *\n * Every value below is taken verbatim from the storefront editor's rail\n * (`efficient-shop` → `storefront-editor.css`, the `.sf-rail` / `.sf-rail-btn`\n * rules), which is the visual reference. The admin portal's hand-rolled rail had\n * drifted (button 36 vs 34, icon 20 vs 18, radius 8 vs 9, a Tailwind accent\n * instead of a CSS var); these tokens end that drift.\n *\n * Exposed BOTH ways, per the same value:\n * - `railTokens` — this JS object, for anything that needs the numbers/colours\n * in code (inline styles, a theme bridge, a Storybook control);\n * - `rail.css` — the stylesheet, which declares the identical values as CSS\n * custom properties on `.es-rail` (names listed in `railCssVars`).\n *\n * Numeric fields are pixel magnitudes (unitless) so they compose in code; the\n * CSS applies the `px`.\n */\nexport const railTokens = {\n /** Rail column width. `--sf-rail-w: 46px`. */\n railWidth: 46,\n /** Vertical padding inside the rail (top === bottom). */\n railPaddingY: 8,\n /** Gap between buttons. */\n railGap: 4,\n /** Rail card corner radius. `--sf-panel-radius: 12px`. */\n railRadius: 12,\n /** Button hit-area (square). */\n buttonSize: 34,\n /** Button corner radius. */\n buttonRadius: 9,\n /** Icon glyph size. */\n iconSize: 18,\n /** Hover/active colour transition. */\n transition: 'background 0.12s, color 0.12s',\n /** Disabled-button opacity. */\n disabledOpacity: 0.35,\n color: {\n /** Rail card background. `--sf-panel`. */\n background: '#ffffff',\n /** Rail card shadow. `--sf-panel-shadow`. */\n shadow: '0 1px 2px rgba(0, 0, 0, 0.05), 0 10px 30px rgba(0, 0, 0, 0.06)',\n /** Idle icon colour. `--sf-muted` (gray-500). */\n idle: '#6b7280',\n /** Hover background. `--sf-hover` (gray-100). */\n hoverBg: '#f3f4f6',\n /** Hover icon colour. `--sf-text` (gray-900). */\n hoverFg: '#111827',\n /** Active icon colour. `--sf-accent` (blue-600). */\n accent: '#2563eb',\n /** Active background. `--sf-accent-tint` (blue-50). */\n accentTint: '#eff6ff',\n },\n} as const;\n\nexport type RailTokens = typeof railTokens;\n\n/**\n * The CSS custom-property name behind each token. `rail.css` sets these on\n * `.es-rail`; override any of them on (or above) the rail element to re-theme it\n * — e.g. `style={{ ['--es-rail-accent']: brand }}` — without shipping new CSS.\n */\nexport const railCssVars = {\n railWidth: '--es-rail-w',\n railPaddingY: '--es-rail-pad-y',\n railGap: '--es-rail-gap',\n railRadius: '--es-rail-radius',\n buttonSize: '--es-rail-btn-size',\n buttonRadius: '--es-rail-btn-radius',\n iconSize: '--es-rail-icon-size',\n background: '--es-rail-bg',\n shadow: '--es-rail-shadow',\n idle: '--es-rail-fg',\n hoverBg: '--es-rail-hover-bg',\n hoverFg: '--es-rail-hover-fg',\n accent: '--es-rail-accent',\n accentTint: '--es-rail-accent-tint',\n} as const;\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { EditorRail, EditorRailButton, EditorRailButtonProps, EditorRailItem, EditorRailProps, RailTokens, railCssVars, railTokens } from './rail/index.js';
|
|
1
|
+
export { EditorRail, EditorRailButton, EditorRailButtonProps, EditorRailItem, EditorRailOrientation, EditorRailProps, RailTokens, railCssVars, railTokens } from './rail/index.js';
|
|
2
2
|
export { AddIcon, LayersIcon, MediaIcon, PageIcon as PagesIcon, IconProps as RailIconProps, SitemapIcon, StylesIcon } from './icons/index.js';
|
|
3
3
|
export { ShellTokens, puckAzureRamp, shellCssVars, shellTokens } from './shell/index.js';
|
|
4
4
|
import 'react';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { EditorRail, EditorRailButton, railCssVars, railTokens } from './chunk-3VMFPQGZ.js';
|
|
1
|
+
export { EditorRail, EditorRailButton, railCssVars, railTokens } from './chunk-HYOACICE.js';
|
|
3
2
|
export { AddIcon, LayersIcon, MediaIcon, PageIcon as PagesIcon, SitemapIcon, StylesIcon } from './chunk-M7B5VTWH.js';
|
|
3
|
+
export { puckAzureRamp, shellCssVars, shellTokens } from './chunk-EZKBKK3E.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/dist/rail/index.d.ts
CHANGED
|
@@ -33,6 +33,23 @@ interface EditorRailItem {
|
|
|
33
33
|
/** Click handler. Skipped while `disabled`. */
|
|
34
34
|
onSelect?: () => void;
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Which way the rail runs.
|
|
38
|
+
*
|
|
39
|
+
* `'column'` — the original, and the default: a slim fixed-width strip down the
|
|
40
|
+
* side of the editor, wearing its own card (a background, a 12px radius and a
|
|
41
|
+
* drop shadow).
|
|
42
|
+
*
|
|
43
|
+
* `'row'` — the same buttons laid left to right, with NO fixed width and NO
|
|
44
|
+
* card, so the rail can sit in the middle of a top bar that already has its own
|
|
45
|
+
* surface. It exists because the column costs a 1280px laptop 56px of preview
|
|
46
|
+
* (46px of rail plus the 10px gap) that the top bar has going spare.
|
|
47
|
+
*
|
|
48
|
+
* Only the CONTAINER changes. Button size, icon size, the gap, and the hover
|
|
49
|
+
* and active look are the same in both directions — the row re-points three
|
|
50
|
+
* existing `--es-rail-*` custom properties and touches nothing else.
|
|
51
|
+
*/
|
|
52
|
+
type EditorRailOrientation = 'column' | 'row';
|
|
36
53
|
interface EditorRailProps {
|
|
37
54
|
/** The buttons, top to bottom, in render order (place the "+" where you want it). */
|
|
38
55
|
items: EditorRailItem[];
|
|
@@ -40,6 +57,12 @@ interface EditorRailProps {
|
|
|
40
57
|
ariaLabel?: string;
|
|
41
58
|
/** Extra class(es) merged onto the rail container. */
|
|
42
59
|
className?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Which way the buttons run. Defaults to `'column'`, which renders exactly
|
|
62
|
+
* what every editor draws today — adding this prop changed no existing
|
|
63
|
+
* output. Pass `'row'` to lay the rail into a top bar.
|
|
64
|
+
*/
|
|
65
|
+
orientation?: EditorRailOrientation;
|
|
43
66
|
}
|
|
44
67
|
interface EditorRailButtonProps {
|
|
45
68
|
label: string;
|
|
@@ -51,11 +74,12 @@ interface EditorRailButtonProps {
|
|
|
51
74
|
}
|
|
52
75
|
|
|
53
76
|
/**
|
|
54
|
-
* The shared
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
77
|
+
* The shared icon-rail — one slim strip of icon buttons that every EFFICIENT
|
|
78
|
+
* editor uses to switch panels (Pages / Layers / Styles / Media / Sitemap) and
|
|
79
|
+
* to quick-add ("+"). By default it is the vertical strip down the left; pass
|
|
80
|
+
* `orientation="row"` and the same buttons lay into a top bar instead. It is a
|
|
81
|
+
* **pure presentational switcher**: give it `items[]`, it draws them; which one
|
|
82
|
+
* is `active` and what each does is the host's business.
|
|
59
83
|
*
|
|
60
84
|
* No `'use client'` here on purpose — the rail has no hooks or state, so it is a
|
|
61
85
|
* plain module a Next-16 server component can import and even statically render.
|
|
@@ -64,11 +88,21 @@ interface EditorRailButtonProps {
|
|
|
64
88
|
* components), so baking a directive into this leaf would only narrow where it
|
|
65
89
|
* can be imported.
|
|
66
90
|
*
|
|
67
|
-
* A
|
|
68
|
-
*
|
|
91
|
+
* A `toolbar` (not a `tablist`), because the rail mixes view *toggles* with
|
|
92
|
+
* plain *actions* like the quick-add — a toolbar of buttons models that
|
|
69
93
|
* honestly, where a tablist would force every button to pretend to be a tab.
|
|
94
|
+
* That is true in both directions, so `orientation` moves `aria-orientation`
|
|
95
|
+
* and leaves the role alone: what the rail IS did not change, only which way it
|
|
96
|
+
* runs — and a toolbar's arrow keys follow its orientation, so a row that kept
|
|
97
|
+
* saying `vertical` would describe the wrong keys.
|
|
98
|
+
*
|
|
99
|
+
* `orientation` defaults to `'column'`, and that path is byte-identical to what
|
|
100
|
+
* this component rendered before the prop existed: same class list, same
|
|
101
|
+
* attributes, same order. `'row'` adds ONE modifier class beside `es-rail` —
|
|
102
|
+
* never instead of it, since every button rule and token in rail.css hangs off
|
|
103
|
+
* the base class — and rail.css does the rest.
|
|
70
104
|
*/
|
|
71
|
-
declare function EditorRail({ items, ariaLabel, className }: EditorRailProps): react.JSX.Element;
|
|
105
|
+
declare function EditorRail({ items, ariaLabel, className, orientation, }: EditorRailProps): react.JSX.Element;
|
|
72
106
|
|
|
73
107
|
/**
|
|
74
108
|
* A single rail button: an icon in a 34×34 square that hovers, highlights when
|
|
@@ -157,4 +191,4 @@ declare const railCssVars: {
|
|
|
157
191
|
readonly accentTint: "--es-rail-accent-tint";
|
|
158
192
|
};
|
|
159
193
|
|
|
160
|
-
export { EditorRail, EditorRailButton, type EditorRailButtonProps, type EditorRailItem, type EditorRailProps, type RailTokens, railCssVars, railTokens };
|
|
194
|
+
export { EditorRail, EditorRailButton, type EditorRailButtonProps, type EditorRailItem, type EditorRailOrientation, type EditorRailProps, type RailTokens, railCssVars, railTokens };
|
package/dist/rail/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { EditorRail, EditorRailButton, railCssVars, railTokens } from '../chunk-
|
|
1
|
+
export { EditorRail, EditorRailButton, railCssVars, railTokens } from '../chunk-HYOACICE.js';
|
|
2
2
|
export { AddIcon, LayersIcon, MediaIcon, PageIcon as PagesIcon, SitemapIcon, StylesIcon } from '../chunk-M7B5VTWH.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/rail/rail.css
CHANGED
|
@@ -40,6 +40,45 @@
|
|
|
40
40
|
box-shadow: var(--es-rail-shadow);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/*
|
|
44
|
+
* The ROW variant (card 66160) — the same rail laid into a top bar.
|
|
45
|
+
*
|
|
46
|
+
* The column costs a 1280px laptop 56px of website preview (a 46px rail plus
|
|
47
|
+
* the 10px panel gap) that the top bar has going spare, so the icons move up
|
|
48
|
+
* there. `.es-rail` above is UNTOUCHED: this rule only overrides, so a consumer
|
|
49
|
+
* who never passes `orientation` gets exactly the stylesheet they had.
|
|
50
|
+
*
|
|
51
|
+
* THE CARD LOOK GOES, THROUGH THE TOKENS THAT ALREADY EXIST. The bar has its
|
|
52
|
+
* own surface and shadow; a second white card floating inside it is the bug.
|
|
53
|
+
* These re-point the THREE custom properties the base rule already reads rather
|
|
54
|
+
* than re-stating `background` / `box-shadow` / `border-radius` here — so the
|
|
55
|
+
* card look stays declared in exactly one place, and a host re-theming the rail
|
|
56
|
+
* still only has the `--es-rail-*` names to learn.
|
|
57
|
+
*
|
|
58
|
+
* WHAT DELIBERATELY DOES NOT CHANGE: the button size, the button radius, the
|
|
59
|
+
* icon size, the gap and every colour. The icons must not resize when they move
|
|
60
|
+
* into the bar, so no `--es-rail-btn-*`, `--es-rail-icon-size` or colour token
|
|
61
|
+
* appears below, and there is no `.es-rail-row .es-rail-btn` rule anywhere.
|
|
62
|
+
* `align-items: center` is inherited from the base rule and does the right
|
|
63
|
+
* thing here too — in a row it centres the buttons vertically.
|
|
64
|
+
*/
|
|
65
|
+
.es-rail.es-rail-row {
|
|
66
|
+
--es-rail-bg: transparent;
|
|
67
|
+
--es-rail-shadow: none;
|
|
68
|
+
--es-rail-radius: 0;
|
|
69
|
+
|
|
70
|
+
flex-direction: row;
|
|
71
|
+
/* No fixed width: the row is as wide as its buttons. `flex: none` from the
|
|
72
|
+
base rule keeps flex-basis on `auto`, so this sizes to content. */
|
|
73
|
+
width: auto;
|
|
74
|
+
/* The column pads `--es-rail-pad-y 0`: the one step goes on the MAIN axis —
|
|
75
|
+
the run of buttons — and the cross axis is handled by the fixed width.
|
|
76
|
+
Rotate the axes and the same step goes on the ENDS of the row. The cross
|
|
77
|
+
axis is 0 on purpose, so the row is exactly one button tall (34px) and the
|
|
78
|
+
52px bar centres it, instead of the rail imposing a height on the bar. */
|
|
79
|
+
padding: 0 var(--es-rail-pad-y);
|
|
80
|
+
}
|
|
81
|
+
|
|
43
82
|
.es-rail-btn {
|
|
44
83
|
width: var(--es-rail-btn-size);
|
|
45
84
|
height: var(--es-rail-btn-size);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "editor-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Shared editor-chrome primitives for the EFFICIENT editors: EditorRail (a Next-16-safe left icon-rail leaf), the shell token layer, and GoldTextInput — type in place and watch the markup formatting appear as you type.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Lewis Liu",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rail/EditorRailButton.tsx","../src/rail/EditorRail.tsx","../src/rail/tokens.ts"],"names":["jsx"],"mappings":"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","file":"chunk-3VMFPQGZ.js","sourcesContent":["import type { EditorRailButtonProps } from './types';\n\n/**\n * A single rail button: an icon in a 34×34 square that hovers, highlights when\n * active, and dims when disabled. Look only — the caller owns the click.\n *\n * `aria-pressed` is emitted **only** when `active` is a real boolean, so a view\n * toggle announces its pressed state while an action button (the quick-add \"+\",\n * whose item omits `active`) stays a plain button rather than a stuck toggle.\n */\nexport function EditorRailButton({\n label,\n icon,\n active,\n disabled,\n onSelect,\n className,\n}: EditorRailButtonProps) {\n const classes = ['es-rail-btn', active ? 'is-active' : '', className ?? '']\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n type=\"button\"\n className={classes}\n title={label}\n aria-label={label}\n aria-pressed={typeof active === 'boolean' ? active : undefined}\n disabled={disabled}\n onClick={disabled ? undefined : onSelect}\n >\n {icon}\n </button>\n );\n}\n","import { EditorRailButton } from './EditorRailButton';\nimport type { EditorRailProps } from './types';\n\n/**\n * The shared left icon-rail — one slim vertical strip of icon buttons that every\n * EFFICIENT editor uses to switch panels (Pages / Layers / Styles / Media /\n * Sitemap) and to quick-add (\"+\"). It is a **pure presentational switcher**: give\n * it `items[]`, it draws them; which one is `active` and what each does is the\n * host's business.\n *\n * No `'use client'` here on purpose — the rail has no hooks or state, so it is a\n * plain module a Next-16 server component can import and even statically render.\n * It's interactive only through the `onSelect` props the host passes, and the\n * host owns its client boundary (both editors' chrome are already client\n * components), so baking a directive into this leaf would only narrow where it\n * can be imported.\n *\n * A vertical `toolbar` (not a `tablist`), because the rail mixes view *toggles*\n * with plain *actions* like the quick-add — a toolbar of buttons models that\n * honestly, where a tablist would force every button to pretend to be a tab.\n */\nexport function EditorRail({ items, ariaLabel = 'Editor', className }: EditorRailProps) {\n return (\n <div\n className={['es-rail', className ?? ''].filter(Boolean).join(' ')}\n role=\"toolbar\"\n aria-orientation=\"vertical\"\n aria-label={ariaLabel}\n >\n {items.map((item) => (\n <EditorRailButton\n key={item.id}\n label={item.label}\n icon={item.icon}\n active={item.active}\n disabled={item.disabled}\n onSelect={item.onSelect}\n />\n ))}\n </div>\n );\n}\n","/**\n * Rail design tokens — the ONE source both apps' rails converge on.\n *\n * Every value below is taken verbatim from the storefront editor's rail\n * (`efficient-shop` → `storefront-editor.css`, the `.sf-rail` / `.sf-rail-btn`\n * rules), which is the visual reference. The admin portal's hand-rolled rail had\n * drifted (button 36 vs 34, icon 20 vs 18, radius 8 vs 9, a Tailwind accent\n * instead of a CSS var); these tokens end that drift.\n *\n * Exposed BOTH ways, per the same value:\n * - `railTokens` — this JS object, for anything that needs the numbers/colours\n * in code (inline styles, a theme bridge, a Storybook control);\n * - `rail.css` — the stylesheet, which declares the identical values as CSS\n * custom properties on `.es-rail` (names listed in `railCssVars`).\n *\n * Numeric fields are pixel magnitudes (unitless) so they compose in code; the\n * CSS applies the `px`.\n */\nexport const railTokens = {\n /** Rail column width. `--sf-rail-w: 46px`. */\n railWidth: 46,\n /** Vertical padding inside the rail (top === bottom). */\n railPaddingY: 8,\n /** Gap between buttons. */\n railGap: 4,\n /** Rail card corner radius. `--sf-panel-radius: 12px`. */\n railRadius: 12,\n /** Button hit-area (square). */\n buttonSize: 34,\n /** Button corner radius. */\n buttonRadius: 9,\n /** Icon glyph size. */\n iconSize: 18,\n /** Hover/active colour transition. */\n transition: 'background 0.12s, color 0.12s',\n /** Disabled-button opacity. */\n disabledOpacity: 0.35,\n color: {\n /** Rail card background. `--sf-panel`. */\n background: '#ffffff',\n /** Rail card shadow. `--sf-panel-shadow`. */\n shadow: '0 1px 2px rgba(0, 0, 0, 0.05), 0 10px 30px rgba(0, 0, 0, 0.06)',\n /** Idle icon colour. `--sf-muted` (gray-500). */\n idle: '#6b7280',\n /** Hover background. `--sf-hover` (gray-100). */\n hoverBg: '#f3f4f6',\n /** Hover icon colour. `--sf-text` (gray-900). */\n hoverFg: '#111827',\n /** Active icon colour. `--sf-accent` (blue-600). */\n accent: '#2563eb',\n /** Active background. `--sf-accent-tint` (blue-50). */\n accentTint: '#eff6ff',\n },\n} as const;\n\nexport type RailTokens = typeof railTokens;\n\n/**\n * The CSS custom-property name behind each token. `rail.css` sets these on\n * `.es-rail`; override any of them on (or above) the rail element to re-theme it\n * — e.g. `style={{ ['--es-rail-accent']: brand }}` — without shipping new CSS.\n */\nexport const railCssVars = {\n railWidth: '--es-rail-w',\n railPaddingY: '--es-rail-pad-y',\n railGap: '--es-rail-gap',\n railRadius: '--es-rail-radius',\n buttonSize: '--es-rail-btn-size',\n buttonRadius: '--es-rail-btn-radius',\n iconSize: '--es-rail-icon-size',\n background: '--es-rail-bg',\n shadow: '--es-rail-shadow',\n idle: '--es-rail-fg',\n hoverBg: '--es-rail-hover-bg',\n hoverFg: '--es-rail-hover-fg',\n accent: '--es-rail-accent',\n accentTint: '--es-rail-accent-tint',\n} as const;\n"]}
|