@crisp-ui-kit/crisp 0.9.0 → 0.9.1
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/dist/appshell.css +2 -0
- package/dist/breadcrumb.css +2 -0
- package/dist/cjs/components/breadcrumb/breadcrumb.js +1 -1
- package/dist/cjs/components/breadcrumb/breadcrumb.recipe.js +3 -1
- package/dist/cjs/core/index.js +15 -0
- package/dist/cjs/core/rtl.js +17 -0
- package/dist/cjs/product/appshell/appshell.js +1 -1
- package/dist/cjs/product/appshell/appshell.recipe.js +2 -0
- package/dist/cjs/product/recordstable/recordstable.js +2 -2
- package/dist/cjs/product/recordstable/recordstable.recipe.js +2 -0
- package/dist/cjs/product/settingsshell/settingsshell.js +1 -1
- package/dist/cjs/product/settingsshell/settingsshell.recipe.js +3 -1
- package/dist/esm/components/breadcrumb/breadcrumb.js +1 -1
- package/dist/esm/components/breadcrumb/breadcrumb.recipe.js +4 -2
- package/dist/esm/core/index.js +1 -0
- package/dist/esm/core/rtl.js +14 -0
- package/dist/esm/product/appshell/appshell.js +1 -1
- package/dist/esm/product/appshell/appshell.recipe.js +3 -1
- package/dist/esm/product/recordstable/recordstable.js +2 -2
- package/dist/esm/product/recordstable/recordstable.recipe.js +3 -1
- package/dist/esm/product/settingsshell/settingsshell.js +1 -1
- package/dist/esm/product/settingsshell/settingsshell.recipe.js +4 -2
- package/dist/recordstable.css +2 -0
- package/dist/settingsshell.css +2 -0
- package/dist/styles.css +8 -0
- package/dist/types/core/index.d.ts +1 -0
- package/dist/types/core/rtl.d.ts +14 -0
- package/package.json +1 -1
package/dist/appshell.css
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
& .appshell-expand { position: absolute; top: var(--space-2); inset-inline-start: var(--space-2); z-index: 6; display: inline-flex; align-items: center; justify-content: center; width: var(--size-row); height: var(--size-row); padding: 0; border: none; border-radius: var(--radius-md); box-shadow: inset 0 0 0 1px var(--border-subtle); background: var(--bg-surface); color: var(--fg-muted); font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
11
11
|
& .appshell-expand:hover { background: var(--bg-raised); color: var(--fg-primary); }
|
|
12
12
|
|
|
13
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
14
|
+
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
@media (prefers-reduced-motion: reduce) {
|
package/dist/breadcrumb.css
CHANGED
|
@@ -6,4 +6,6 @@
|
|
|
6
6
|
& button.breadcrumb-item { border: none; background: none; font: inherit; cursor: pointer; }
|
|
7
7
|
& .breadcrumb-item[aria-current] { color: var(--fg-primary); font-weight: var(--weight-medium); }
|
|
8
8
|
& .breadcrumb-sep { flex-shrink: 0; color: color-mix(in srgb, var(--fg-primary) 28%, transparent); }
|
|
9
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
10
|
+
|
|
9
11
|
}
|
|
@@ -43,7 +43,7 @@ const breadcrumb_recipe_1 = require("./breadcrumb.recipe");
|
|
|
43
43
|
* marked `aria-current="page"`; earlier items render as links or buttons.
|
|
44
44
|
*/
|
|
45
45
|
function Breadcrumb({ items, separator, "aria-label": ariaLabel = "Breadcrumb", className, ...rest }) {
|
|
46
|
-
const sep = separator ?? ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { size: 14, strokeWidth: 1.75, "aria-hidden": "true" }));
|
|
46
|
+
const sep = separator ?? ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { "data-rtl-flip": "", size: 14, strokeWidth: 1.75, "aria-hidden": "true" }));
|
|
47
47
|
return ((0, jsx_runtime_1.jsx)("nav", { "aria-label": ariaLabel, className: (0, breadcrumb_recipe_1.breadcrumbRecipe)({ className }), ...rest, children: items.map((item, i) => {
|
|
48
48
|
const last = i === items.length - 1;
|
|
49
49
|
const content = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [item.icon, item.label] }));
|
|
@@ -12,7 +12,9 @@ const config = (0, core_1.defineRecipe)({
|
|
|
12
12
|
& a.breadcrumb-item:hover, & button.breadcrumb-item:hover { color: ${tokens_1.contract.fgPrimary}; background: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 5%, transparent); }
|
|
13
13
|
& button.breadcrumb-item { border: none; background: none; font: inherit; cursor: pointer; }
|
|
14
14
|
& .breadcrumb-item[aria-current] { color: ${tokens_1.contract.fgPrimary}; font-weight: ${tokens_1.contract.weight.medium}; }
|
|
15
|
-
& .breadcrumb-sep { flex-shrink: 0; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 28%, transparent); }
|
|
15
|
+
& .breadcrumb-sep { flex-shrink: 0; color: color-mix(in srgb, ${tokens_1.contract.fgPrimary} 28%, transparent); }
|
|
16
|
+
${core_1.rtlFlipCss}
|
|
17
|
+
`,
|
|
16
18
|
variants: {},
|
|
17
19
|
defaultVariants: {},
|
|
18
20
|
compoundVariants: [],
|
package/dist/cjs/core/index.js
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.resolveRecipe = exports.Primitive = exports.defineRecipe = exports.cx = void 0;
|
|
4
18
|
var cx_1 = require("./cx");
|
|
@@ -9,3 +23,4 @@ var primitive_1 = require("./primitive");
|
|
|
9
23
|
Object.defineProperty(exports, "Primitive", { enumerable: true, get: function () { return primitive_1.Primitive; } });
|
|
10
24
|
var resolve_1 = require("./resolve");
|
|
11
25
|
Object.defineProperty(exports, "resolveRecipe", { enumerable: true, get: function () { return resolve_1.resolveRecipe; } });
|
|
26
|
+
__exportStar(require("./rtl"), exports);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rtlFlipCss = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Mirroring for direction-bearing icons.
|
|
6
|
+
*
|
|
7
|
+
* A chevron or arrow that means "back", "next", "toward the start" or "open"
|
|
8
|
+
* points the wrong way under RTL, and unlike spacing or alignment it cannot be
|
|
9
|
+
* fixed with a logical property: these are `lucide-react` nodes, static SVG
|
|
10
|
+
* paths with no direction of their own.
|
|
11
|
+
*
|
|
12
|
+
* Mark the icons that carry a direction with `data-rtl-flip` and include this
|
|
13
|
+
* snippet in the recipe. Icons whose meaning is NOT directional — a downward
|
|
14
|
+
* disclosure chevron, a search glass, a check — must be left unmarked: flipping
|
|
15
|
+
* them is a regression, not a fix.
|
|
16
|
+
*/
|
|
17
|
+
exports.rtlFlipCss = `[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }`;
|
|
@@ -99,6 +99,6 @@ function AppShell({ sidebar, children, width: widthProp, defaultWidth = 275, onW
|
|
|
99
99
|
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, appshell_recipe_1.appshellRecipe)({ className }), ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { className: "appshell-side", "data-collapsed": collapsed ? "" : undefined, style: {
|
|
100
100
|
width: collapsed ? 0 : width,
|
|
101
101
|
transition: dragging ? "none" : "width .14s ease",
|
|
102
|
-
}, children: [(0, jsx_runtime_1.jsx)("div", { className: "appshell-side-inner", style: { width }, children: sidebar(toggleCollapse) }), !collapsed && ((0, jsx_runtime_1.jsx)("div", { className: "appshell-resize", "data-dragging": dragging ? "" : undefined, "aria-hidden": "true", onPointerDown: startResize }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "appshell-main", children: [collapsed && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "appshell-expand", "aria-label": expandLabel, onClick: () => setCollapsed(false), children: (0, jsx_runtime_1.jsx)(lucide_react_1.PanelLeft, { size: 15, strokeWidth: 1.75 }) })), children] })] }));
|
|
102
|
+
}, children: [(0, jsx_runtime_1.jsx)("div", { className: "appshell-side-inner", style: { width }, children: sidebar(toggleCollapse) }), !collapsed && ((0, jsx_runtime_1.jsx)("div", { className: "appshell-resize", "data-dragging": dragging ? "" : undefined, "aria-hidden": "true", onPointerDown: startResize }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "appshell-main", children: [collapsed && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "appshell-expand", "aria-label": expandLabel, onClick: () => setCollapsed(false), children: (0, jsx_runtime_1.jsx)(lucide_react_1.PanelLeft, { "data-rtl-flip": "", size: 15, strokeWidth: 1.75 }) })), children] })] }));
|
|
103
103
|
}
|
|
104
104
|
AppShell.displayName = "AppShell";
|
|
@@ -18,6 +18,8 @@ const config = (0, core_1.defineRecipe)({
|
|
|
18
18
|
& .appshell-main { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
|
|
19
19
|
& .appshell-expand { position: absolute; top: ${tokens_1.contract.space["2"]}; inset-inline-start: ${tokens_1.contract.space["2"]}; z-index: 6; display: inline-flex; align-items: center; justify-content: center; width: ${tokens_1.contract.size.row}; height: ${tokens_1.contract.size.row}; padding: 0; border: none; border-radius: ${tokens_1.contract.radius.md}; box-shadow: inset 0 0 0 1px ${tokens_1.contract.borderSubtle}; background: ${tokens_1.contract.bgSurface}; color: ${tokens_1.contract.fgMuted}; font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
20
20
|
& .appshell-expand:hover { background: ${tokens_1.contract.bgRaised}; color: ${tokens_1.contract.fgPrimary}; }
|
|
21
|
+
|
|
22
|
+
${core_1.rtlFlipCss}
|
|
21
23
|
`,
|
|
22
24
|
variants: {},
|
|
23
25
|
defaultVariants: {},
|
|
@@ -984,7 +984,7 @@ function RecordsTable({ labels, columns: columnsProp = exports.defaultColumns, r
|
|
|
984
984
|
}
|
|
985
985
|
: undefined, onDragEnd: () => setDragCol(null), onClick: (e) => openColumnMenu(col.key, e.currentTarget), children: [Icon ? (0, jsx_runtime_1.jsx)(Icon, { size: 14, strokeWidth: 1.75 }) : null, (0, jsx_runtime_1.jsx)("span", { className: "recordstable-th-label", children: col.label }), (0, jsx_runtime_1.jsx)("span", { className: "recordstable-sort", children: (0, jsx_runtime_1.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)("path", { d: "m4 6 4 4 4-4" }) }) })] })), openMenu === `col:${col.key}` &&
|
|
986
986
|
rootRef.current &&
|
|
987
|
-
(0, react_dom_1.createPortal)((0, jsx_runtime_1.jsxs)("div", { ref: menuRef, className: "recordstable-menu recordstable-menu--fixed recordstable-menu--hdr", role: "menu", "aria-label": `${col.label} column`, style: menuPos ?? undefined, onKeyDown: onMenuKeyDown, children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => sortBy(col.key, "asc"), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowUp, { size: 15, strokeWidth: 1.75 }), t.sortAscending] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => sortBy(col.key, "desc"), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowDown, { size: 15, strokeWidth: 1.75 }), t.sortDescending] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, disabled: i <= 1, onClick: () => moveColumn(col.key, -1), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowLeft, { size: 15, strokeWidth: 1.75 }), t.moveLeft] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, disabled: i === 0 || i >= cols.length - 1, onClick: () => moveColumn(col.key, 1), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowRight, { size: 15, strokeWidth: 1.75 }), t.moveRight] }), (0, jsx_runtime_1.jsx)("div", { className: "recordstable-menu-sep" }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => {
|
|
987
|
+
(0, react_dom_1.createPortal)((0, jsx_runtime_1.jsxs)("div", { ref: menuRef, className: "recordstable-menu recordstable-menu--fixed recordstable-menu--hdr", role: "menu", "aria-label": `${col.label} column`, style: menuPos ?? undefined, onKeyDown: onMenuKeyDown, children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => sortBy(col.key, "asc"), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowUp, { size: 15, strokeWidth: 1.75 }), t.sortAscending] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => sortBy(col.key, "desc"), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowDown, { size: 15, strokeWidth: 1.75 }), t.sortDescending] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, disabled: i <= 1, onClick: () => moveColumn(col.key, -1), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowLeft, { "data-rtl-flip": "", size: 15, strokeWidth: 1.75 }), t.moveLeft] }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, disabled: i === 0 || i >= cols.length - 1, onClick: () => moveColumn(col.key, 1), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ArrowRight, { "data-rtl-flip": "", size: 15, strokeWidth: 1.75 }), t.moveRight] }), (0, jsx_runtime_1.jsx)("div", { className: "recordstable-menu-sep" }), (0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => {
|
|
988
988
|
setRenamingCol(col.key);
|
|
989
989
|
setOpenMenu(null);
|
|
990
990
|
}, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Pencil, { size: 15, strokeWidth: 1.75 }), t.editColumnLabel] }), cols.length > 1 && ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => hideColumn(col.key), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.EyeOff, { size: 15, strokeWidth: 1.75 }), t.hideFromView] }))] }), rootRef.current), (0, jsx_runtime_1.jsx)("span", { className: "recordstable-resize", "aria-hidden": "true", onPointerDown: (e) => {
|
|
@@ -1025,7 +1025,7 @@ function RecordsTable({ labels, columns: columnsProp = exports.defaultColumns, r
|
|
|
1025
1025
|
: undefined, avatarTone: avatarTone })), i === 0 && onOpenRecord && !isEditing && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "recordstable-open", "aria-label": `Open ${cellText(col, row)}`, onClick: (e) => {
|
|
1026
1026
|
e.stopPropagation();
|
|
1027
1027
|
onOpenRecord(row);
|
|
1028
|
-
}, children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowUpRight, { size: 15, strokeWidth: 1.75 }) }))] }, col.key));
|
|
1028
|
+
}, children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowUpRight, { "data-rtl-flip": "", size: 15, strokeWidth: 1.75 }) }))] }, col.key));
|
|
1029
1029
|
}), (0, jsx_runtime_1.jsx)("td", { className: "recordstable-td recordstable-addcol" })] }, row.id))) }), (0, jsx_runtime_1.jsx)("tfoot", { children: (0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsx)("td", { className: "recordstable-sum recordstable-col-check" }), cols.map((col, i) => {
|
|
1030
1030
|
const a = agg[col.key] ?? "none";
|
|
1031
1031
|
const res = summarize(col, a, visibleRows);
|
|
@@ -145,6 +145,8 @@ ${(0, tabletoolbar_chrome_1.toolbarChromeBody)("recordstable")}
|
|
|
145
145
|
& .recordstable-bulk-sep { width: 1px; height: 20px; margin: 0 ${tokens_1.contract.space["0.5"]}; background: ${tokens_1.contract.borderSubtle}; }
|
|
146
146
|
& .recordstable-bulk-close { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: none; border-radius: ${tokens_1.contract.radius.md}; background: transparent; color: ${tokens_1.contract.fgMuted}; cursor: pointer; }
|
|
147
147
|
& .recordstable-bulk-close:hover { background: ${tokens_1.contract.bgRaised}; color: ${tokens_1.contract.fgPrimary}; }
|
|
148
|
+
|
|
149
|
+
${core_1.rtlFlipCss}
|
|
148
150
|
`,
|
|
149
151
|
variants: {},
|
|
150
152
|
defaultVariants: {},
|
|
@@ -54,6 +54,6 @@ function SettingsShell({ title = "Settings", onBack, groups, activeItem, onSelec
|
|
|
54
54
|
}))
|
|
55
55
|
.filter((g) => g.items.length > 0)
|
|
56
56
|
: groups;
|
|
57
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, settingsshell_recipe_1.settingsshellRecipe)({ className }), ...rest, children: [(0, jsx_runtime_1.jsxs)("nav", { className: "settingsshell-nav", "aria-label": navLabel, children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: "settingsshell-back", onClick: onBack, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { size: 16, strokeWidth: 2 }), title] }), searchable && ((0, jsx_runtime_1.jsxs)("div", { className: "settingsshell-search", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { size: 15, strokeWidth: 1.75 }), (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: searchPlaceholder, "aria-label": searchPlaceholder, value: query, onChange: (e) => setQuery(e.target.value) })] })), (0, jsx_runtime_1.jsx)("div", { className: "settingsshell-groups", children: filtered.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "settingsshell-empty", children: emptyLabel })) : (filtered.map((g, gi) => ((0, jsx_runtime_1.jsxs)("div", { className: "settingsshell-group", children: [g.label != null && ((0, jsx_runtime_1.jsx)("div", { className: "settingsshell-group-label", children: g.label })), g.items.map((it) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "settingsshell-item", "aria-current": it.id === activeItem ? "page" : undefined, "data-active": it.id === activeItem ? "" : undefined, onClick: () => onSelect(it.id), children: [it.icon, (0, jsx_runtime_1.jsx)("span", { className: "settingsshell-item-label", children: it.label })] }, it.id)))] }, gi)))) })] }), (0, jsx_runtime_1.jsx)("div", { className: "settingsshell-content", children: children })] }));
|
|
57
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, settingsshell_recipe_1.settingsshellRecipe)({ className }), ...rest, children: [(0, jsx_runtime_1.jsxs)("nav", { className: "settingsshell-nav", "aria-label": navLabel, children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: "settingsshell-back", onClick: onBack, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { "data-rtl-flip": "", size: 16, strokeWidth: 2 }), title] }), searchable && ((0, jsx_runtime_1.jsxs)("div", { className: "settingsshell-search", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { size: 15, strokeWidth: 1.75 }), (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: searchPlaceholder, "aria-label": searchPlaceholder, value: query, onChange: (e) => setQuery(e.target.value) })] })), (0, jsx_runtime_1.jsx)("div", { className: "settingsshell-groups", children: filtered.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "settingsshell-empty", children: emptyLabel })) : (filtered.map((g, gi) => ((0, jsx_runtime_1.jsxs)("div", { className: "settingsshell-group", children: [g.label != null && ((0, jsx_runtime_1.jsx)("div", { className: "settingsshell-group-label", children: g.label })), g.items.map((it) => ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "settingsshell-item", "aria-current": it.id === activeItem ? "page" : undefined, "data-active": it.id === activeItem ? "" : undefined, onClick: () => onSelect(it.id), children: [it.icon, (0, jsx_runtime_1.jsx)("span", { className: "settingsshell-item-label", children: it.label })] }, it.id)))] }, gi)))) })] }), (0, jsx_runtime_1.jsx)("div", { className: "settingsshell-content", children: children })] }));
|
|
58
58
|
}
|
|
59
59
|
SettingsShell.displayName = "SettingsShell";
|
|
@@ -37,7 +37,9 @@ const config = (0, core_1.defineRecipe)({
|
|
|
37
37
|
& .settingsshell-item[data-active] svg { color: ${tokens_1.contract.fgPrimary}; }
|
|
38
38
|
& .settingsshell-empty { padding: ${tokens_1.contract.space["3"]} ${tokens_1.contract.space["2"]}; font-size: ${tokens_1.contract.text.md}; color: ${tokens_1.contract.fgMuted}; }
|
|
39
39
|
|
|
40
|
-
& .settingsshell-content { flex: 1; min-width: 0; min-height: 0; overflow-y: auto; padding: ${tokens_1.contract.space["6"]} ${tokens_1.contract.space["8"]}; }
|
|
40
|
+
& .settingsshell-content { flex: 1; min-width: 0; min-height: 0; overflow-y: auto; padding: ${tokens_1.contract.space["6"]} ${tokens_1.contract.space["8"]}; }
|
|
41
|
+
${core_1.rtlFlipCss}
|
|
42
|
+
`,
|
|
41
43
|
variants: {},
|
|
42
44
|
defaultVariants: {},
|
|
43
45
|
compoundVariants: [],
|
|
@@ -7,7 +7,7 @@ import { breadcrumbRecipe } from "./breadcrumb.recipe.js";
|
|
|
7
7
|
* marked `aria-current="page"`; earlier items render as links or buttons.
|
|
8
8
|
*/
|
|
9
9
|
export function Breadcrumb({ items, separator, "aria-label": ariaLabel = "Breadcrumb", className, ...rest }) {
|
|
10
|
-
const sep = separator ?? (_jsx(ChevronRight, { size: 14, strokeWidth: 1.75, "aria-hidden": "true" }));
|
|
10
|
+
const sep = separator ?? (_jsx(ChevronRight, { "data-rtl-flip": "", size: 14, strokeWidth: 1.75, "aria-hidden": "true" }));
|
|
11
11
|
return (_jsx("nav", { "aria-label": ariaLabel, className: breadcrumbRecipe({ className }), ...rest, children: items.map((item, i) => {
|
|
12
12
|
const last = i === items.length - 1;
|
|
13
13
|
const content = (_jsxs(_Fragment, { children: [item.icon, item.label] }));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineRecipe, resolveRecipe } from "../../core/index.js";
|
|
1
|
+
import { defineRecipe, resolveRecipe, rtlFlipCss } from "../../core/index.js";
|
|
2
2
|
import { contract as c } from "../../tokens/index.js";
|
|
3
3
|
// A breadcrumb trail — Attio's record-page nav ("Companies / Google").
|
|
4
4
|
const config = defineRecipe({
|
|
@@ -9,7 +9,9 @@ const config = defineRecipe({
|
|
|
9
9
|
& a.breadcrumb-item:hover, & button.breadcrumb-item:hover { color: ${c.fgPrimary}; background: color-mix(in srgb, ${c.fgPrimary} 5%, transparent); }
|
|
10
10
|
& button.breadcrumb-item { border: none; background: none; font: inherit; cursor: pointer; }
|
|
11
11
|
& .breadcrumb-item[aria-current] { color: ${c.fgPrimary}; font-weight: ${c.weight.medium}; }
|
|
12
|
-
& .breadcrumb-sep { flex-shrink: 0; color: color-mix(in srgb, ${c.fgPrimary} 28%, transparent); }
|
|
12
|
+
& .breadcrumb-sep { flex-shrink: 0; color: color-mix(in srgb, ${c.fgPrimary} 28%, transparent); }
|
|
13
|
+
${rtlFlipCss}
|
|
14
|
+
`,
|
|
13
15
|
variants: {},
|
|
14
16
|
defaultVariants: {},
|
|
15
17
|
compoundVariants: [],
|
package/dist/esm/core/index.js
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirroring for direction-bearing icons.
|
|
3
|
+
*
|
|
4
|
+
* A chevron or arrow that means "back", "next", "toward the start" or "open"
|
|
5
|
+
* points the wrong way under RTL, and unlike spacing or alignment it cannot be
|
|
6
|
+
* fixed with a logical property: these are `lucide-react` nodes, static SVG
|
|
7
|
+
* paths with no direction of their own.
|
|
8
|
+
*
|
|
9
|
+
* Mark the icons that carry a direction with `data-rtl-flip` and include this
|
|
10
|
+
* snippet in the recipe. Icons whose meaning is NOT directional — a downward
|
|
11
|
+
* disclosure chevron, a search glass, a check — must be left unmarked: flipping
|
|
12
|
+
* them is a regression, not a fix.
|
|
13
|
+
*/
|
|
14
|
+
export const rtlFlipCss = `[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }`;
|
|
@@ -63,6 +63,6 @@ export function AppShell({ sidebar, children, width: widthProp, defaultWidth = 2
|
|
|
63
63
|
return (_jsxs("div", { className: appshellRecipe({ className }), ...rest, children: [_jsxs("div", { className: "appshell-side", "data-collapsed": collapsed ? "" : undefined, style: {
|
|
64
64
|
width: collapsed ? 0 : width,
|
|
65
65
|
transition: dragging ? "none" : "width .14s ease",
|
|
66
|
-
}, children: [_jsx("div", { className: "appshell-side-inner", style: { width }, children: sidebar(toggleCollapse) }), !collapsed && (_jsx("div", { className: "appshell-resize", "data-dragging": dragging ? "" : undefined, "aria-hidden": "true", onPointerDown: startResize }))] }), _jsxs("div", { className: "appshell-main", children: [collapsed && (_jsx("button", { type: "button", className: "appshell-expand", "aria-label": expandLabel, onClick: () => setCollapsed(false), children: _jsx(PanelLeft, { size: 15, strokeWidth: 1.75 }) })), children] })] }));
|
|
66
|
+
}, children: [_jsx("div", { className: "appshell-side-inner", style: { width }, children: sidebar(toggleCollapse) }), !collapsed && (_jsx("div", { className: "appshell-resize", "data-dragging": dragging ? "" : undefined, "aria-hidden": "true", onPointerDown: startResize }))] }), _jsxs("div", { className: "appshell-main", children: [collapsed && (_jsx("button", { type: "button", className: "appshell-expand", "aria-label": expandLabel, onClick: () => setCollapsed(false), children: _jsx(PanelLeft, { "data-rtl-flip": "", size: 15, strokeWidth: 1.75 }) })), children] })] }));
|
|
67
67
|
}
|
|
68
68
|
AppShell.displayName = "AppShell";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineRecipe, resolveRecipe } from "../../core/index.js";
|
|
1
|
+
import { defineRecipe, resolveRecipe, rtlFlipCss } from "../../core/index.js";
|
|
2
2
|
import { contract as c } from "../../tokens/index.js";
|
|
3
3
|
// App-shell layout: a collapsible + resizable sidebar pane next to a main pane,
|
|
4
4
|
// mirroring how Attio's window works. The sidebar pane clips (never squishes)
|
|
@@ -15,6 +15,8 @@ const config = defineRecipe({
|
|
|
15
15
|
& .appshell-main { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
|
|
16
16
|
& .appshell-expand { position: absolute; top: ${c.space["2"]}; inset-inline-start: ${c.space["2"]}; z-index: 6; display: inline-flex; align-items: center; justify-content: center; width: ${c.size.row}; height: ${c.size.row}; padding: 0; border: none; border-radius: ${c.radius.md}; box-shadow: inset 0 0 0 1px ${c.borderSubtle}; background: ${c.bgSurface}; color: ${c.fgMuted}; font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
17
17
|
& .appshell-expand:hover { background: ${c.bgRaised}; color: ${c.fgPrimary}; }
|
|
18
|
+
|
|
19
|
+
${rtlFlipCss}
|
|
18
20
|
`,
|
|
19
21
|
variants: {},
|
|
20
22
|
defaultVariants: {},
|
|
@@ -946,7 +946,7 @@ export function RecordsTable({ labels, columns: columnsProp = defaultColumns, ro
|
|
|
946
946
|
}
|
|
947
947
|
: undefined, onDragEnd: () => setDragCol(null), onClick: (e) => openColumnMenu(col.key, e.currentTarget), children: [Icon ? _jsx(Icon, { size: 14, strokeWidth: 1.75 }) : null, _jsx("span", { className: "recordstable-th-label", children: col.label }), _jsx("span", { className: "recordstable-sort", children: _jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: _jsx("path", { d: "m4 6 4 4 4-4" }) }) })] })), openMenu === `col:${col.key}` &&
|
|
948
948
|
rootRef.current &&
|
|
949
|
-
createPortal(_jsxs("div", { ref: menuRef, className: "recordstable-menu recordstable-menu--fixed recordstable-menu--hdr", role: "menu", "aria-label": `${col.label} column`, style: menuPos ?? undefined, onKeyDown: onMenuKeyDown, children: [_jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => sortBy(col.key, "asc"), children: [_jsx(ArrowUp, { size: 15, strokeWidth: 1.75 }), t.sortAscending] }), _jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => sortBy(col.key, "desc"), children: [_jsx(ArrowDown, { size: 15, strokeWidth: 1.75 }), t.sortDescending] }), _jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, disabled: i <= 1, onClick: () => moveColumn(col.key, -1), children: [_jsx(ArrowLeft, { size: 15, strokeWidth: 1.75 }), t.moveLeft] }), _jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, disabled: i === 0 || i >= cols.length - 1, onClick: () => moveColumn(col.key, 1), children: [_jsx(ArrowRight, { size: 15, strokeWidth: 1.75 }), t.moveRight] }), _jsx("div", { className: "recordstable-menu-sep" }), _jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => {
|
|
949
|
+
createPortal(_jsxs("div", { ref: menuRef, className: "recordstable-menu recordstable-menu--fixed recordstable-menu--hdr", role: "menu", "aria-label": `${col.label} column`, style: menuPos ?? undefined, onKeyDown: onMenuKeyDown, children: [_jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => sortBy(col.key, "asc"), children: [_jsx(ArrowUp, { size: 15, strokeWidth: 1.75 }), t.sortAscending] }), _jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => sortBy(col.key, "desc"), children: [_jsx(ArrowDown, { size: 15, strokeWidth: 1.75 }), t.sortDescending] }), _jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, disabled: i <= 1, onClick: () => moveColumn(col.key, -1), children: [_jsx(ArrowLeft, { "data-rtl-flip": "", size: 15, strokeWidth: 1.75 }), t.moveLeft] }), _jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, disabled: i === 0 || i >= cols.length - 1, onClick: () => moveColumn(col.key, 1), children: [_jsx(ArrowRight, { "data-rtl-flip": "", size: 15, strokeWidth: 1.75 }), t.moveRight] }), _jsx("div", { className: "recordstable-menu-sep" }), _jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => {
|
|
950
950
|
setRenamingCol(col.key);
|
|
951
951
|
setOpenMenu(null);
|
|
952
952
|
}, children: [_jsx(Pencil, { size: 15, strokeWidth: 1.75 }), t.editColumnLabel] }), cols.length > 1 && (_jsxs("button", { type: "button", className: "recordstable-menu-item", role: "menuitem", tabIndex: -1, onClick: () => hideColumn(col.key), children: [_jsx(EyeOff, { size: 15, strokeWidth: 1.75 }), t.hideFromView] }))] }), rootRef.current), _jsx("span", { className: "recordstable-resize", "aria-hidden": "true", onPointerDown: (e) => {
|
|
@@ -987,7 +987,7 @@ export function RecordsTable({ labels, columns: columnsProp = defaultColumns, ro
|
|
|
987
987
|
: undefined, avatarTone: avatarTone })), i === 0 && onOpenRecord && !isEditing && (_jsx("button", { type: "button", className: "recordstable-open", "aria-label": `Open ${cellText(col, row)}`, onClick: (e) => {
|
|
988
988
|
e.stopPropagation();
|
|
989
989
|
onOpenRecord(row);
|
|
990
|
-
}, children: _jsx(ArrowUpRight, { size: 15, strokeWidth: 1.75 }) }))] }, col.key));
|
|
990
|
+
}, children: _jsx(ArrowUpRight, { "data-rtl-flip": "", size: 15, strokeWidth: 1.75 }) }))] }, col.key));
|
|
991
991
|
}), _jsx("td", { className: "recordstable-td recordstable-addcol" })] }, row.id))) }), _jsx("tfoot", { children: _jsxs("tr", { children: [_jsx("td", { className: "recordstable-sum recordstable-col-check" }), cols.map((col, i) => {
|
|
992
992
|
const a = agg[col.key] ?? "none";
|
|
993
993
|
const res = summarize(col, a, visibleRows);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toolbarChromeBody, toolbarChromeHead, } from "../../components/tabletoolbar/tabletoolbar.chrome.js";
|
|
2
|
-
import { defineRecipe, resolveRecipe } from "../../core/index.js";
|
|
2
|
+
import { defineRecipe, resolveRecipe, rtlFlipCss } from "../../core/index.js";
|
|
3
3
|
import { contract as c } from "../../tokens/index.js";
|
|
4
4
|
import { recordTagCss } from "./recordstable.tag.js";
|
|
5
5
|
// Attio's record grid, measured: 36px rows, 1px borderSubtle (#eeeff1) grid
|
|
@@ -142,6 +142,8 @@ ${toolbarChromeBody("recordstable")}
|
|
|
142
142
|
& .recordstable-bulk-sep { width: 1px; height: 20px; margin: 0 ${c.space["0.5"]}; background: ${c.borderSubtle}; }
|
|
143
143
|
& .recordstable-bulk-close { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: none; border-radius: ${c.radius.md}; background: transparent; color: ${c.fgMuted}; cursor: pointer; }
|
|
144
144
|
& .recordstable-bulk-close:hover { background: ${c.bgRaised}; color: ${c.fgPrimary}; }
|
|
145
|
+
|
|
146
|
+
${rtlFlipCss}
|
|
145
147
|
`,
|
|
146
148
|
variants: {},
|
|
147
149
|
defaultVariants: {},
|
|
@@ -18,6 +18,6 @@ export function SettingsShell({ title = "Settings", onBack, groups, activeItem,
|
|
|
18
18
|
}))
|
|
19
19
|
.filter((g) => g.items.length > 0)
|
|
20
20
|
: groups;
|
|
21
|
-
return (_jsxs("div", { className: settingsshellRecipe({ className }), ...rest, children: [_jsxs("nav", { className: "settingsshell-nav", "aria-label": navLabel, children: [_jsxs("button", { type: "button", className: "settingsshell-back", onClick: onBack, children: [_jsx(ChevronLeft, { size: 16, strokeWidth: 2 }), title] }), searchable && (_jsxs("div", { className: "settingsshell-search", children: [_jsx(Search, { size: 15, strokeWidth: 1.75 }), _jsx("input", { type: "text", placeholder: searchPlaceholder, "aria-label": searchPlaceholder, value: query, onChange: (e) => setQuery(e.target.value) })] })), _jsx("div", { className: "settingsshell-groups", children: filtered.length === 0 ? (_jsx("div", { className: "settingsshell-empty", children: emptyLabel })) : (filtered.map((g, gi) => (_jsxs("div", { className: "settingsshell-group", children: [g.label != null && (_jsx("div", { className: "settingsshell-group-label", children: g.label })), g.items.map((it) => (_jsxs("button", { type: "button", className: "settingsshell-item", "aria-current": it.id === activeItem ? "page" : undefined, "data-active": it.id === activeItem ? "" : undefined, onClick: () => onSelect(it.id), children: [it.icon, _jsx("span", { className: "settingsshell-item-label", children: it.label })] }, it.id)))] }, gi)))) })] }), _jsx("div", { className: "settingsshell-content", children: children })] }));
|
|
21
|
+
return (_jsxs("div", { className: settingsshellRecipe({ className }), ...rest, children: [_jsxs("nav", { className: "settingsshell-nav", "aria-label": navLabel, children: [_jsxs("button", { type: "button", className: "settingsshell-back", onClick: onBack, children: [_jsx(ChevronLeft, { "data-rtl-flip": "", size: 16, strokeWidth: 2 }), title] }), searchable && (_jsxs("div", { className: "settingsshell-search", children: [_jsx(Search, { size: 15, strokeWidth: 1.75 }), _jsx("input", { type: "text", placeholder: searchPlaceholder, "aria-label": searchPlaceholder, value: query, onChange: (e) => setQuery(e.target.value) })] })), _jsx("div", { className: "settingsshell-groups", children: filtered.length === 0 ? (_jsx("div", { className: "settingsshell-empty", children: emptyLabel })) : (filtered.map((g, gi) => (_jsxs("div", { className: "settingsshell-group", children: [g.label != null && (_jsx("div", { className: "settingsshell-group-label", children: g.label })), g.items.map((it) => (_jsxs("button", { type: "button", className: "settingsshell-item", "aria-current": it.id === activeItem ? "page" : undefined, "data-active": it.id === activeItem ? "" : undefined, onClick: () => onSelect(it.id), children: [it.icon, _jsx("span", { className: "settingsshell-item-label", children: it.label })] }, it.id)))] }, gi)))) })] }), _jsx("div", { className: "settingsshell-content", children: children })] }));
|
|
22
22
|
}
|
|
23
23
|
SettingsShell.displayName = "SettingsShell";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineRecipe, resolveRecipe } from "../../core/index.js";
|
|
1
|
+
import { defineRecipe, resolveRecipe, rtlFlipCss } from "../../core/index.js";
|
|
2
2
|
import { contract as c } from "../../tokens/index.js";
|
|
3
3
|
// The Settings layout — measured from Attio's Settings: a 256px left nav with a
|
|
4
4
|
// back header, a search field, and grouped nav items (active row raised), beside
|
|
@@ -34,7 +34,9 @@ const config = defineRecipe({
|
|
|
34
34
|
& .settingsshell-item[data-active] svg { color: ${c.fgPrimary}; }
|
|
35
35
|
& .settingsshell-empty { padding: ${c.space["3"]} ${c.space["2"]}; font-size: ${c.text.md}; color: ${c.fgMuted}; }
|
|
36
36
|
|
|
37
|
-
& .settingsshell-content { flex: 1; min-width: 0; min-height: 0; overflow-y: auto; padding: ${c.space["6"]} ${c.space["8"]}; }
|
|
37
|
+
& .settingsshell-content { flex: 1; min-width: 0; min-height: 0; overflow-y: auto; padding: ${c.space["6"]} ${c.space["8"]}; }
|
|
38
|
+
${rtlFlipCss}
|
|
39
|
+
`,
|
|
38
40
|
variants: {},
|
|
39
41
|
defaultVariants: {},
|
|
40
42
|
compoundVariants: [],
|
package/dist/recordstable.css
CHANGED
|
@@ -198,6 +198,8 @@
|
|
|
198
198
|
& .recordstable-bulk-close { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: none; border-radius: var(--radius-md); background: transparent; color: var(--fg-muted); cursor: pointer; }
|
|
199
199
|
& .recordstable-bulk-close:hover { background: var(--bg-raised); color: var(--fg-primary); }
|
|
200
200
|
|
|
201
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
202
|
+
|
|
201
203
|
}
|
|
202
204
|
|
|
203
205
|
@media (prefers-reduced-motion: reduce) {
|
package/dist/settingsshell.css
CHANGED
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
& .settingsshell-empty { padding: var(--space-3) var(--space-2); font-size: var(--text-md); color: var(--fg-muted); }
|
|
30
30
|
|
|
31
31
|
& .settingsshell-content { flex: 1; min-width: 0; min-height: 0; overflow-y: auto; padding: var(--space-6) var(--space-8); }
|
|
32
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
33
|
+
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
@media (prefers-reduced-motion: reduce) {
|
package/dist/styles.css
CHANGED
|
@@ -272,6 +272,8 @@
|
|
|
272
272
|
& button.breadcrumb-item { border: none; background: none; font: inherit; cursor: pointer; }
|
|
273
273
|
& .breadcrumb-item[aria-current] { color: var(--fg-primary); font-weight: var(--weight-medium); }
|
|
274
274
|
& .breadcrumb-sep { flex-shrink: 0; color: color-mix(in srgb, var(--fg-primary) 28%, transparent); }
|
|
275
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
276
|
+
|
|
275
277
|
}
|
|
276
278
|
|
|
277
279
|
.bulkbar {
|
|
@@ -1732,6 +1734,8 @@
|
|
|
1732
1734
|
& .appshell-expand { position: absolute; top: var(--space-2); inset-inline-start: var(--space-2); z-index: 6; display: inline-flex; align-items: center; justify-content: center; width: var(--size-row); height: var(--size-row); padding: 0; border: none; border-radius: var(--radius-md); box-shadow: inset 0 0 0 1px var(--border-subtle); background: var(--bg-surface); color: var(--fg-muted); font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
1733
1735
|
& .appshell-expand:hover { background: var(--bg-raised); color: var(--fg-primary); }
|
|
1734
1736
|
|
|
1737
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
1738
|
+
|
|
1735
1739
|
}
|
|
1736
1740
|
|
|
1737
1741
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -2449,6 +2453,8 @@
|
|
|
2449
2453
|
& .recordstable-bulk-close { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: none; border-radius: var(--radius-md); background: transparent; color: var(--fg-muted); cursor: pointer; }
|
|
2450
2454
|
& .recordstable-bulk-close:hover { background: var(--bg-raised); color: var(--fg-primary); }
|
|
2451
2455
|
|
|
2456
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
2457
|
+
|
|
2452
2458
|
}
|
|
2453
2459
|
|
|
2454
2460
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -2537,6 +2543,8 @@
|
|
|
2537
2543
|
& .settingsshell-empty { padding: var(--space-3) var(--space-2); font-size: var(--text-md); color: var(--fg-muted); }
|
|
2538
2544
|
|
|
2539
2545
|
& .settingsshell-content { flex: 1; min-width: 0; min-height: 0; overflow-y: auto; padding: var(--space-6) var(--space-8); }
|
|
2546
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
2547
|
+
|
|
2540
2548
|
}
|
|
2541
2549
|
|
|
2542
2550
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mirroring for direction-bearing icons.
|
|
3
|
+
*
|
|
4
|
+
* A chevron or arrow that means "back", "next", "toward the start" or "open"
|
|
5
|
+
* points the wrong way under RTL, and unlike spacing or alignment it cannot be
|
|
6
|
+
* fixed with a logical property: these are `lucide-react` nodes, static SVG
|
|
7
|
+
* paths with no direction of their own.
|
|
8
|
+
*
|
|
9
|
+
* Mark the icons that carry a direction with `data-rtl-flip` and include this
|
|
10
|
+
* snippet in the recipe. Icons whose meaning is NOT directional — a downward
|
|
11
|
+
* disclosure chevron, a search glass, a check — must be left unmarked: flipping
|
|
12
|
+
* them is a regression, not a fix.
|
|
13
|
+
*/
|
|
14
|
+
export declare const rtlFlipCss = "[dir=\"rtl\"] & [data-rtl-flip] { transform: scaleX(-1); }";
|