pinakes/crates/pinakes-ui/assets/styles/_plugins.scss
NotAShelf 9389af9fda
pinakes-ui: enforce plugin endpoint allowlist; replace inline styles with CSS custom properties
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I751e5c7ec66f045ee1f0bad6c72759416a6a6964
2026-03-11 21:30:44 +03:00

94 lines
2.7 KiB
SCSS

@use 'variables' as *;
@use 'mixins' as *;
// Plugin UI renderer layout classes.
//
// Dynamic values are passed via CSS custom properties set on the element.
// The layout rules here consume those properties via var() so the renderer
// never injects full CSS rule strings.
// Container: vertical flex column with configurable gap and padding.
.plugin-container {
display: flex;
flex-direction: column;
gap: var(--plugin-gap, 0px);
padding: var(--plugin-padding, 0);
}
// Grid: CSS grid with a configurable column count and gap.
.plugin-grid {
display: grid;
grid-template-columns: repeat(var(--plugin-columns, 1), 1fr);
gap: var(--plugin-gap, 0px);
}
// Flex: display:flex driven by data-* attribute selectors.
// The gap is a CSS custom property; direction/justify/align/wrap are
// plain enum strings placed in data attributes by the renderer.
.plugin-flex {
display: flex;
gap: var(--plugin-gap, 0px);
&[data-direction='row'] { flex-direction: row; }
&[data-direction='column'] { flex-direction: column; }
&[data-justify='flex-start'] { justify-content: flex-start; }
&[data-justify='flex-end'] { justify-content: flex-end; }
&[data-justify='center'] { justify-content: center; }
&[data-justify='space-between'] { justify-content: space-between; }
&[data-justify='space-around'] { justify-content: space-around; }
&[data-justify='space-evenly'] { justify-content: space-evenly; }
&[data-align='flex-start'] { align-items: flex-start; }
&[data-align='flex-end'] { align-items: flex-end; }
&[data-align='center'] { align-items: center; }
&[data-align='stretch'] { align-items: stretch; }
&[data-align='baseline'] { align-items: baseline; }
&[data-wrap='wrap'] { flex-wrap: wrap; }
&[data-wrap='nowrap'] { flex-wrap: nowrap; }
}
// Split: side-by-side sidebar + main area.
.plugin-split {
display: flex;
}
// Sidebar width is driven by --plugin-sidebar-width.
.plugin-split-sidebar {
width: var(--plugin-sidebar-width, 200px);
flex-shrink: 0;
}
.plugin-split-main {
flex: 1;
min-width: 0;
}
// Media grid reuses the same column/gap variables as .plugin-grid.
.plugin-media-grid {
display: grid;
grid-template-columns: repeat(var(--plugin-columns, 2), 1fr);
gap: var(--plugin-gap, 8px);
}
// Table column with a plugin-specified fixed width.
// The width is passed as --plugin-col-width on the th element.
.plugin-col-constrained {
width: var(--plugin-col-width);
}
// Progress bar: the fill element carries --plugin-progress.
.plugin-progress-bar {
height: 100%;
background: $accent;
border-radius: 4px;
transition: width 0.3s ease;
width: var(--plugin-progress, 0%);
}
// Chart wrapper: height is driven by --plugin-chart-height.
.plugin-chart {
overflow: auto;
height: var(--plugin-chart-height, 200px);
}